SYNC: working widget resizing

This commit is contained in:
SPRINX0\prochazka
2025-12-11 14:37:11 +01:00
committed by Diflow
parent e004ed2f4b
commit 142791360c
2 changed files with 105 additions and 44 deletions

View File

@@ -1,3 +1,4 @@
import { newMatcherFn } from 'diff2html/lib/rematch';
import _ from 'lodash'; import _ from 'lodash';
export interface WidgetBarStoredProps { export interface WidgetBarStoredProps {
@@ -11,6 +12,7 @@ export interface WidgetBarStoredPropsResult {
export interface WidgetBarComputedProps { export interface WidgetBarComputedProps {
contentHeight: number; contentHeight: number;
storedHeight?: number;
visibleItemsCount: number; visibleItemsCount: number;
splitterVisible: boolean; splitterVisible: boolean;
collapsed: boolean; collapsed: boolean;
@@ -62,6 +64,9 @@ export function computeInitialWidgetBarProps(
definitions: WidgetBarItemDefinition[], definitions: WidgetBarItemDefinition[],
currentProps: WidgetBarComputedResult currentProps: WidgetBarComputedResult
): WidgetBarComputedResult { ): WidgetBarComputedResult {
if (!container.clientHeight) {
return currentProps;
}
const visibleItems = definitions.filter(def => !def.skip); const visibleItems = definitions.filter(def => !def.skip);
const expandedItems = visibleItems.filter(def => !(currentProps[def.name]?.collapsed ?? def.collapsed)); const expandedItems = visibleItems.filter(def => !(currentProps[def.name]?.collapsed ?? def.collapsed));
const res: WidgetBarComputedResult = {}; const res: WidgetBarComputedResult = {};
@@ -78,6 +83,7 @@ export function computeInitialWidgetBarProps(
const isExpanded = def.name === expandedItem?.name; const isExpanded = def.name === expandedItem?.name;
res[def.name] = { res[def.name] = {
contentHeight: isExpanded ? availableContentHeight : 0, contentHeight: isExpanded ? availableContentHeight : 0,
storedHeight: currentProps[def.name]?.contentHeight,
visibleItemsCount: visibleItems.length, visibleItemsCount: visibleItems.length,
splitterVisible: false, splitterVisible: false,
collapsed: !isExpanded, collapsed: !isExpanded,
@@ -93,8 +99,8 @@ export function computeInitialWidgetBarProps(
const flexibleItems = []; const flexibleItems = [];
for (const def of expandedItems) { for (const def of expandedItems) {
if (def.storeHeight && currentProps[def.name]?.contentHeight > 0) { if (def.storeHeight && currentProps[def.name]?.storedHeight > 0) {
const storedHeight = currentProps[def.name].contentHeight; const storedHeight = currentProps[def.name].storedHeight;
itemHeights[def.name] = storedHeight; itemHeights[def.name] = storedHeight;
totalContentHeight += storedHeight; totalContentHeight += storedHeight;
} else if (def.height) { } else if (def.height) {
@@ -143,6 +149,7 @@ export function computeInitialWidgetBarProps(
visibleItemsCount: visibleItems.length, visibleItemsCount: visibleItems.length,
splitterVisible: visibleItems.length > 1 && visibleIndex < visibleItems.length - 1, splitterVisible: visibleItems.length > 1 && visibleIndex < visibleItems.length - 1,
collapsed: !expandedItems.includes(def), collapsed: !expandedItems.includes(def),
storedHeight: currentProps[def.name]?.storedHeight,
clickableTitle: true, clickableTitle: true,
}; };
visibleIndex += 1; visibleIndex += 1;
@@ -160,47 +167,78 @@ export function handleResizeWidgetBar(
): WidgetBarComputedResult { ): WidgetBarComputedResult {
const res = _.cloneDeep(currentProps); const res = _.cloneDeep(currentProps);
const visibleItems = definitions.filter(def => !def.skip); const visibleItems = definitions.filter(def => !def.skip);
const resizedItemDef = definitions.find(def => def.name === resizedItemName); const currentItemDef = definitions.find(def => def.name === resizedItemName);
if (!resizedItemDef || resizedItemDef.collapsed) return res; if (!currentItemDef || currentItemDef.collapsed) return res;
const resizedItemProps = res[resizedItemName]; const currentItemProps = res[resizedItemName];
let itemIndex = visibleItems.findIndex(def => def.name === resizedItemName);
const itemProps = res[currentItemDef.name];
const nextItemDef = visibleItems[itemIndex + 1];
const currentHeight = itemProps.contentHeight;
const nextItemProps = res[nextItemDef.name];
if (!nextItemDef) return res;
if (deltaY < 0) { if (deltaY < 0) {
// moving up - reduce height of resized item, if too small, reduce height of previous items let newHeight = currentHeight + deltaY;
let remainingDeltaY = -deltaY; if (newHeight < currentItemDef.minimalContentHeight) {
let itemIndex = visibleItems.findIndex(def => def.name === resizedItemName); newHeight = currentItemDef.minimalContentHeight;
while (remainingDeltaY > 0 && itemIndex >= 0) {
const itemDef = visibleItems[itemIndex];
const itemProps = res[itemDef.name];
const currentHeight = itemProps.contentHeight;
const minimalHeight = itemDef.minimalContentHeight;
const reducibleHeight = currentHeight - minimalHeight;
if (reducibleHeight > 0) {
const reduction = Math.min(reducibleHeight, remainingDeltaY);
itemProps.contentHeight -= reduction;
remainingDeltaY -= reduction;
}
itemIndex -= 1;
} }
const actualDeltaY = newHeight - currentHeight;
nextItemProps.contentHeight -= actualDeltaY;
currentItemProps.contentHeight += actualDeltaY;
// // moving up - reduce height of resized item, if too small, reduce height of previous items
// let remainingDeltaY = -deltaY;
// let itemIndex = visibleItems.findIndex(def => def.name === resizedItemName);
// while (remainingDeltaY > 0 && itemIndex >= 0) {
// const itemDef = visibleItems[itemIndex];
// const itemProps = res[itemDef.name];
// const currentHeight = itemProps.contentHeight;
// const minimalHeight = itemDef.minimalContentHeight;
// const reducibleHeight = currentHeight - minimalHeight;
// if (reducibleHeight > 0) {
// const reduction = Math.min(reducibleHeight, remainingDeltaY);
// itemProps.contentHeight -= reduction;
// remainingDeltaY -= reduction;
// }
// itemIndex -= 1;
// }
} else { } else {
let newHeight = nextItemProps.contentHeight - deltaY;
if (newHeight < nextItemDef.minimalContentHeight) {
newHeight = nextItemDef.minimalContentHeight;
}
const actualDeltaY = nextItemProps.contentHeight - newHeight;
nextItemProps.contentHeight -= actualDeltaY;
currentItemProps.contentHeight += actualDeltaY;
// moving down - increase height of resized item, reduce size of next item, if too small, reduce size of further items // moving down - increase height of resized item, reduce size of next item, if too small, reduce size of further items
// if all items below are at minimal height, stop // if all items below are at minimal height, stop
let remainingDeltaY = deltaY; // let remainingDeltaY = deltaY;
let itemIndex = visibleItems.findIndex(def => def.name === resizedItemName) + 1; // let itemIndex = visibleItems.findIndex(def => def.name === resizedItemName);
while (remainingDeltaY > 0 && itemIndex < visibleItems.length) { // while (remainingDeltaY > 0 && itemIndex < visibleItems.length) {
const itemDef = visibleItems[itemIndex]; // const itemDef = visibleItems[itemIndex];
const itemProps = res[itemDef.name]; // const itemProps = res[itemDef.name];
const currentHeight = itemProps.contentHeight; // const currentHeight = itemProps.contentHeight;
const minimalHeight = itemDef.minimalContentHeight; // const minimalHeight = itemDef.minimalContentHeight;
const reducibleHeight = currentHeight - minimalHeight; // const reducibleHeight = currentHeight - minimalHeight;
if (reducibleHeight > 0) { // if (reducibleHeight > 0) {
const reduction = Math.min(reducibleHeight, remainingDeltaY); // const reduction = Math.min(reducibleHeight, remainingDeltaY);
itemProps.contentHeight -= reduction; // itemProps.contentHeight -= reduction;
resizedItemProps.contentHeight += reduction; // resizedItemProps.contentHeight += reduction;
remainingDeltaY -= reduction; // remainingDeltaY -= reduction;
// }
// itemIndex += 1;
// }
} }
itemIndex += 1;
if (currentItemDef.storeHeight) {
currentItemProps.storedHeight = currentItemProps.contentHeight;
} }
if (nextItemDef.storeHeight) {
nextItemProps.storedHeight = nextItemProps.contentHeight;
} }
return res; return res;
} }
@@ -242,11 +280,29 @@ export function extractStoredWidgetBarProps(
const def = definitions.find(d => d.name === key); const def = definitions.find(d => d.name === key);
if (!def) continue; if (!def) continue;
res[key] = { res[key] = {
contentHeight: contentHeight: def.storeHeight ? currentProps[key]?.storedHeight : undefined,
def.storeHeight && currentProps[key]?.contentHeight > 0 ? currentProps[key]?.contentHeight : undefined,
collapsed: currentProps[key]?.collapsed, collapsed: currentProps[key]?.collapsed,
}; };
} }
return res; return res;
} }
export function createWidgetBarComputedResultFromStored(stored: WidgetBarStoredPropsResult): WidgetBarComputedResult {
const res: WidgetBarComputedResult = {};
if (!stored) return res;
let visibleIndex = 0;
const visibleCount = Object.keys(stored).length;
for (const key in stored) {
res[key] = {
storedHeight: stored[key]?.contentHeight,
contentHeight: 0,
collapsed: stored[key]?.collapsed,
clickableTitle: false,
splitterVisible: visibleCount > 1 && visibleIndex < visibleCount - 1,
visibleItemsCount: 0,
};
visibleIndex += 1;
}
return res;
}

View File

@@ -1,10 +1,11 @@
<script lang="ts"> <script lang="ts">
import { onMount, setContext } from 'svelte'; import { onMount, setContext } from 'svelte';
import { writable } from 'svelte/store'; import { writable } from 'svelte/store';
import _ from 'lodash'; import _, { get } from 'lodash';
import { getLocalStorage, setLocalStorage } from '../utility/storageCache'; import { getLocalStorage, setLocalStorage } from '../utility/storageCache';
import { import {
computeInitialWidgetBarProps, computeInitialWidgetBarProps,
createWidgetBarComputedResultFromStored,
extractStoredWidgetBarProps, extractStoredWidgetBarProps,
handleResizeWidgetBar, handleResizeWidgetBar,
toggleCollapseWidgetBar, toggleCollapseWidgetBar,
@@ -18,7 +19,7 @@
let clientHeight; let clientHeight;
// const widgetColumnBarHeight = writable(0); // const widgetColumnBarHeight = writable(0);
const widgetColumnBarComputed = writable({}); const widgetColumnBarComputed = writable(createWidgetBarComputedResultFromStored(getLocalStorage(storageName)));
$: containerProps = { $: containerProps = {
clientHeight, clientHeight,
@@ -57,15 +58,19 @@
// $: $widgetColumnBarHeight = clientHeight; // $: $widgetColumnBarHeight = clientHeight;
$: recompute(definitions); $: {
definitions;
containerProps;
recompute();
}
function recompute(defs: WidgetBarItemDefinition[]) { function recompute() {
$widgetColumnBarComputed = computeInitialWidgetBarProps(containerProps, defs, getLocalStorage(storageName) || {}); $widgetColumnBarComputed = computeInitialWidgetBarProps(containerProps, definitions, $widgetColumnBarComputed);
saveStorage(); saveStorage();
} }
onMount(() => { onMount(() => {
recompute(definitions); recompute();
}); });
</script> </script>