umi#useHistory TypeScript Examples

The following examples show how to use umi#useHistory. 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: use-url-state.ts    From bext with MIT License 7 votes vote down vote up
useUrlState = <S extends UrlState = UrlState>(
  initialState?: S | (() => S),
  options?: Options,
) => {
  type State = Partial<{ [key in keyof S]: any }>;
  const { navigateMode = 'push' } = options || {};
  const history = useHistory();
  const update = useUpdate();

  const initialStateRef = useRef(
    typeof initialState === 'function'
      ? (initialState as () => S)()
      : initialState || {},
  );

  const queryFromUrl = useMemo(() => {
    return parse(location.search, parseConfig);
  }, [location.search]);

  const targetQuery: State = useMemo(
    () => ({
      ...initialStateRef.current,
      ...queryFromUrl,
    }),
    [queryFromUrl],
  );

  const setState = (s: React.SetStateAction<State>) => {
    const newQuery = typeof s === 'function' ? s(targetQuery) : s;
    update();
    history[navigateMode]({
      hash: location.hash,
      search: stringify({ ...queryFromUrl, ...newQuery }, parseConfig) || '?',
    });
  };

  return [targetQuery, useMemoizedFn(setState)] as const;
}
Example #2
Source File: use-history.ts    From bext with MIT License 5 votes vote down vote up
useHistoryPush = () => {
  const history = useHistory();
  const [query] = useUrlState();

  return useMemoizedFn((path: string, newQuery: Record<string, any> = {}) =>
    history.push(`${path}?${queryStr(query, newQuery)}`),
  );
}
Example #3
Source File: use-history.ts    From bext with MIT License 5 votes vote down vote up
useHistoryReplace = () => {
  const history = useHistory();
  const [query] = useUrlState();

  return useMemoizedFn((path: string, newQuery: Record<string, any> = {}) =>
    history.replace(`${path}?${queryStr(query, newQuery)}`),
  );
}
Example #4
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 #5
Source File: index.tsx    From bext with MIT License 5 votes vote down vote up
MetaPage: FC = () => {
  useTitle('脚本');
  const history = useHistory();
  const historyReplace = useHistoryReplace();
  const { metaList, tagList } = useMeta();
  const options = useMemo(
    () => [
      { key: FILTER_ALL, text: '全部分类' },
      ...tagList.map((tag) => ({ key: tag.name, text: tag.name })),
    ],
    [tagList],
  );
  const [filter] = useUrlState({ tag: undefined }, { navigateMode: 'replace' });
  const list = useMemo(
    () =>
      filter.tag
        ? metaList.filter(({ tags }) => tags?.includes(filter.tag))
        : metaList,
    [metaList, filter.tag],
  );
  const onChange = (tag?: string | number) => {
    if (typeof tag === 'string') {
      historyReplace(history.location.pathname, {
        tag: tag === FILTER_ALL ? undefined : tag,
      });
    }
  };

  useEffect(() => {
    trackEvent(Events.tagView, filter.tag || '全部分类');
  }, [filter.tag]);

  return (
    <>
      <div className="flex items-center justify-end px-6 py-2">
        <Dropdown
          options={options}
          selectedKey={filter.tag || FILTER_ALL}
          onChange={(_, option) => onChange(option?.key)}
          responsiveMode={ResponsiveMode.small}
          onRenderOption={(option) => (
            <span
              className={
                option?.key === FILTER_ALL ? 'font-semibold' : undefined
              }
            >
              {option?.text}
            </span>
          )}
        />
      </div>
      <MetaList list={list} withPaddingX />
    </>
  );
}
Example #6
Source File: dev-header.tsx    From bext with MIT License 4 votes vote down vote up
DevHeader: FC = () => {
  const history = useHistory();
  const { draft, saveDraft } = useDraft();
  const [detailVisible, { setTrue: showPanel, setFalse: hidePanel }] =
    useBoolean(false);
  const inDev = useInDev();
  useEffect(() => {
    if (inDev && !draft?.id) {
      showPanel();
    }
  }, [inDev, showPanel, draft]);

  const [publishVisible, { setTrue: showPublish, setFalse: hidePublish }] =
    useBoolean(false);
  const theme = useTheme();
  const { notify } = useNotifications();

  const onDebug = async () => {
    const { id, name, version, source, defaultConfig } = draft!;
    if (id && name && version) {
      try {
        const build = await excuteCompile({
          meta: {
            id,
            name,
            version,
            source: source || '',
            defaultConfig,
          },
        });
        window.ReactNativeWebView?.postMessage(
          JSON.stringify({
            type: 'debug',
            payload: build,
          }),
        );
      } catch (error) {
        notify({
          message: '编译失败,请查看控制台',
          status: 'error',
        });
      }
    } else {
      notify({
        message: '请填写完整 ID,名称,版本号',
        status: 'warning',
      });
    }
  };

  const user = useObservableState(user$);

  return (
    <>
      <header
        className="px-6 flex items-center justify-between h-12"
        style={{
          borderBottom: `1px solid ${theme.semanticColors.bodyDivider}`,
        }}
      >
        {isBextClient ? null : (
          <CommandBarButton
            text="返回"
            iconProps={{ iconName: 'ChevronLeft' }}
            className="h-8"
            onClick={() => {
              saveDraft();
              history.goBack();
            }}
          />
        )}
        <div>
          <DefaultButton onClick={showPanel}>编辑详情</DefaultButton>
          {isBextClient ? (
            <DefaultButton className="ml-3" onClick={onDebug}>
              调试
            </DefaultButton>
          ) : null}
          <PrimaryButton
            className="ml-3"
            onClick={() => {
              if (user.status === 'complete') {
                showPublish();
                return;
              }
              notify({
                status: 'warning',
                message: '请前往更多页面登录后发布',
              });
            }}
          >
            准备发布
          </PrimaryButton>
          <EditDetail visible={detailVisible} hide={hidePanel} />
        </div>
      </header>
      <Dialog
        hidden={!publishVisible}
        onDismiss={hidePublish}
        dialogContentProps={{
          type: DialogType.normal,
          title: '填写版本更新信息',
        }}
        modalProps={{
          isBlocking: false,
          layerProps: { hostId: LAYER_HOST_ID },
        }}
      >
        <PublishDialog hide={hidePublish} />
      </Dialog>
    </>
  );
}
Example #7
Source File: index.tsx    From ant-design-pro-V5-multitab with MIT License 4 votes vote down vote up
Tab = (props: ITab) => {
    const history = useHistory()
    const { value, tabIndex } = props;
    const { active, dispatch, tabWidth, tarnslateX, showTabs, tabsWidth, tabList } = useModel("system");
    const { dropScope } = useAliveController()
    const closable = tabList.length > 1
    return (
        <div
            className={`${styles.tabItem} link-tab ${tabIndex === active ? styles.active : ''}`}
            title={value.title}
            onClick={() => {
                // translate了 多少个
                const tarnsNumber = Math.floor(tarnslateX / tabWidth)
                // 隐藏了多少
                const isBeyondDistance = tarnslateX - tarnsNumber * tabWidth;
                if (tabIndex - tarnsNumber <= 0) {
                    dispatch({ type: 'CHANGESTATE', payload: { active: tabIndex, tarnslateX: tarnslateX - isBeyondDistance } })
                    history.push({ ...value })
                    return;
                }
                // 是否在可视区域内
                if ((tabIndex - tarnsNumber + 1) === showTabs) {
                    // 需要移动的距离计算
                    const x = (tabIndex + 1) * (tabWidth as number) - (tabsWidth - 100)
                    dispatch({ type: 'CHANGESTATE', payload: { active: tabIndex, tarnslateX: x } })
                    history.push({ ...value })
                    return;
                }
                dispatch({ type: 'CHANGESTATE', payload: { active: tabIndex } })
                history.push({ ...value })

            }}>
            {value.title}
            {
                closable && (
                    <div
                        className={styles.closeIcon}
                        onClick={(e) => {
                            e.stopPropagation()
                            const currentName = value.keepAliveName
                            // 如果关闭激活中的 KeepAlive Tab,需要先离开当前路由
                            // 触发 KeepAlive unactivated 后再进行 drop
                            const localTablist = JSON.parse(JSON.stringify(tabList))
                            localTablist.splice(tabIndex, 1)
                            let activeIndex: number = 0;
                            if (tabIndex < active) {
                                // 我在前面
                                activeIndex = active - 1;
                                dropScope(currentName)
                            } else if (tabIndex === active) {
                                // 点击后面当前窗口
                                if (active > 0) {
                                    activeIndex = active - 1
                                    const timer = setTimeout(() => {
                                        clearTimeout(timer)
                                        history.push(tabList[activeIndex])
                                    }, 10)

                                } else {
                                    activeIndex = 0
                                    const timer = setTimeout(() => {
                                        clearTimeout(timer)
                                        history.push(localTablist[activeIndex])
                                    }, 10)
                                }
                                const unlisten = history.listen(() => {
                                    unlisten()
                                    const dropTimer = setTimeout(() => {
                                        clearTimeout(dropTimer)
                                        dropScope(currentName)
                                    }, 10)
                                })
                            } else {
                                activeIndex = active
                                dropScope(currentName)
                            }
                            dispatch({ type: "CHANGESTATE", payload: { tabList: localTablist, active: activeIndex, tarnslateX: 0 } })
                        }}>
                        <CloseOutlined />
                    </div>
                )
            }

        </div>
    );
}