mirror of
https://gitlab.com/upRootNutrition/dotfiles.git
synced 2025-12-08 05:49:25 -06:00
135 lines
4.5 KiB
TypeScript
135 lines
4.5 KiB
TypeScript
|
|
// This returns the flags passed into your Elm application
|
||
|
|
export const flags = async ({ env }: ElmLand.FlagsArgs) => {
|
||
|
|
// Get user's preferred font size by creating a temporary element
|
||
|
|
const tempDiv = document.createElement("div");
|
||
|
|
tempDiv.style.fontSize = "1rem";
|
||
|
|
tempDiv.style.position = "absolute";
|
||
|
|
tempDiv.style.visibility = "hidden";
|
||
|
|
document.body.appendChild(tempDiv);
|
||
|
|
const baseFontSize = parseFloat(window.getComputedStyle(tempDiv).fontSize);
|
||
|
|
document.body.removeChild(tempDiv);
|
||
|
|
|
||
|
|
return {
|
||
|
|
width: window.innerWidth,
|
||
|
|
height: window.innerHeight,
|
||
|
|
baseFontSize: baseFontSize,
|
||
|
|
};
|
||
|
|
};
|
||
|
|
|
||
|
|
// This function is called after your Elm app starts
|
||
|
|
export const onReady = ({ app, env }: ElmLand.OnReadyArgs) => {
|
||
|
|
console.log("Elm is ready", app);
|
||
|
|
|
||
|
|
// Simple loading screen with minimum display time
|
||
|
|
let loadingComplete = false;
|
||
|
|
|
||
|
|
function completeLoading() {
|
||
|
|
if (!loadingComplete && app.ports?.assetsLoaded?.send) {
|
||
|
|
loadingComplete = true;
|
||
|
|
console.log("Loading complete - starting fade out sequence");
|
||
|
|
app.ports.assetsLoaded.send(null);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Set up the loading completion trigger
|
||
|
|
if (app.ports?.checkAssetsLoaded?.subscribe) {
|
||
|
|
app.ports.checkAssetsLoaded.subscribe(() => {
|
||
|
|
console.log("Elm app ready - starting loading timer");
|
||
|
|
|
||
|
|
// Minimum display time for loading screen (so users can see it)
|
||
|
|
const minDisplayTime = 1200; // 1.2 seconds
|
||
|
|
|
||
|
|
// Check if fonts are loaded, then wait for minimum time
|
||
|
|
if (document.fonts) {
|
||
|
|
document.fonts.ready.then(() => {
|
||
|
|
console.log(
|
||
|
|
"Fonts loaded, waiting for minimum display time of",
|
||
|
|
minDisplayTime,
|
||
|
|
"ms",
|
||
|
|
);
|
||
|
|
setTimeout(() => {
|
||
|
|
console.log("Minimum display time elapsed, triggering fade out");
|
||
|
|
completeLoading();
|
||
|
|
}, minDisplayTime);
|
||
|
|
});
|
||
|
|
} else {
|
||
|
|
// Fallback if fonts API not supported
|
||
|
|
console.log("Fonts API not supported, using fallback timing");
|
||
|
|
setTimeout(completeLoading, minDisplayTime + 300);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// Determine initial theme first
|
||
|
|
let initialTheme = "dark"; // Match Elm's hardcoded default
|
||
|
|
const savedTheme = localStorage.getItem("app-theme");
|
||
|
|
if (savedTheme) {
|
||
|
|
initialTheme = savedTheme;
|
||
|
|
} else if (window.matchMedia) {
|
||
|
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
||
|
|
initialTheme = mediaQuery.matches ? "dark" : "light";
|
||
|
|
}
|
||
|
|
|
||
|
|
// Store the determined initial theme
|
||
|
|
localStorage.setItem("app-theme", initialTheme);
|
||
|
|
|
||
|
|
// Handle saving theme to localStorage AND toggle requests
|
||
|
|
if (app.ports?.saveTheme?.subscribe) {
|
||
|
|
app.ports.saveTheme.subscribe((themeOrSignal: unknown) => {
|
||
|
|
if (themeOrSignal === "toggle") {
|
||
|
|
// Handle toggle request - now we know localStorage has the current theme
|
||
|
|
const currentTheme = localStorage.getItem("app-theme") || initialTheme;
|
||
|
|
const newTheme = currentTheme === "light" ? "dark" : "light";
|
||
|
|
console.log("Toggling theme from", currentTheme, "to", newTheme);
|
||
|
|
localStorage.setItem("app-theme", newTheme);
|
||
|
|
|
||
|
|
// Send new theme back to Elm
|
||
|
|
if (app.ports?.loadTheme?.send) {
|
||
|
|
app.ports.loadTheme.send(newTheme);
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
// Handle normal theme saving (when theme is set directly)
|
||
|
|
console.log("Saving theme:", themeOrSignal);
|
||
|
|
localStorage.setItem("app-theme", themeOrSignal as string);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// Load theme from localStorage on startup
|
||
|
|
if (app.ports?.loadTheme?.send) {
|
||
|
|
console.log("Loading initial theme:", initialTheme);
|
||
|
|
app.ports.loadTheme.send(initialTheme);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Optional: Listen for system theme changes
|
||
|
|
if (window.matchMedia) {
|
||
|
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
||
|
|
mediaQuery.addEventListener("change", (e) => {
|
||
|
|
// Only apply if user hasn't manually saved a theme preference
|
||
|
|
if (!savedTheme) {
|
||
|
|
const systemTheme = e.matches ? "dark" : "light";
|
||
|
|
console.log("System theme changed:", systemTheme);
|
||
|
|
localStorage.setItem("app-theme", systemTheme);
|
||
|
|
if (app.ports?.loadTheme?.send) {
|
||
|
|
app.ports.loadTheme.send(systemTheme);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// Type definitions for Elm Land
|
||
|
|
namespace ElmLand {
|
||
|
|
export type FlagsArgs = {
|
||
|
|
env: Record<string, string>;
|
||
|
|
};
|
||
|
|
export type OnReadyArgs = {
|
||
|
|
env: Record<string, string>;
|
||
|
|
app: { ports?: Record<string, Port> };
|
||
|
|
};
|
||
|
|
export type Port = {
|
||
|
|
send?: (data: unknown) => void;
|
||
|
|
subscribe?: (callback: (data: unknown) => unknown) => void;
|
||
|
|
};
|
||
|
|
}
|