mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-07-06 23:43:32 +00:00
[ENG-1592] Correctly assign tab titles on desktop (#2030)
* correctly set tab titles * use selectedTabIndex * empty tabId * prettier
This commit is contained in:
parent
8cbd38d6f9
commit
74d97d4957
|
@ -80,18 +80,22 @@ const routes = createRoutes(platform, cache);
|
|||
|
||||
function AppInner() {
|
||||
const [tabs, setTabs] = useState(() => [createTab()]);
|
||||
const [tabIndex, setTabIndex] = useState(0);
|
||||
const [selectedTabIndex, setSelectedTabIndex] = useState(0);
|
||||
|
||||
const selectedTab = tabs[selectedTabIndex]!;
|
||||
|
||||
function createTab() {
|
||||
const history = createMemoryHistory();
|
||||
const router = createMemoryRouterWithHistory({ routes, history });
|
||||
|
||||
const id = Math.random().toString();
|
||||
|
||||
const dispose = router.subscribe((event) => {
|
||||
// we don't care about non-idle events as those are artifacts of form mutations + suspense
|
||||
if (event.navigation.state !== 'idle') return;
|
||||
|
||||
setTabs((routers) => {
|
||||
const index = routers.findIndex((r) => r.router === router);
|
||||
const index = routers.findIndex((r) => r.id === id);
|
||||
if (index === -1) return routers;
|
||||
|
||||
const routerAtIndex = routers[index]!;
|
||||
|
@ -105,12 +109,12 @@ function AppInner() {
|
|||
: Math.max(routerAtIndex.maxIndex, history.index)
|
||||
};
|
||||
|
||||
return [...routers];
|
||||
return [...routers]
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
id: Math.random().toString(),
|
||||
id,
|
||||
router,
|
||||
history,
|
||||
dispose,
|
||||
|
@ -121,8 +125,6 @@ function AppInner() {
|
|||
};
|
||||
}
|
||||
|
||||
const tab = tabs[tabIndex]!;
|
||||
|
||||
const createTabPromise = useRef(Promise.resolve());
|
||||
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
|
@ -131,38 +133,37 @@ function AppInner() {
|
|||
const div = ref.current;
|
||||
if (!div) return;
|
||||
|
||||
div.appendChild(tab.element);
|
||||
div.appendChild(selectedTab.element);
|
||||
|
||||
return () => {
|
||||
while (div.firstChild) {
|
||||
div.removeChild(div.firstChild);
|
||||
}
|
||||
};
|
||||
}, [tab.element]);
|
||||
}, [selectedTab.element]);
|
||||
|
||||
return (
|
||||
<RouteTitleContext.Provider
|
||||
value={useMemo(
|
||||
() => ({
|
||||
setTitle(title) {
|
||||
setTabs((oldTabs) => {
|
||||
const tabs = [...oldTabs];
|
||||
const tab = tabs[tabIndex];
|
||||
if (!tab) return tabs;
|
||||
setTitle(id, title) {
|
||||
setTabs((tabs) => {
|
||||
const tabIndex = tabs.findIndex(t => t.id === id);
|
||||
if (tabIndex === -1) return tabs;
|
||||
|
||||
tabs[tabIndex] = { ...tab, title };
|
||||
tabs[tabIndex] = { ...tabs[tabIndex]!, title };
|
||||
|
||||
return tabs;
|
||||
return [...tabs];
|
||||
});
|
||||
}
|
||||
}),
|
||||
[tabIndex]
|
||||
[]
|
||||
)}
|
||||
>
|
||||
<TabsContext.Provider
|
||||
value={{
|
||||
tabIndex,
|
||||
setTabIndex,
|
||||
tabIndex: selectedTabIndex,
|
||||
setTabIndex: setSelectedTabIndex,
|
||||
tabs: tabs.map(({ router, title }) => ({ router, title })),
|
||||
createTab() {
|
||||
createTabPromise.current = createTabPromise.current.then(
|
||||
|
@ -170,9 +171,10 @@ function AppInner() {
|
|||
new Promise((res) => {
|
||||
startTransition(() => {
|
||||
setTabs((tabs) => {
|
||||
const newTabs = [...tabs, createTab()];
|
||||
const newTab = createTab();
|
||||
const newTabs = [...tabs, newTab];
|
||||
|
||||
setTabIndex(newTabs.length - 1);
|
||||
setSelectedTabIndex(newTabs.length - 1);
|
||||
|
||||
return newTabs;
|
||||
});
|
||||
|
@ -192,7 +194,7 @@ function AppInner() {
|
|||
|
||||
tabs.splice(index, 1);
|
||||
|
||||
setTabIndex(Math.min(tabIndex, tabs.length - 1));
|
||||
setSelectedTabIndex(Math.min(selectedTabIndex, tabs.length - 1));
|
||||
|
||||
return [...tabs];
|
||||
});
|
||||
|
@ -201,15 +203,16 @@ function AppInner() {
|
|||
}}
|
||||
>
|
||||
<SpacedriveInterfaceRoot>
|
||||
{tabs.map((tab) =>
|
||||
{tabs.map((tab, index) =>
|
||||
createPortal(
|
||||
<SpacedriveRouterProvider
|
||||
key={tab.id}
|
||||
routing={{
|
||||
routes,
|
||||
visible: tabIndex === tabs.indexOf(tab),
|
||||
visible: selectedTabIndex === tabs.indexOf(tab),
|
||||
router: tab.router,
|
||||
currentIndex: tab.currentIndex,
|
||||
tabId: tab.id,
|
||||
maxIndex: tab.maxIndex
|
||||
}}
|
||||
/>,
|
||||
|
|
|
@ -112,6 +112,7 @@ function App() {
|
|||
<SpacedriveRouterProvider
|
||||
routing={{
|
||||
...router,
|
||||
tabId: '',
|
||||
routes,
|
||||
visible: true
|
||||
}}
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
use crate::{
|
||||
api::CoreEvent,
|
||||
object::{media::thumbnail::get_indexed_thumbnail_path, orphan_remover::OrphanRemoverActor},
|
||||
sync, Node,
|
||||
};
|
||||
use crate::{api::CoreEvent, object::media::thumbnail::get_indexed_thumbnail_path, sync, Node};
|
||||
|
||||
use sd_file_path_helper::{file_path_to_full_path, IsolatedFilePathData};
|
||||
use sd_p2p::spacetunnel::Identity;
|
||||
|
|
|
@ -6,6 +6,7 @@ import { createRoutes } from './app';
|
|||
export const RoutingContext = createContext<{
|
||||
visible: boolean;
|
||||
currentIndex: number;
|
||||
tabId: string;
|
||||
maxIndex: number;
|
||||
routes: ReturnType<typeof createRoutes>;
|
||||
} | null>(null);
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
import { createContext, useContext, useLayoutEffect } from 'react';
|
||||
import { useRoutingContext } from '~/RoutingContext';
|
||||
|
||||
export function useRouteTitle(title: string) {
|
||||
const routingCtx = useRoutingContext();
|
||||
const ctx = useContext(RouteTitleContext);
|
||||
|
||||
// layout effect avoids 'New Tab' showing up briefly
|
||||
useLayoutEffect(() => {
|
||||
document.title = title;
|
||||
if (ctx) ctx.setTitle(title);
|
||||
}, [title, ctx]);
|
||||
if (ctx) ctx.setTitle(routingCtx.tabId, title);
|
||||
}, [routingCtx.tabId, title, ctx]);
|
||||
|
||||
return title;
|
||||
}
|
||||
|
||||
export const RouteTitleContext = createContext<{
|
||||
setTitle: (title: string) => void;
|
||||
setTitle: (id: string, title: string) => void;
|
||||
} | null>(null);
|
||||
|
|
|
@ -53,6 +53,7 @@ export function SpacedriveRouterProvider(props: {
|
|||
visible: boolean;
|
||||
router: Router;
|
||||
currentIndex: number;
|
||||
tabId: string;
|
||||
maxIndex: number;
|
||||
};
|
||||
}) {
|
||||
|
@ -63,6 +64,7 @@ export function SpacedriveRouterProvider(props: {
|
|||
routes: props.routing.routes,
|
||||
visible: props.routing.visible,
|
||||
currentIndex: props.routing.currentIndex,
|
||||
tabId: props.routing.tabId,
|
||||
maxIndex: props.routing.maxIndex
|
||||
}}
|
||||
>
|
||||
|
|
Loading…
Reference in a new issue