Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/imo-ui.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { ensureGlobalCollageJs } from "@collagejs/core";
import { ensureImoController } from "./shared/common.js";
import { getInitialImoUiOptions } from "./shared/options.js";
import { getInitialImoUiFactoryOptions } from "./shared/options.js";
import { UiController } from "./UiController.js";

ensureGlobalCollageJs();
ensureImoController();
// @ts-expect-error TS2540 - ui property is declared as read-only.
CollageJs.Imo.ui = new UiController();
const imoUiOptions = await getInitialImoUiOptions();
if (imoUiOptions.localStorageTrigger && localStorage.getItem(imoUiOptions.localStorageTrigger) === 'true') {
const imoUiOptions = await getInitialImoUiFactoryOptions();
if (imoUiOptions.ui.localStorageTrigger && localStorage.getItem(imoUiOptions.ui.localStorageTrigger) === 'true') {
CollageJs.Imo.ui.mount();
}
8 changes: 4 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ import { buildPiece } from "@collagejs/svelte";
import Imo from "./lib/Imo.svelte";
import { cssMountFactory } from "@collagejs/vite-css/ex";
import type { ImoUiFactoryOptions } from "./types.js";
import { getInitialImoUiOptions } from "./shared/options.js";
import { getInitialImoUiFactoryOptions } from "./shared/options.js";
import { initImoUiOptions } from "./lib/state/imoUiOptions";
import type { CorePiece } from "@collagejs/core";

const cssMount = cssMountFactory('piece');

export async function imoUiFactory(options?: ImoUiFactoryOptions): Promise<CorePiece<{}>> {
const mountFn = options?.base ? cssMount.bind({ base: options.base }) : cssMount;
const initialOptions = await getInitialImoUiOptions(options?.ui);
initImoUiOptions(initialOptions);
const initialOptions = await getInitialImoUiFactoryOptions(options);
const mountFn = initialOptions?.base ? cssMount.bind({ base: initialOptions.base }) : cssMount;
initImoUiOptions(initialOptions.ui);
const corePiece = buildPiece(Imo);
return {
mount: [mountFn, corePiece.mount],
Expand Down
4 changes: 2 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { mount } from 'svelte';
import App from './App.svelte';
import { getInitialImoUiOptions } from './shared/options.js';
import { getInitialImoUiFactoryOptions } from './shared/options.js';
import { initImoUiOptions } from './lib/state/imoUiOptions.js';

initImoUiOptions(await getInitialImoUiOptions());
initImoUiOptions((await getInitialImoUiFactoryOptions()).ui);

const app = mount(App, {
target: document.getElementById('app')!,
Expand Down
11 changes: 10 additions & 1 deletion src/private-types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { type ImportMap } from "@collagejs/importmap";
import type { GlassSettings, ImoUiOptions } from "./types.js";
import type { GlassSettings, ImoUiFactoryOptions, ImoUiOptions } from "./types.js";

/**
* Version of `ImoUiOptions` where every setting is a required setting.
Expand All @@ -10,6 +10,15 @@ export type RequiredImoUiOptions = Required<Omit<ImoUiOptions, 'glass'>> & {
*/
glass: Required<GlassSettings>;
}
/**
* Version of `ImoUiFactoryOptions` where every setting is a required setting.
*/
export type RequiredImoUiFactoryOptions = Required<Omit<ImoUiFactoryOptions, 'ui'>> & {
/**
* User interface options.
*/
'ui': RequiredImoUiOptions;
};
/**
* An entry in `@collagejs/imo`'s log.
*/
Expand Down
44 changes: 27 additions & 17 deletions src/shared/options.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import wjConfig from "wj-config";
import type { RequiredImoUiOptions } from "../private-types.js";
import type { RequiredImoUiFactoryOptions, RequiredImoUiOptions } from "../private-types.js";
import { skImoUiOptions } from "./storage-keys.js";
import type { ImoUiOptions, ImPostingOptions } from "../types.js";
import type { ImoUiFactoryOptions, ImPostingOptions } from "../types.js";

/**
* Identifier used to tag IMO options.
Expand All @@ -28,19 +28,23 @@ const defaultImPostingOptions: Required<ImPostingOptions> = {
};

/**
* Default IMO UI options.
* Default IMO UI factory options.
*/
export const defaultImoUiOptions: RequiredImoUiOptions = {
theme: 'system',
position: 'bottom-right',
language: 'en',
localStorageTrigger: 'imo-ui',
glass: {
enabled: true,
blur: 15,
opacity: 0.1,
saturation: 110,
},
export const defaultImoUiFactoryOptions: RequiredImoUiFactoryOptions = {
base: '',
shadowDom: true,
ui: {
theme: 'system',
position: 'bottom-right',
language: 'en',
localStorageTrigger: 'imo-ui',
glass: {
enabled: true,
blur: 15,
opacity: 0.1,
saturation: 110,
},
}
};

/**
Expand Down Expand Up @@ -79,14 +83,20 @@ export async function readImPostingOptions(): Promise<Required<ImPostingOptions>
*
* The script is set by the `@collagejs/vite-im` Vite plug-in; the parameter carries the values given to the IMO UI
* factory function.
*
* ### IMPORTANT
*
* These values are considered *initial* because, as the user interface is used and tweaked by the user/developer,
* settings are stored in local storage. Once a copy of the settings exist in local storage, these options are
* effectively superseded.
* @param options Optional set of options that are merged last (and therefore has the highest priority).
* @returns The final initial set of options for the IMO user interface.
*/
export async function getInitialImoUiOptions(options?: ImoUiOptions): Promise<RequiredImoUiOptions> {
export async function getInitialImoUiFactoryOptions(options?: ImoUiFactoryOptions): Promise<RequiredImoUiFactoryOptions> {
let optionsScript: HTMLElement | null;
try {
return await wjConfig()
.addObject(defaultImoUiOptions)
.addObject(defaultImoUiFactoryOptions)
.addJson<{}>(() => Promise.resolve(optionsScript!.textContent))
.when(() => {
optionsScript = document.querySelector(`script[type="application/json"][id="${imoUiOptionsId}"]`);
Expand All @@ -97,7 +107,7 @@ export async function getInitialImoUiOptions(options?: ImoUiOptions): Promise<Re
}
catch (e) {
console.warn(`Failed to parse default IMO settings: ${(e as Error).message}`);
return structuredClone(defaultImoUiOptions);
return structuredClone(defaultImoUiFactoryOptions);
}
}

Expand Down
Loading