- 最主要的一处:登录成功后点浏览器"后退",会回到一个仍然认为"已登录"的底层连接、但重新挂载出来
的登录表单——按钮永久卡在禁用的"登录中…"(loginDisabled只有失败分支会重置,成功分支从来没有,
因为正常路径下这个页面早就导航走了,没人会看到);如果不管这个直接切换企业码后再次提交,
doLogin()/handleNewAccountRequest()开头的"已认证就直接放行"逻辑会让登录悄悄跳过凭据校验,
或者让注册请求收到后端原始英文错误"already authenticated (409)"。根治方式是在
handleHashRoute加一道门:hash指向登录/注册等纯"未登录态"视图、但连接其实已认证时,直接重定向
离开,不让这类表单有机会被重新渲染出来——已用真实浏览器验证4个入口(login/register/tenant/
reset/cred)全部正确重定向,且确认不影响真正的登录后安全类页面(如identity-check)。
handleLoginSuccessful也顺手补了loginDisabled:false兜底。
- 系统消息列表:后端`GET /system-notifications`明明返回`next_cursor`表示还有更多,前端从来没用过,
未读50+条永远只能看到最近20条、永远没法真正清零。补了"加载更多"分页——已用真实账号(60+条历史
通知)验证,点击后正确追加下一页、游标耗尽后正确不再显示按钮。
- 已处理(通过/拒绝)的好友申请通知,原来只要event_type以"friend.request"开头就显示"查看新朋友"
按钮——不区分"待处理"和"已是历史结果",点了跳到待处理列表也找不到对应项。改成只在
`friend.request.created`时显示,已用真实账号里同时存在created/accepted/rejected三种通知
验证行为符合预期。
- 注册页四处不统一的占位品牌名(讯工捷迅/捷信密使/捷讯/即时通讯,没有一个是真实品牌名)与
系统消息页脚"即时通讯安全团队",统一改用BASE_APP_NAME("MeetingIM")。
- config.js的KNOWN_HOSTS.hosted从web.tinode.co改为web.118im.com(这是WS连接失败时的最终
兜底地址,指向无关第三方域名不只是品牌问题,是真实会连错服务器);host-name.js的
detectServerAddress()原来只要hostname是localhost就无条件返回硬编码的localhost:6060,
完全不管页面实际监听的端口——本项目自己的开发代理跑在8093,清缓存后首次连接必然先撞一次
死连接,改成和非localhost分支一样用页面自己的真实端口。
- 实名认证提交成功后,姓名/证件号输入框原来会变成空白(后端成功响应不含masked_name/
masked_id_number,组件切到只读态时又没有回退到用户自己刚输入的草稿值)——改成没有脱敏字段时
回退显示用户本次会话里刚输入的原始值,不是留白。
- Firebase推送通知初始化失败原来复用登录/注册表单的错误提示通道,可能盖住一个同时发生的真实
登录错误,或在用户还没操作登录表单时就先弹出一条无关提示——推送本身是锦上添花功能,改成只
console记录+静默关闭开关,不再抢占登录页的错误展示位。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
168 lines
7.5 KiB
JavaScript
168 lines
7.5 KiB
JavaScript
import { PACKAGE_VERSION } from './version.js';
|
|
|
|
// 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');
|
|
|
|
// API key. Use https://github.com/tinode/chat/tree/master/keygen to generate your own.
|
|
// Injected at build time via webpack DefinePlugin from the TINODE_API_KEY env var
|
|
// (see webpack.config.js and .env.local). Falls back to the public sample key when unset,
|
|
// which only works against a backend still using the matching sample API_KEY_SALT.
|
|
export const API_KEY = process.env.TINODE_API_KEY || 'AQEAAAABAAD_rAp4DJh05a1HAwFT3A6K';
|
|
|
|
// The array of possible hosts to connect to.
|
|
export const KNOWN_HOSTS = {hosted: 'web.118im.com', local: 'localhost:6060'};
|
|
|
|
// Default host name and port to connect to.
|
|
export const DEFAULT_HOST = KNOWN_HOSTS.hosted;
|
|
|
|
// Enable console logging.
|
|
export const LOGGING_ENABLED = true;
|
|
|
|
// Minimum time between two keypress notifications, milliseconds.
|
|
export const KEYPRESS_DELAY = 3_000;
|
|
// Delay before sending a read notification, milliseconds.
|
|
export const READ_DELAY = 1_500;
|
|
|
|
// The default shortest allowed tag length. Matches the value on the server.
|
|
export const MIN_TAG_LENGTH = 2;
|
|
// The default greatest allowed tag length. Matches the value on the server.
|
|
export const MAX_TAG_LENGTH = 96;
|
|
// The default maximum number of tags allowed. Matches the value on the server.
|
|
export const MAX_TAG_COUNT = 16;
|
|
|
|
// Access mode for P2P subscriptions initiated by the current user.
|
|
export const DEFAULT_P2P_ACCESS_MODE = 'JRWPS';
|
|
// Access mode for new group topics created by the current user.
|
|
export const NEW_GRP_ACCESS_MODE = 'JRWPSAO';
|
|
// Access mode for a channel.
|
|
export const CHANNEL_ACCESS_MODE = 'JR';
|
|
|
|
// Access mode for no access.
|
|
export const NO_ACCESS_MODE = 'N';
|
|
|
|
// Mediaquery breakpoint between desktop and mobile, in px. Should match the value
|
|
// in @media (max-size: 640px) in base.css
|
|
export const MEDIA_BREAKPOINT = 640;
|
|
// Size of css 'rem' unit in pixels. Default 1rem = 10pt = 13px.
|
|
export const REM_SIZE = 13;
|
|
|
|
// Size of the avatar image: when image dimensions are greater or the image is not square, it's resized to
|
|
// a square of this size or less.
|
|
export const AVATAR_SIZE = 384;
|
|
|
|
// Maximum size of an avatar in bytes for sending in-band. Bigger avatars will be sent out of band (as uploads).
|
|
export const MAX_AVATAR_BYTES = 4096;
|
|
|
|
// Size of the broken_image shown in MessagesView
|
|
export const BROKEN_IMAGE_SIZE = 32;
|
|
|
|
// Size of video preview when dimensions are missing.
|
|
export const NO_DIMENSIONS_VIDEO = 128;
|
|
|
|
// Number of chat messages to fetch in one call.
|
|
export const MESSAGES_PAGE = 24;
|
|
|
|
// Default maximum in-band (included directly into the message) attachment size which fits into
|
|
// a message of 256K in size. Used when the server-provided value is unavailable. The actual
|
|
// binary size of the attachment should be smaller due to base64 encoding expansion and some overhead,
|
|
// for instance 1024 bytes.
|
|
// Increase this limit to a greater value in production, if desired. Also increase
|
|
// max_message_size in the server config.
|
|
export const MAX_INBAND_ATTACHMENT_SIZE = 262_144;
|
|
|
|
// Default absolute maximum attachment size to be used with the server = 8MB.
|
|
// Used when the server-provided value is unavailable. Increase to something like 100MB in production.
|
|
export const MAX_EXTERN_ATTACHMENT_SIZE = 1 << 23;
|
|
|
|
// Maximum allowed linear dimension (pixels) of an image sent inline. Larger images will be shrunk
|
|
// to make the larger dimension fit under this size. You may want to adjust it to 1600 or
|
|
// 2400 for production.
|
|
export const MAX_IMAGE_DIM = 1024;
|
|
|
|
// Linear dimensions of image preview: shrink image under this size for previews.
|
|
export const IMAGE_PREVIEW_DIM = 64;
|
|
|
|
// Linear dimensions of video screencapture: shrink image under this size for previews.
|
|
export const VIDEO_PREVIEW_DIM = 96;
|
|
|
|
// Linear dimensions of image thumbnail: shrink image under this size for thumbnails in reply quote previews.
|
|
export const IMAGE_THUMBNAIL_DIM = 36;
|
|
// Width of video thumbnail: allow it to be wider, but not taller. Use IMAGE_THUMBNAIL_DIM for height.
|
|
export const VIDEO_THUMBNAIL_WIDTH = 48;
|
|
|
|
// Maximum number of online users to be shown in a topic title bar. Others will be
|
|
// hidden under "+X more"
|
|
export const MAX_ONLINE_IN_TOPIC = 4;
|
|
|
|
// Maximum length of user name, topic title, and private comment.
|
|
export const MAX_TITLE_LENGTH = 60;
|
|
// Maximum length of topic description.
|
|
export const MAX_TOPIC_DESCRIPTION_LENGTH = 360;
|
|
// Maximum length of user name when displaying a video call.
|
|
export const MAX_PEER_TITLE_LENGTH = 24;
|
|
|
|
// Length of message previews in chat list, in characters.
|
|
export const MESSAGE_PREVIEW_LENGTH = 80;
|
|
|
|
// Length of a quote in quoted reply (for outgoing messages).
|
|
export const QUOTED_REPLY_LENGTH = 30;
|
|
// Length of a preview of a forwarded message.
|
|
export const FORWARDED_PREVIEW_LENGTH = 84;
|
|
// Length of preview for a message being edited.
|
|
export const EDIT_PREVIEW_LENGTH = 48;
|
|
|
|
// Minimum duration of an audio recording in milliseconds (2 sec).
|
|
export const MIN_DURATION = 2_000;
|
|
// Maximum duration of an audio recording in milliseconds (10 min).
|
|
export const MAX_DURATION = 600_000;
|
|
|
|
// No real destination exists for these (this is a private multi-tenant product, not the open-source
|
|
// Tinode project) -- null rather than the upstream project's own contact/legal pages, which acc-support-view.jsx
|
|
// renders as inert text instead of a link (same treatment auth-onboarding-view.jsx already gives its
|
|
// own placeholder 用户协议/隐私政策 links).
|
|
export const LINK_CONTACT_US = null;
|
|
export const LINK_PRIVACY_POLICY = null;
|
|
export const LINK_TERMS_OF_SERVICE = null;
|
|
|
|
// When user starts a P2P topic, automatic subscription does not
|
|
// happen until the first message. Setting this option to true enables
|
|
// immediate subscription.
|
|
export const IMMEDIATE_P2P_SUBSCRIPTION = false;
|
|
|
|
// URL schemes permitted to appear in links (i.e. no javascript: scheme).
|
|
export const CLICKABLE_URL_SCHEMES = ['http', 'https', 'ftp', 'ftps'];
|
|
|
|
// Size of the QR code in the app.
|
|
export const QRCODE_SIZE = 128;
|
|
|
|
// How much time has to pass to consider computer awoken from sleep (80 sec).
|
|
// Chrome throttles ticker events in inactive tabs to once per minute. This
|
|
// value ensures that these once-a-minute events do not trigger a reconnect.
|
|
export const WAKE_UP_TIMEOUT = 80000;
|
|
// Timer interval between checks if computer woke up from sleep (1 sec).
|
|
export const WAKE_UP_TICK = 1000;
|
|
|
|
// Swipe distance to register as a gesture, in pixels.
|
|
export const MIN_SWIPE_DISTANCE = REM_SIZE * 3;
|
|
|
|
// Self-topic avatar as an SVG icon encoded as data URI
|
|
export const SELF_AVATAR_URI = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZpZXdCb3g9IjAgMCAxNyAxNyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMy41NjIgMXYxNS40NTlsNC42ODYtMy4yNyA0Ljc1MiAzLjI2di0xNS40NDloLTkuNDM4ek0xMiAxNC41NTFsLTMuNzU2LTIuNTc4LTMuNjgxIDIuNTY4di0xMi41NDFoNy40Mzd2MTIuNTUxeiIgZmlsbD0iIzU1NTU1NSIgLz48L3N2Zz4=' // eslint-disable-line max-len
|
|
|
|
// Toast display duration, milliseconds.
|
|
export const TOAST_DURATION = 3_000;
|
|
|
|
// Initial/default color scheme.
|
|
export const DEFAULT_COLOR_SCHEME = 'auto';
|
|
|
|
// Default text size in points.
|
|
export const DEFAULT_TEXT_SIZE = 10;
|
|
|
|
// MIME type for the legacy Drafty form-response data.
|
|
export const DRAFTY_FR_MIME_TYPE_LEGACY = 'application/json'; // Remove in 2026.
|
|
|
|
// Path to wallpaper images.
|
|
export const WALLPAPER_DEFAULTS = {type: 'patt', index: 0, path:'img/bkg/'};
|