fix(app): new layout issues

This commit is contained in:
Adam
2026-01-15 07:00:53 -06:00
parent 679270d9e0
commit 564d3edfac
4 changed files with 113 additions and 31 deletions

View File

@@ -47,13 +47,34 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
const globalSdk = useGlobalSDK()
const globalSync = useGlobalSync()
const server = useServer()
const isRecord = (value: unknown): value is Record<string, unknown> =>
typeof value === "object" && value !== null && !Array.isArray(value)
const migrate = (value: unknown) => {
if (!isRecord(value)) return value
const sidebar = value.sidebar
if (!isRecord(sidebar)) return value
if (typeof sidebar.workspaces !== "boolean") return value
return {
...value,
sidebar: {
...sidebar,
workspaces: {},
workspacesDefault: sidebar.workspaces,
},
}
}
const target = Persist.global("layout", ["layout.v6"])
const [store, setStore, _, ready] = persisted(
Persist.global("layout", ["layout.v6"]),
{ ...target, migrate },
createStore({
sidebar: {
opened: false,
width: 280,
workspaces: false,
workspaces: {} as Record<string, boolean>,
workspacesDefault: false,
},
terminal: {
height: 280,
@@ -305,12 +326,15 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
resize(width: number) {
setStore("sidebar", "width", width)
},
workspaces: createMemo(() => store.sidebar.workspaces ?? false),
setWorkspaces(value: boolean) {
setStore("sidebar", "workspaces", value)
workspaces(directory: string) {
return createMemo(() => store.sidebar.workspaces[directory] ?? store.sidebar.workspacesDefault ?? false)
},
toggleWorkspaces() {
setStore("sidebar", "workspaces", (x) => !x)
setWorkspaces(directory: string, value: boolean) {
setStore("sidebar", "workspaces", directory, value)
},
toggleWorkspaces(directory: string) {
const current = store.sidebar.workspaces[directory] ?? store.sidebar.workspacesDefault ?? false
setStore("sidebar", "workspaces", directory, !current)
},
},
terminal: {

View File

@@ -271,6 +271,12 @@ export default function Layout(props: ParentProps) {
return layout.projects.list().find((p) => p.worktree === directory || p.sandboxes?.includes(directory))
})
const workspaceSetting = createMemo(() => {
const project = currentProject()
if (!project) return false
return layout.sidebar.workspaces(project.worktree)()
})
createEffect(() => {
const project = currentProject()
if (!project) return
@@ -306,7 +312,16 @@ export default function Layout(props: ParentProps) {
return sessions.filter((s) => !s.parentID)
}
const currentSessions = createMemo(() => projectSessions(currentProject()))
const currentSessions = createMemo(() => {
const project = currentProject()
if (!project) return [] as Session[]
if (workspaceSetting()) return projectSessions(project)
const [projectStore] = globalSync.child(project.worktree)
return projectStore.session
.filter((session) => session.directory === projectStore.path.directory)
.filter((session) => !session.parentID)
.toSorted(sortSessions)
})
type PrefetchQueue = {
inflight: Set<string>
@@ -729,6 +744,21 @@ export default function Layout(props: ParentProps) {
requestAnimationFrame(() => scrollToSession(id))
})
createEffect(() => {
const project = currentProject()
if (!project) return
if (workspaceSetting()) {
const dirs = [project.worktree, ...(project.sandboxes ?? [])]
for (const directory of dirs) {
globalSync.project.loadSessions(directory)
}
return
}
globalSync.project.loadSessions(project.worktree)
})
createEffect(() => {
if (isLargeViewport()) {
const sidebarWidth = layout.sidebar.opened() ? layout.sidebar.width() : 64
@@ -943,6 +973,7 @@ export default function Layout(props: ParentProps) {
})
const workspaces = createMemo(() => workspaceIds(props.project).slice(0, 2))
const workspaceEnabled = createMemo(() => layout.sidebar.workspaces(props.project.worktree)())
const label = (directory: string) => {
const [data] = globalSync.child(directory)
const kind = directory === props.project.worktree ? "local" : "sandbox"
@@ -959,6 +990,15 @@ export default function Layout(props: ParentProps) {
.slice(0, 2)
}
const projectSessions = () => {
const [data] = globalSync.child(props.project.worktree)
return data.session
.filter((session) => session.directory === data.path.directory)
.filter((session) => !session.parentID)
.toSorted(sortSessions)
.slice(0, 2)
}
const trigger = (
<button
type="button"
@@ -980,23 +1020,39 @@ export default function Layout(props: ParentProps) {
<div class="-m-3 flex flex-col w-72">
<div class="px-3 py-2 text-12-medium text-text-strong">Recent sessions</div>
<div class="px-2 pb-2 flex flex-col gap-2">
<For each={workspaces()}>
{(directory) => (
<div class="flex flex-col gap-1">
<div class="px-2 py-0.5 flex items-center gap-1 min-w-0">
<div class="shrink-0 size-6 flex items-center justify-center">
<Icon name="branch" size="small" class="text-icon-base" />
<Show
when={workspaceEnabled()}
fallback={
<For each={projectSessions()}>
{(session) => (
<SessionItem
session={session}
slug={base64Encode(props.project.worktree)}
dense
mobile={props.mobile}
/>
)}
</For>
}
>
<For each={workspaces()}>
{(directory) => (
<div class="flex flex-col gap-1">
<div class="px-2 py-0.5 flex items-center gap-1 min-w-0">
<div class="shrink-0 size-6 flex items-center justify-center">
<Icon name="branch" size="small" class="text-icon-base" />
</div>
<span class="truncate text-14-medium text-text-strong">{label(directory)}</span>
</div>
<span class="truncate text-14-medium text-text-strong">{label(directory)}</span>
<For each={sessions(directory)}>
{(session) => (
<SessionItem session={session} slug={base64Encode(directory)} dense mobile={props.mobile} />
)}
</For>
</div>
<For each={sessions(directory)}>
{(session) => (
<SessionItem session={session} slug={base64Encode(directory)} dense mobile={props.mobile} />
)}
</For>
</div>
)}
</For>
)}
</For>
</Show>
</div>
<div class="px-2 py-2 border-t border-border-weak-base">
<Button
@@ -1068,7 +1124,7 @@ export default function Layout(props: ParentProps) {
return `${kind} : ${name}`
})
const open = createMemo(() => store.workspaceExpanded[props.directory] ?? true)
const hasMore = createMemo(() => local() && workspaceStore.session.length >= workspaceStore.limit)
const hasMore = createMemo(() => local() && workspaceStore.sessionTotal > workspaceStore.session.length)
const loadMore = async () => {
if (!local()) return
setWorkspaceStore("limit", (limit) => limit + 5)
@@ -1157,7 +1213,7 @@ export default function Layout(props: ParentProps) {
.filter((session) => !session.parentID)
.toSorted(sortSessions),
)
const hasMore = createMemo(() => workspaceStore.session.length >= workspaceStore.limit)
const hasMore = createMemo(() => workspaceStore.sessionTotal > workspaceStore.session.length)
const loadMore = async () => {
setWorkspaceStore("limit", (limit) => limit + 5)
await globalSync.project.loadSessions(props.project.worktree)
@@ -1324,9 +1380,9 @@ export default function Layout(props: ParentProps) {
<DropdownMenu.ItemLabel>Close project</DropdownMenu.ItemLabel>
</DropdownMenu.Item>
<DropdownMenu.Separator />
<DropdownMenu.Item onSelect={() => layout.sidebar.toggleWorkspaces()}>
<DropdownMenu.Item onSelect={() => layout.sidebar.toggleWorkspaces(p().worktree)}>
<DropdownMenu.ItemLabel>
{layout.sidebar.workspaces() ? "Disable workspaces" : "Enable workspaces"}
{layout.sidebar.workspaces(p().worktree)() ? "Disable workspaces" : "Enable workspaces"}
</DropdownMenu.ItemLabel>
</DropdownMenu.Item>
</DropdownMenu.Content>
@@ -1336,7 +1392,7 @@ export default function Layout(props: ParentProps) {
</div>
<Show
when={layout.sidebar.workspaces()}
when={layout.sidebar.workspaces(p().worktree)()}
fallback={
<>
<div class="py-4 px-3">

View File

@@ -293,6 +293,11 @@ pub fn run() {
"#
));
#[cfg(target_os = "macos")]
let window_builder = window_builder
.title_bar_style(tauri::TitleBarStyle::Overlay)
.hidden_title(true);
let _window = window_builder.build().expect("Failed to create window");
let (tx, rx) = oneshot::channel();

View File

@@ -319,9 +319,6 @@ render(() => {
return (
<PlatformProvider value={platform}>
<AppBaseProviders>
{ostype() === "macos" && (
<div class="mx-px bg-background-base border-b border-border-weak-base h-8" data-tauri-drag-region />
)}
<ServerGate>
{(data) => {
setServerPassword(data().password)