farirpgs / fari-app

The Free and Open-Source VTT

Home Page:https://fari.app/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Presenter View / Streamer View

RPDeshaies opened this issue · comments

🚩 Is your feature request related to a problem? Please describe

When using the offline mode, I would like to look at my private index cards without everyone having the ability to see them while I cast my screen.

When I use Fari with my group, I would like to have a Twitch tailored user interface so that I can stream the content of Fari inside OBS for all my viewer's to see

✅ Describe the solution you'd like

We could look at using React Portal to open a new window and update the content of that portal dynamically.

export function WindowPortal(props: { children: ReactNode; onClose(): void }) {
  const externalWindow = useRef<Window | null>();

  const containerEl = useRef<HTMLDivElement>();
  if (!containerEl.current) {
    containerEl.current = document.createElement("div");
  }
  useEffect(() => {
    externalWindow.current = window.open(
      "",
      "",
      "width=600,height=400,left=200,top=200"
    );

    if (externalWindow.current && containerEl.current) {
      externalWindow.current.document.body.appendChild(containerEl.current);
      externalWindow.current.onbeforeunload = () => {
        props.onClose();
      };
    }
    return () => {
      if (externalWindow.current) {
        externalWindow.current.close();
      }
    };
  }, []);

  return ReactDOM.createPortal(props.children, containerEl.current);
}

The issue with this is that JSS / Emotion styles generated inside the real app aren't shared with the new window.
We could do a one time copy, but that would mean that style updates would not be synced.
We could also manually copy styles every n seconds but it would be a very hackish way to solve this issue.

We could also use Emotion's cache provider, but that would only solve half the issue because some components don't use emotion but rely instead of MUI's styling.

emotion-js/emotion#1229 (comment)

A low-hanging fruit would be to have a custom set of components that are MADE to live outside the scope of the real app, but that would mean having to rewrite a couple of components to handle this.

Syncing data and events on the other hand is going to be handled super easily.

The main issue that we need to investigate is how to handle syncing the CSS styles between the main app and the portal opened in a new window.