All files / src/desktop EditorGlass.ts

100% Statements 27/27
95% Branches 19/20
100% Functions 4/4
100% Lines 27/27

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60            12x 12x   3x   12x 12x                   9x 9x 9x     9x 9x 9x 9x 9x 6x 5x 1x       5x   3x 3x     1x   9x 9x 9x         1x 1x 2x 2x      
import { invoke } from '@tauri-apps/api/core';
import { Effect, EffectState, getCurrentWindow } from '@tauri-apps/api/window';
 
/** Window design strength (0-100) shared with the main window: the saved file wins over localStorage. */
export async function loadBlend(): Promise<number> {
  let saved: number | null;
  try {
    saved = await invoke<number | null>('theme_blend');
  } catch {
    saved = null;
  }
  const value = saved ?? Number(localStorage.getItem('themeBlend'));
  return Number.isFinite(value)
    ? Math.max(0, Math.min(100, Math.round(value)))
    : 0;
}
 
/**
 * Gives a macOS editor window the main window's Window design: the same blend, native
 * Liquid Glass (or vibrancy before macOS 26) and reduced-transparency handling.
 */
export async function applyEditorGlass(): Promise<void> {
  const root = document.documentElement;
  const blend = await loadBlend();
  const reduced = matchMedia(
    '(prefers-reduced-transparency: reduce), (prefers-contrast: more)',
  ).matches;
  const glass = blend > 0 && !reduced;
  let native = false;
  try {
    const win = getCurrentWindow();
    if (glass) {
      const liquid = await invoke<boolean>('set_liquid_glass', { on: true });
      if (!liquid)
        await win.setEffects({
          effects: [Effect.UnderWindowBackground],
          state: EffectState.Active,
        });
      native = true;
    } else {
      await invoke('set_liquid_glass', { on: false });
      await win.clearEffects();
    }
  } catch {
    native = false;
  }
  root.style.setProperty('--theme-blend', String(glass ? blend / 100 : 0));
  root.dataset.appearance = glass ? 'glass' : 'mac';
  root.dataset.nativeGlass = String(glass && native);
}
 
/** Keeps an editor window in step with the main window's design slider. */
export function watchEditorGlass() {
  void applyEditorGlass();
  addEventListener('storage', (event) => {
    Eif (event.key === 'themeBlend' || event.key === null)
      void applyEditorGlass();
  });
}