persist tab pane state, handle vertical scrolling in tab pane

This commit is contained in:
Ennea
2025-10-01 16:35:27 +02:00
parent 2cdc5bfcd9
commit 9f097b4df3
5 changed files with 33 additions and 12 deletions
@@ -1,5 +1,5 @@
<script lang="ts">
import { selectedTab, knownTabs, tabBarState } from "$lib/shared.svelte";
import { selectedTab, knownTabs, tabPaneState, closeTabPane } from "$lib/shared.svelte";
async function selectTab(index: number) {
const rawResponse = await fetch('/tab', {
@@ -13,17 +13,13 @@
// const content = await rawResponse.json();
// TODO: use the response
}
function closeTabBar() {
tabBarState.visible = false;
}
</script>
<aside id="tabs" class:visible={tabBarState.visible}>
<aside id="tabs" class:visible={tabPaneState.visible}>
<div class="inner">
<header>
<span>Tabs</span>
<button type="button" onclick={() => closeTabBar()}>
<button type="button" onclick={() => closeTabPane()}>
<!-- "x" icon from https://github.com/feathericons/feather, under MIT license -->
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
@@ -1,12 +1,13 @@
<script lang="ts">
import { tabBarState } from "$lib/shared.svelte";
import { tabPaneState, openTabPane } from "$lib/shared.svelte";
function onclick() {
tabBarState.visible = true;
openTabPane();
}
</script>
<button type="button" aria-label="Open tab pane" class:visible={!tabBarState.visible} {onclick}>
<button type="button" aria-label="Open tab pane" class:visible={!tabPaneState.visible} {onclick} disabled={tabPaneState.visible}>
<!-- "chevron-right" icon from https://github.com/feathericons/feather, under MIT license -->
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>
</button>
+12 -1
View File
@@ -11,4 +11,15 @@ export interface ChannelOption {
export const selectedTab: { index: number } = $state({ index: 0 });
export const knownTabs: ChatTab[] = $state([]);
export const tabBarState: { visible: boolean } = $state({ visible: false });
export const tabPaneState: { visible: boolean } = $state({ visible: false });
export const persistentTabPabeStateKey = 'chat2_tab_pane_visible';
export function openTabPane() {
tabPaneState.visible = true;
window.localStorage.setItem(persistentTabPabeStateKey, 'true');
}
export function closeTabPane() {
tabPaneState.visible = false;
window.localStorage.setItem(persistentTabPabeStateKey, 'false');
}
@@ -3,6 +3,7 @@
import { Alert } from "@sveltestrap/sveltestrap";
import { onMount } from 'svelte';
import { ChatTwoWeb } from '$lib/chat.svelte'
import { tabPaneState, persistentTabPabeStateKey } from "$lib/shared.svelte";
import { addGfdStylesheet } from "$lib/gfd";
import DynamicTextArea from "../../components/DynamicTextArea.svelte";
import ChannelSelector from "../../components/ChannelSelector.svelte";
@@ -30,6 +31,17 @@
// Populate the stylesheet with gfd data
addGfdStylesheet('/files/gfdata.gfd', '/files/fonticon_ps5.tex');
// read saved tab pane state from localStorage
try {
const tabPaneVisible = window.localStorage.getItem(persistentTabPabeStateKey);
if (tabPaneVisible !== null) {
tabPaneState.visible = JSON.parse(tabPaneVisible);
}
} catch (e) {
// JSON.parse() failed, let's reset what's in localStorage
window.localStorage.removeItem(persistentTabPabeStateKey);
}
// Load all web functions in the background
const _ = new ChatTwoWeb();
});
@@ -119,7 +119,8 @@ main.auth {
/* tab list */
aside#tabs {
flex: 0 0 auto;
overflow: hidden;
overflow-x: hidden;
scrollbar-color: var(--fg-scrollbar) var(--bg-sidebar);
background-color: var(--bg-sidebar);
transition: width 250ms ease;