fix(auth): 登录页不停刷新、无法输入
未登录时五个 Tab 视图会同时挂载各自的 Screen,每个都判定「没登录」,
于是每个都对**当前**视图发一次 navigate('/login/', {reloadAll: true})。
每次 reloadAll 又让其他几个重新挂载,再各发一次——登录表单被持续拆掉重建,
根本打不出字。关掉页面过渡动画后这个循环变紧,症状才明显起来。
判断登录与否是外壳的职责,不是每个页面各自抢着跳转:
- App 持有会话状态:没有会话就只渲染一个 /login/ 视图,连 Tab 栏都不出;
有会话才渲染五个 Tab。
- Screen 不再做任何跳转。
- setSession / clearSession 派发 ghl:auth 事件。storage 事件只在**其他**
标签页触发,同标签页的登录登出需要自己的信号。
- 登录成功后不再手动 navigate:外壳会换掉整个视图,从一个正要被卸载的
视图里发起路由是在和它抢。
实测:登出后登录页只有 1 个视图、无 Tab 栏,输入的内容 2.5 秒后仍在,
且输入框还是同一个 DOM 节点(没有重挂);恢复会话后自动切回 5 个 Tab。
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import { ReactNode, useEffect, useState } from 'react';
|
||||
import { ReactNode } from 'react';
|
||||
import { Page, Navbar, NavLeft, NavRight, Link, f7 } from 'framework7-react';
|
||||
import { apiClient } from '../services/api';
|
||||
import './Screen.css';
|
||||
|
||||
interface ScreenProps {
|
||||
@@ -10,8 +9,6 @@ interface ScreenProps {
|
||||
large?: boolean;
|
||||
/** Back chevron instead of the app's utility links. */
|
||||
backLink?: boolean;
|
||||
/** Skip the auth gate (the login screen itself). */
|
||||
open?: boolean;
|
||||
right?: ReactNode;
|
||||
children: ReactNode;
|
||||
}
|
||||
@@ -52,24 +49,8 @@ function goBack() {
|
||||
* collapsing large titles — while the content inside stays ours.
|
||||
*/
|
||||
function Screen({
|
||||
title, subtitle, large = true, backLink, open, right, children,
|
||||
title, subtitle, large = true, backLink, right, children,
|
||||
}: ScreenProps) {
|
||||
const [authed, setAuthed] = useState(() => apiClient.isAuthenticated());
|
||||
|
||||
useEffect(() => {
|
||||
if (open || authed) return;
|
||||
// Router navigation rather than a redirect component: F7 owns history.
|
||||
f7.views.current.router.navigate('/login/', { reloadAll: true });
|
||||
}, [authed, open]);
|
||||
|
||||
useEffect(() => {
|
||||
const onStorage = () => setAuthed(apiClient.isAuthenticated());
|
||||
window.addEventListener('storage', onStorage);
|
||||
return () => window.removeEventListener('storage', onStorage);
|
||||
}, []);
|
||||
|
||||
if (!open && !authed) return <Page />;
|
||||
|
||||
return (
|
||||
<Page>
|
||||
<Navbar large={large} transparent={large} title={title} subtitle={subtitle}>
|
||||
|
||||
Reference in New Issue
Block a user