adithyasource / clear

simple and lightweight game launcher
https://clear.adithya.zip
The Unlicense
39 stars 1 forks source link

Use a store to manage `libraryData` #6

Closed jer3m01 closed 5 months ago

jer3m01 commented 5 months ago

Instead of

if (
  libraryData().userSettings.roundedBorders == undefined ||
  libraryData().userSettings.roundedBorders == true
) {
  setRoundedBorders(true);
} else {
  setRoundedBorders(false);
}
if (
  libraryData().userSettings.gameTitle == undefined ||
  libraryData().userSettings.gameTitle == true
) {
  setGameTitle(true);
} else {
  setGameTitle(false);
}
...

(and also instead of below from #5)

const [showSideBar, setShowSideBar] = createSignal(libraryData().userSettings.showSideBar ?? true);
const [roundedBorders, setRoundedBorders] = createSignal(libraryData().userSettings.roundedBorders ?? true);
...

you can use a store to manage all your options:

const [libraryData, setLibraryData] = createStore({
  userSettings: {
    showSideBar: true,
    roundedBorders: true,
    ...
  },
  ...
});

libraryData.userSettings.showSideBar; // => `true`
setLibraryData("userSettings", "showSideBar", false);

A store is like a signal but it works with deeper objects and retains reactivity for nested updates. This also allows you to load the data straight from the JSON:

const [libraryData, setLibraryData] = createStore(JSON.parse(getLibraryData));

For use inside the context you can either export the store itself:

export function GlobalContextProvider(props) {
  const [libraryData, setLibraryData] = createStore(JSON.parse(getLibraryData));

  // set defaults
  ...

  const context = {
    libraryData, 
    setLibraryData,
  };

  return (
    <GlobalContext.Provider value={context}>
      {props.children}
    </GlobalContext.Provider>
  );
}

function ExampleComponent() {
  const context = useGlobalContext();

  context.libraryData.userSettings.showSideBar; // => boolean
  context.setLibraryData("userSettings", "showSideBar", false);
}

or you could create derived signals and setters for each:

export function GlobalContextProvider(props) {
  const [libraryData, setLibraryData] = createStore(JSON.parse(getLibraryData));

  const context = {
    showSideBar: () => libraryData.userSettings.showSideBar ?? true, // set defaults here 
    setShowSideBar: (value) => setLibraryData("userSettings", "showSideBar", value),
  };

  return (
    <GlobalContext.Provider value={context}>
      {props.children}
    </GlobalContext.Provider>
  );
}

function ExampleComponent() {
  const context = useGlobalContext();

  context.showSideBar(); // => boolean
  context.setShowSideBar(true);
}

Solid docs: https://docs.solidjs.com/concepts/stores https://docs.solidjs.com/reference/store-utilities/create-store

Checkout #7 for a better storage interface.

adithyasource commented 5 months ago

thanks for opening the issues, looks like solid advice! i'll definitely implement them in clear while working on the next update!

adithyasource commented 5 months ago

Thank you so much for the suggestions! The store for libraryData was implemented in be7097c and global contexts were implemented in bd05d83