import { type JSXElement, Accessor, createContext, createEffect, on, onCleanup, useContext, } from "solid-js"; import type { Client, User } from "stoat.js"; import { useModals } from "@revolt/modal"; import { State } from "@revolt/state"; import { State as LifecycleState } from "./Controller"; import { CHANGELOG_MODAL_CONST } from "@revolt/modal/modals/Changelog"; import ClientController from "./Controller"; export type { default as ClientController } from "./Controller"; const clientContext = createContext(null! as ClientController); /** * Mount the modal controller */ export function ClientContext(props: { state: State; children: JSXElement }) { const { openModal } = useModals(); // eslint-disable-next-line solid/reactivity const controller = new ClientController(props.state); onCleanup(() => controller.dispose()); createEffect(() => { const lastIndex = props.state.settings.getValue("changelog:last_index"); if (controller.lifecycle.state() === LifecycleState.Ready) return; if ( lastIndex !== CHANGELOG_MODAL_CONST.index && new Date() < CHANGELOG_MODAL_CONST.until ) { openModal({ type: "changelog", initial: CHANGELOG_MODAL_CONST.index, }); props.state.settings.setValue( "changelog:last_index", CHANGELOG_MODAL_CONST.index, ); } }); createEffect( on( () => controller.lifecycle.policyAttentionRequired(), (attentionRequired) => { if (typeof attentionRequired !== "undefined") { const [changes, acknowledge] = attentionRequired; openModal({ type: "policy_change", changes, acknowledge, }); } }, ), ); return ( {props.children} ); } /** * Get various lifecycle objects * @returns Lifecycle information */ export function useClientLifecycle() { const { login, logout, selectUsername, lifecycle, isLoggedIn, isError } = useContext(clientContext); return { login, logout, selectUsername, lifecycle, isLoggedIn, isError, }; } /** * Get the currently active client if one is available * @returns Client */ export function useClient(): Accessor { const controller = useContext(clientContext); return () => controller.getCurrentClient()!; } /** * Get the currently logged in user * @returns User */ export function useUser(): Accessor { const controller = useContext(clientContext); return () => controller.getCurrentClient()!.user; } /** * Plain API client with no authentication * @returns API Client */ export function useApi() { return useContext(clientContext).api; } export const IS_DEV = import.meta.env.DEV;