fix(editor): account footer is the account alone; language rides elsewhere
The bottom-left block read wrong: a globe crowding the account button for no gain — language already lives in the menubar's Language menu for everyone, and (for signed-in users) inside the account menu. The footer now holds only the account button. Width-aware, as requested: when the explorer is dragged narrow (footer under 150px, via container query) the username hides and the avatar alone identifies the account; with the explorer collapsed, the floating fallback box shows just the circle. Adds the OSS half of the crash fix: LocaleSync listens for 'velxio-locale-switch' window events and performs the locale change as a normal SPA navigation. The pro account menu is injected into its own React root OUTSIDE the Router, so it cannot navigate itself — its language rows dispatch this event instead.
This commit is contained in:
parent
e17f6fd6cf
commit
155513a493
|
|
@ -633,7 +633,19 @@ body {
|
|||
background: #171a21;
|
||||
}
|
||||
|
||||
.explorer-account-footer:has([data-auth-user]) .corner-lang,
|
||||
.editor-corner-box:has([data-auth-user]) .corner-lang {
|
||||
.explorer-account-footer {
|
||||
container-type: inline-size;
|
||||
}
|
||||
|
||||
/* Tight footer (narrow explorer): the avatar alone identifies the account;
|
||||
the name is a luxury that costs exactly the width we do not have. */
|
||||
@container (max-width: 150px) {
|
||||
.explorer-account-footer .header-username-text {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Collapsed explorer: the floating fallback box shows the circle only. */
|
||||
.editor-corner-box .header-username-text {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,18 +76,4 @@
|
|||
letter-spacing: 0.4px;
|
||||
}
|
||||
|
||||
/* Inside the editor's bottom-left corner box the switcher sits at the
|
||||
bottom edge of the screen — the menu must drop UP or it opens straight
|
||||
into the void below the viewport. */
|
||||
.editor-corner-box .velxio-language-menu {
|
||||
top: auto;
|
||||
bottom: 110%;
|
||||
margin: 0 0 6px;
|
||||
}
|
||||
|
||||
/* Same drop-up need at the explorer footer. */
|
||||
.explorer-account-footer .velxio-language-menu {
|
||||
top: auto;
|
||||
bottom: 110%;
|
||||
margin: 0 0 6px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,18 +11,35 @@
|
|||
*/
|
||||
|
||||
import { useEffect, type ReactNode } from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import { i18n, loadLocale } from "./index";
|
||||
import { LOCALE_META, DEFAULT_LOCALE } from "./config";
|
||||
import { getLocaleFromPath } from "./path";
|
||||
import { LOCALE_META, DEFAULT_LOCALE, type Locale } from "./config";
|
||||
import { getLocaleFromPath, switchLocale } from "./path";
|
||||
import { writeLocaleCookie } from "./cookie";
|
||||
|
||||
type Props = { children: ReactNode };
|
||||
|
||||
export function LocaleSync({ children }: Props) {
|
||||
const { pathname } = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const target = getLocaleFromPath(pathname);
|
||||
|
||||
// Locale switching for UI that lives OUTSIDE the Router: the pro account
|
||||
// menu is injected into its own React root, so it cannot call
|
||||
// useNavigate() — its language rows dispatch this event instead, and the
|
||||
// switch happens here as a normal SPA navigation (no reload, workspace
|
||||
// intact). Same path the header globe takes.
|
||||
useEffect(() => {
|
||||
const onSwitch = (e: Event): void => {
|
||||
const locale = (e as CustomEvent<{ locale?: string }>).detail?.locale;
|
||||
if (!locale) return;
|
||||
const next = switchLocale(window.location.pathname, locale as Locale);
|
||||
navigate(next + window.location.search + window.location.hash);
|
||||
};
|
||||
window.addEventListener('velxio-locale-switch', onSwitch);
|
||||
return () => window.removeEventListener('velxio-locale-switch', onSwitch);
|
||||
}, [navigate]);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
(async () => {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ import { showConfirmDialog } from '../store/useMessageDialogStore';
|
|||
import { useAutoSaveProject } from '../hooks/useAutoSaveProject';
|
||||
import { registerEditorCommand } from '../lib/editorCommands';
|
||||
import { EditorMenuBar } from '../components/editor/EditorMenuBar';
|
||||
import { LanguageSwitcher } from '../components/layout/LanguageSwitcher';
|
||||
import type { CompilationLog } from '../utils/compilationLogger';
|
||||
import '../App.css';
|
||||
|
||||
|
|
@ -390,20 +389,15 @@ export const EditorPage: React.FC = () => {
|
|||
there used to be 44+38. On narrow widths the strip wraps internally
|
||||
and the header grows; the docked AI chat is avoided by the same
|
||||
padding-right the strip always had. */
|
||||
/* Account + language block. Fused as the explorer panel's footer so a
|
||||
long file tree scrolls ABOVE it instead of disappearing underneath a
|
||||
floating box; when the explorer is collapsed it falls back to the
|
||||
small fixed corner box. The standalone language switcher only shows
|
||||
while logged OUT — signed-in users change language inside the account
|
||||
menu (see pro HeaderAuth), and a CSS :has() rule hides the globe when
|
||||
the auth slot renders a logged-in marker. */
|
||||
/* Account block. Fused as the explorer panel's footer so a long file
|
||||
tree scrolls ABOVE it instead of disappearing underneath a floating
|
||||
box; when the explorer is collapsed it falls back to the small fixed
|
||||
corner box (avatar only there — no room for a name). */
|
||||
const accountBlock = !isMobile ? (
|
||||
<>
|
||||
<span className="corner-lang">
|
||||
<LanguageSwitcher />
|
||||
</span>
|
||||
<div data-velxio-slot="header-auth" style={{ display: 'contents' }} />
|
||||
</>
|
||||
// Just the account button. Language lives in the menubar's Language
|
||||
// menu (for everyone) and inside the account menu (for signed-in
|
||||
// users) — the standalone globe crowded the footer for no gain.
|
||||
<div data-velxio-slot="header-auth" style={{ display: 'contents' }} />
|
||||
) : undefined;
|
||||
|
||||
const unifiedToolbar = !isMobile ? (
|
||||
|
|
|
|||
Loading…
Reference in New Issue