Files
element-call/src/lotus/lotusWidget.ts
T
Lotus CIandClaude Opus 5 e9a59336c7 fix(lotus): transparent-theme contrast guard; phone-only rail shrink; live URL params
- lotusTransparent without lotusTheme warns and applies the theme anyway;
  name tags/header/footer get a subtle text-shadow + backdrop blur under
  body.lotus-transparent (#21).
- Landscape filmstrip shrink requires (pointer: coarse) so a short
  desktop/PiP window isn't reflowed as a phone (#32).
- lotusParam re-reads window.location on every call (#33).

Fixes #21
Fixes #32
Fixes #33

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-09-13 01:22:20 -04:00

70 lines
2.5 KiB
TypeScript

/*
Copyright 2026 Lotus Guild
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
/**
* Shared helpers for the Lotus fork's widget extensions.
*
* Everything here is **opt-in**: each feature is gated behind a `lotus*` URL
* param that the Lotus host (cinny) appends to the widget iframe URL. With no
* param present, none of this code changes Element Call's behaviour — which
* keeps the fork a minimal, additive, easy-to-rebase diff over upstream.
*/
import { logger } from "matrix-js-sdk/lib/logger";
import { widget } from "../widget";
import type { LotusWidgetActions } from "./lotusActions";
export { LotusWidgetActions } from "./lotusActions";
/**
* Read a URL param from either the query string or the hash fragment (Element
* Call passes widget params via both depending on host), without depending on
* EC's own `getUrlParams` parser (keeps the rebase surface small).
*
* [lotus #33] Re-parsed from `window.location` on every call instead of being
* cached at first use: parsing is cheap, and caching risked returning a
* stale value if `location.hash`/`search` are ever rewritten after first
* read (e.g. during in-iframe navigation).
*/
export function lotusParam(name: string): string | null {
// Match EC's own ParamParser precedence: the hash fragment wins over the
// query string. So seed from the fragment first, then fill gaps from query.
const hash = window.location.hash.replace(/^#\/?/, "");
const hashQuery = hash.includes("?") ? hash.slice(hash.indexOf("?") + 1) : "";
const params = new URLSearchParams(hashQuery);
for (const [k, v] of new URLSearchParams(window.location.search)) {
if (!params.has(k)) params.append(k, v);
}
return params.get(name);
}
/** Whether a boolean-ish Lotus feature flag is enabled. */
export function lotusFlag(name: string): boolean {
const v = lotusParam(name);
return v === "1" || v === "true";
}
/**
* Send a fromWidget message to the Lotus host, swallowing the inevitable
* rejection when the host hasn't (yet) registered a handler for it. Returns
* true if the widget transport was available to attempt the send.
*/
export function lotusSendToHost(
action: LotusWidgetActions,
data: unknown,
): boolean {
const api = widget?.api;
if (!api) return false;
void api.transport
.send(action, data as Record<string, unknown>)
.catch((e) => {
logger.debug(`[lotus] host did not ack ${action}`, e);
});
return true;
}