import { assign, setup } from "xstate"; import { Context, Events } from "./types.ts"; export const machineBase = setup({ types: { context: {} as Context, events: {} as Events, }, actions: { registerSlides: assign(({ context, event }) => { if (event.type === "presentation.start") { const currentIndex = event.slides.findIndex((s) => s.id === event.currentSlide ); return { ...context, presentationId: event.presentationId, slides: event.slides, currentIndex: Math.max(currentIndex, 0), channel: new BroadcastChannel(event.presentationId), }; } else { return context; } }), scrollToSlide({ context }) { if (context.currentIndex > 0) { const slide = context.slides[context.currentIndex]; document.querySelector(`#${slide.id}`)?.scrollIntoView({ behavior: "instant", }); } }, updateUrl({ context }) { const url = new URL(document.URL); const hash = `#${context.slides[context.currentIndex].id}`; url.hash = hash; location.replace(url); }, updateCurrentSlide: assign({ currentIndex: ({ context, event }) => { if (event.type === "navigate.scroll") { const index = context.slides.findIndex((s) => s.id === event.slideId); return Math.max(index, 0); } return context.currentIndex; }, }), nextSlide: assign({ currentIndex: ({ context }) => { if (context.currentIndex + 1 > context.slides.length - 1) { return context.currentIndex; } return context.currentIndex + 1; }, }), previousSlide: assign({ currentIndex: ({ context }) => { if (context.currentIndex - 1 < 0) { return context.currentIndex; } return context.currentIndex - 1; }, }), }, });