frontend: polish app launch and release experience

This commit is contained in:
archipelago
2026-06-11 00:24:40 -04:00
parent c393b96da3
commit 1a3d726eac
140 changed files with 5930 additions and 920 deletions
@@ -0,0 +1,42 @@
import { nextTick, onBeforeUnmount, onMounted, ref, type Ref } from 'vue'
export function useCollapsingHeaderTabs(
headerRef: Ref<HTMLElement | null>,
primaryRef: Ref<HTMLElement | null>,
tabsProbeRef: Ref<HTMLElement | null>,
minSearchWidth = 176
) {
const collapsed = ref(false)
let resizeObserver: ResizeObserver | null = null
function measure() {
const header = headerRef.value
const probe = tabsProbeRef.value
if (!header || !probe) return
const primaryWidth = primaryRef.value?.getBoundingClientRect().width ?? 0
const tabsWidth = probe.getBoundingClientRect().width
const gapWidth = 48
collapsed.value = primaryWidth + tabsWidth + minSearchWidth + gapWidth > header.clientWidth
}
function scheduleMeasure() {
nextTick(() => requestAnimationFrame(measure))
}
onMounted(() => {
scheduleMeasure()
resizeObserver = new ResizeObserver(scheduleMeasure)
if (headerRef.value) resizeObserver.observe(headerRef.value)
if (primaryRef.value) resizeObserver.observe(primaryRef.value)
if (tabsProbeRef.value) resizeObserver.observe(tabsProbeRef.value)
window.addEventListener('resize', scheduleMeasure)
})
onBeforeUnmount(() => {
resizeObserver?.disconnect()
window.removeEventListener('resize', scheduleMeasure)
})
return { collapsed, measure: scheduleMeasure }
}