ahooks#useLocalStorageState TypeScript Examples

The following examples show how to use ahooks#useLocalStorageState. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: declare-dialog.tsx    From bext with MIT License 6 votes vote down vote up
DeclareDialog: FC = () => {
  const [read, setRead] = useLocalStorageState<boolean>(BEXT_DECLARE_READ_KEY, {
    defaultValue: false,
  });

  return read ? null : (
    <Dialog
      hidden={false}
      onDismiss={() => setRead(true)}
      dialogContentProps={{
        type: DialogType.largeHeader,
        title: '首次访问声明',
        subText: DECLARE_TEXT,
      }}
      modalProps={{ isBlocking: true, layerProps: { hostId: LAYER_HOST_ID } }}
    >
      <DialogFooter>
        <PrimaryButton
          onClick={() => setRead(true)}
          text="我已阅读并同意以上内容"
        />
      </DialogFooter>
    </Dialog>
  );
}
Example #2
Source File: preference.ts    From bext with MIT License 6 votes vote down vote up
[PreferenceProvider, usePreference] = constate(() => {
  const [preference, set] = useLocalStorageState<Preference>('BEXT.PREF', {
    defaultValue: {},
  });
  const ref = useRef(preference);
  const setPreference = useCallback((value: Partial<Preference>) => {
    set((old) => {
      ref.current = { ...old, ...value };
      return ref.current;
    });
  }, []);

  const getPreference = useCallback(() => ref.current, []);

  return {
    preference,
    setPreference,
    getPreference,
  };
})
Example #3
Source File: review.tsx    From bext with MIT License 5 votes vote down vote up
MetaReview: FC = () => {
  useMount(() => {
    trackEvent(Events.metaReview, currentMeta?.id);
  });

  const { currentMeta } = useMetaDetail();
  const theme = useTheme();

  const [reviewKey, setReviewKey] = useState('source');
  const [monaco, setMonaco] = useLocalStorageState('BEXT.DETAIL_MONACO', {
    defaultValue: false,
  });
  const history = useHistory();

  useTitle(`查看代码:${currentMeta?.name}`);

  return (
    <>
      <header
        className="px-3 flex items-center justify-between"
        style={{
          borderBottom: `1px solid ${theme.semanticColors.bodyDivider}`,
        }}
      >
        <CommandBarButton
          text="返回"
          iconProps={{ iconName: 'ChevronLeft' }}
          className="h-8 mr-2"
          onClick={() => {
            history.goBack();
          }}
        />
        <Pivot
          headersOnly
          selectedKey={reviewKey}
          onLinkClick={(item) =>
            item && setReviewKey(item.props.itemKey || 'source')
          }
          className="flex-1"
        >
          <PivotItem headerText="Source" itemKey="source" />
          <PivotItem headerText="Detail" itemKey="detail" />
        </Pivot>
        <Checkbox
          label="Monaco"
          checked={monaco}
          onChange={() => setMonaco(!monaco)}
        />
      </header>
      {monaco ? (
        <div className="flex-1 overflow-y-hidden">
          <Editor
            value={(currentMeta as any)?.[reviewKey]}
            options={{
              readOnly: true,
            }}
            language={reviewKey === 'detail' ? 'html' : 'javascript'}
          />
        </div>
      ) : (
        <div className="p-4 overflow-auto flex-1">
          <code className="whitespace-pre text-xs">
            {(currentMeta as any)?.[reviewKey]}
          </code>
        </div>
      )}
    </>
  );
}
Example #4
Source File: config-install.tsx    From bext with MIT License 4 votes vote down vote up
ConfigInstall: FC<{
  onInstall: (build: string) => void;
  hide?: () => void;
}> = ({ onInstall, hide }) => {
  const { currentMeta } = useMetaDetail();

  const [formData, setFormData] = useState(
    () => currentMeta?.defaultConfig || {},
  );
  const [hasError, setHasError] = useState(false);

  const { notify } = useNotifications();

  const updateConfigCache = useMemoizedFn(() => setConfigCache(formData));

  const { run: install, loading } = useRequest(
    async (config?: any) => {
      const { id, name, version, source, defaultConfig } = currentMeta!;
      onInstall(
        await excuteCompile({
          meta: {
            id,
            name,
            version,
            source,
            defaultConfig: config ?? defaultConfig,
          },
        }),
      );
      hide?.();
    },
    {
      manual: true,
      onError: () =>
        notify({
          message: '编译失败,请点击“更多” -> “报告问题”',
          status: 'error',
        }),
      onSuccess: updateConfigCache,
    },
  );

  const [configCache, setConfigCache] = useLocalStorageState(
    bextConfigCacheKey(currentMeta?.id || 'unknown'),
  );

  const validate = useMemo(() => {
    try {
      return ajv.compile(currentMeta?.configSchema);
    } catch (error) {
      console.error(error);
    }
  }, [currentMeta?.configSchema]);

  const restoreCache = () => {
    if (validate?.(configCache)) {
      setFormData(configCache);
      notify({
        message: '已填充上次安装选项',
        status: 'success',
        dismissAfter: 1000,
      });
    } else {
      notify({
        message: '选项缓存已过期,请重新编辑配置',
        status: 'error',
      });
    }
  };

  return (
    <Dialog
      hidden={false}
      onDismiss={hide}
      dialogContentProps={{ type: DialogType.normal, title: '安装选项' }}
      minWidth={400}
      modalProps={{ layerProps: { hostId: LAYER_HOST_ID } }}
    >
      已为你填充默认选项
      {configCache ? (
        <>
          ,或者点击<Link onClick={restoreCache}>恢复之前的安装配置</Link>
        </>
      ) : null}
      ,你可以直接安装或者修改下方选项后安装。
      <Separator />
      <JsonSchemaForm
        schema={currentMeta?.configSchema}
        formData={formData}
        onChange={({ formData, errors }) => {
          setFormData(formData);
          setHasError(!!errors.length);
        }}
        omitExtraData
        liveOmit
        liveValidate
      >
        <></>
      </JsonSchemaForm>
      <DialogFooter>
        <PrimaryButton
          onClick={() => install(formData)}
          text={loading ? '处理中...' : '安装'}
          disabled={hasError || loading}
        />
        <DefaultButton onClick={hide} text="取消" />
      </DialogFooter>
    </Dialog>
  );
}
Example #5
Source File: draft.ts    From bext with MIT License 4 votes vote down vote up
[DraftProvider, useDraft] = constate(() => {
  const [cacheDraft, setCacheDraft] = useLocalStorageState<Draft>(
    BEXT_DRAFT_KEY,
    { defaultValue: null },
  );

  const [draft, setDraftObject, getDraftObject] =
    useGetState<Draft>(cacheDraft);

  const setDraft = useCallback(
    (state: Draft) =>
      setDraftObject((prev) =>
        state === null
          ? null
          : {
              ...prev,
              ...state,
              // FIXME: 清理存量数据
              build: undefined,
              options: undefined,
            },
      ),
    [],
  );

  const [clientReady, setClientReady, getClientReady] = useGetState(false);

  const injectDraft = useMemoizedFn((content: string = '{}') => {
    try {
      setDraftObject(JSON.parse(content));
      setClientReady(true);
    } catch (error) {}
  });

  useEffect(() => ((window.injectDraft = injectDraft), void 0));

  useEffect(() => {
    if (isBextClient) {
      try {
        window.ReactNativeWebView?.postMessage(
          JSON.stringify({
            type: 'ready',
          }),
        );
      } catch (error) {}
    }
  }, [isBextClient]);

  const saveDraft = useMemoizedFn(() => {
    setCacheDraft(draft);
    if (isBextClient && getClientReady()) {
      try {
        window.ReactNativeWebView?.postMessage(
          JSON.stringify({
            type: 'save',
            payload: draft,
          }),
        );
      } catch (error) {}
    }
  });

  useThrottleEffect(
    () => {
      if (draft) {
        saveDraft();
      }
    },
    [draft],
    { wait: 3000 },
  );

  return {
    draft,
    setDraft,
    setDraftObject,
    getDraftObject,
    saveDraft,
    cacheDraft,
  };
})