customize.tsx 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import { useCallback } from 'react';
  2. import useSWR, { SWRResponse } from 'swr';
  3. import useSWRImmutable from 'swr/immutable';
  4. import { apiv3Get, apiv3Put } from '~/client/util/apiv3-client';
  5. import type { updateConfigMethodForAdmin } from '~/interfaces/admin';
  6. import type { IResLayoutSetting, IResGrowiTheme } from '~/interfaces/customize';
  7. export const useSWRxLayoutSetting = (): SWRResponse<IResLayoutSetting, Error> & updateConfigMethodForAdmin<IResLayoutSetting> => {
  8. const fetcher = useCallback(async() => {
  9. const res = await apiv3Get('/customize-setting/layout');
  10. return res.data;
  11. }, []);
  12. const swrResponse = useSWRImmutable('/customize-setting/layout', fetcher);
  13. const update = useCallback(async(layoutSetting: IResLayoutSetting) => {
  14. await apiv3Put('/customize-setting/layout', layoutSetting);
  15. await swrResponse.mutate();
  16. }, [swrResponse]);
  17. return {
  18. ...swrResponse,
  19. update,
  20. };
  21. };
  22. export const useSWRxGrowiThemeSetting = (): SWRResponse<IResGrowiTheme, Error> => {
  23. const fetcher = useCallback(async() => {
  24. const res = await apiv3Get<IResGrowiTheme>('/customize-setting/theme');
  25. return res.data;
  26. }, []);
  27. const swrResponse = useSWR('/customize-setting/theme', fetcher);
  28. const update = async(theme: string) => {
  29. await apiv3Put('/customize-setting/layout', { theme });
  30. if (swrResponse.data == null) {
  31. swrResponse.mutate();
  32. return;
  33. }
  34. const newData = { ...swrResponse.data, currentTheme: theme };
  35. // The updateFn should be a promise or asynchronous function to handle the remote mutation
  36. // it should return updated data. see: https://swr.vercel.app/docs/mutation#optimistic-updates
  37. // Moreover, `async() => false` does not work since it's too fast to be calculated.
  38. await swrResponse.mutate(new Promise(r => setTimeout(() => r(newData), 10)), { optimisticData: () => newData });
  39. };
  40. return Object.assign(
  41. swrResponse,
  42. {
  43. update,
  44. },
  45. );
  46. };