mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-24 20:36:40 +07:00
(nextjs) fixed flow loading, anchors and styles
This commit is contained in:
parent
2e0ad878a3
commit
c5bac54494
11 changed files with 90 additions and 70 deletions
|
@ -2,4 +2,12 @@ const withTM = require('next-transpile-modules')(['ramda']);
|
||||||
|
|
||||||
module.exports = withTM({
|
module.exports = withTM({
|
||||||
/* Your Next.js config */
|
/* Your Next.js config */
|
||||||
|
async rewrites() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
source: '/post:id',
|
||||||
|
destination: '/node/:id',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,7 +8,9 @@ interface AnchorProps extends LinkProps {}
|
||||||
|
|
||||||
const Anchor: VFC<AnchorProps> = ({ ref, href, ...rest }) =>
|
const Anchor: VFC<AnchorProps> = ({ ref, href, ...rest }) =>
|
||||||
CONFIG.isNextEnvironment ? (
|
CONFIG.isNextEnvironment ? (
|
||||||
<NextLink {...rest} href={href ?? ''} />
|
<NextLink href={href ?? ''} passHref>
|
||||||
|
<a {...rest} />
|
||||||
|
</NextLink>
|
||||||
) : (
|
) : (
|
||||||
<Link {...rest} to={href ?? ''} />
|
<Link {...rest} to={href ?? ''} />
|
||||||
);
|
);
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { useFlowCellControls } from '~/hooks/flow/useFlowCellControls';
|
||||||
import { useClickOutsideFocus } from '~/hooks/dom/useClickOutsideFocus';
|
import { useClickOutsideFocus } from '~/hooks/dom/useClickOutsideFocus';
|
||||||
import { MenuDots } from '~/components/common/MenuDots';
|
import { MenuDots } from '~/components/common/MenuDots';
|
||||||
import { FlowCellImage } from '~/components/flow/FlowCellImage';
|
import { FlowCellImage } from '~/components/flow/FlowCellImage';
|
||||||
|
import { Anchor } from '~/components/common/Anchor';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
id: INode['id'];
|
id: INode['id'];
|
||||||
|
@ -71,7 +72,7 @@ const FlowCell: FC<Props> = ({
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<NavLink className={styles.link} to={to}>
|
<Anchor className={styles.link} href={to}>
|
||||||
{withText && (
|
{withText && (
|
||||||
<FlowCellText className={styles.text} heading={<h4 className={styles.title}>{title}</h4>}>
|
<FlowCellText className={styles.text} heading={<h4 className={styles.title}>{title}</h4>}>
|
||||||
{text!}
|
{text!}
|
||||||
|
@ -94,7 +95,7 @@ const FlowCell: FC<Props> = ({
|
||||||
<h4 className={styles.title}>{title}</h4>
|
<h4 className={styles.title}>{title}</h4>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</NavLink>
|
</Anchor>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,13 +3,13 @@ import styles from './styles.module.scss';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { INode } from '~/types';
|
import { INode } from '~/types';
|
||||||
import { PRESETS, URLS } from '~/constants/urls';
|
import { PRESETS, URLS } from '~/constants/urls';
|
||||||
import { RouteComponentProps, withRouter } from 'react-router';
|
import { RouteComponentProps } from 'react-router';
|
||||||
import { getURL, getURLFromString } from '~/utils/dom';
|
import { getURL, getURLFromString } from '~/utils/dom';
|
||||||
import { useColorGradientFromString } from '~/hooks/color/useColorGradientFromString';
|
import { useColorGradientFromString } from '~/hooks/color/useColorGradientFromString';
|
||||||
import { Square } from '~/components/common/Square';
|
import { Square } from '~/components/common/Square';
|
||||||
import { useNavigation } from '~/hooks/navigation/useNavigation';
|
import { useGotoNode } from '~/hooks/node/useGotoNode';
|
||||||
|
|
||||||
type IProps = RouteComponentProps & {
|
type IProps = {
|
||||||
item: Partial<INode>;
|
item: Partial<INode>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,12 +29,11 @@ const getTitleLetters = (title?: string): string => {
|
||||||
: words[0].substr(0, 2).toUpperCase();
|
: words[0].substr(0, 2).toUpperCase();
|
||||||
};
|
};
|
||||||
|
|
||||||
const NodeRelatedItemUnconnected: FC<IProps> = memo(({ item }) => {
|
const NodeRelatedItem: FC<IProps> = memo(({ item }) => {
|
||||||
const { push } = useNavigation();
|
const onClick = useGotoNode(item.id);
|
||||||
const [is_loaded, setIsLoaded] = useState(false);
|
const [is_loaded, setIsLoaded] = useState(false);
|
||||||
const [width, setWidth] = useState(0);
|
const [width, setWidth] = useState(0);
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
const onClick = useCallback(() => push(URLS.NODE_URL(item.id)), [item, push]);
|
|
||||||
|
|
||||||
const thumb = useMemo(
|
const thumb = useMemo(
|
||||||
() => (item.thumbnail ? getURL({ url: item.thumbnail }, PRESETS.avatar) : ''),
|
() => (item.thumbnail ? getURL({ url: item.thumbnail }, PRESETS.avatar) : ''),
|
||||||
|
@ -95,6 +94,4 @@ const NodeRelatedItemUnconnected: FC<IProps> = memo(({ item }) => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const NodeRelatedItem = withRouter(NodeRelatedItemUnconnected);
|
|
||||||
|
|
||||||
export { NodeRelatedItem };
|
export { NodeRelatedItem };
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { useCallback, useState } from 'react';
|
||||||
import { getNodeDiff } from '~/api/node';
|
import { getNodeDiff } from '~/api/node';
|
||||||
import { uniq } from 'ramda';
|
import { uniq } from 'ramda';
|
||||||
import { useFlowStore } from '~/store/flow/useFlowStore';
|
import { useFlowStore } from '~/store/flow/useFlowStore';
|
||||||
import { runInAction } from 'mobx';
|
import { runInAction, toJS } from 'mobx';
|
||||||
import { showErrorToast } from '~/utils/errors/showToast';
|
import { showErrorToast } from '~/utils/errors/showToast';
|
||||||
|
|
||||||
export const useFlowLoader = () => {
|
export const useFlowLoader = () => {
|
||||||
|
@ -81,5 +81,7 @@ export const useFlowLoader = () => {
|
||||||
}
|
}
|
||||||
}, [flow]);
|
}, [flow]);
|
||||||
|
|
||||||
|
console.log(toJS(flow.nodes));
|
||||||
|
|
||||||
return { getInitialNodes, isSyncing, loadMore };
|
return { getInitialNodes, isSyncing, loadMore };
|
||||||
};
|
};
|
||||||
|
|
9
src/hooks/node/useNodePageParams.ts
Normal file
9
src/hooks/node/useNodePageParams.ts
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import { useRouteMatch } from 'react-router';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
|
import { CONFIG } from '~/utils/config';
|
||||||
|
|
||||||
|
export const useNodePageParams = () => {
|
||||||
|
return CONFIG.isNextEnvironment
|
||||||
|
? (useRouter().query.id as string)
|
||||||
|
: useRouteMatch<{ id: string }>().params.id;
|
||||||
|
};
|
|
@ -20,8 +20,6 @@ import { useGlobalLoader } from '~/hooks/dom/useGlobalLoader';
|
||||||
const mobxStore = getMOBXStore();
|
const mobxStore = getMOBXStore();
|
||||||
|
|
||||||
export default function MyApp({ Component, pageProps }) {
|
export default function MyApp({ Component, pageProps }) {
|
||||||
useGlobalLoader();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StoreContextProvider store={mobxStore}>
|
<StoreContextProvider store={mobxStore}>
|
||||||
<SWRConfigProvider>
|
<SWRConfigProvider>
|
||||||
|
|
|
@ -3,10 +3,13 @@ import { FlowLayout } from '~/layouts/FlowLayout';
|
||||||
import { useFlow } from '~/hooks/flow/useFlow';
|
import { useFlow } from '~/hooks/flow/useFlow';
|
||||||
import { FlowContextProvider } from '~/utils/context/FlowContextProvider';
|
import { FlowContextProvider } from '~/utils/context/FlowContextProvider';
|
||||||
import { observer } from 'mobx-react-lite';
|
import { observer } from 'mobx-react-lite';
|
||||||
|
import { useGlobalLoader } from '~/hooks/dom/useGlobalLoader';
|
||||||
|
|
||||||
interface Props {}
|
interface Props {}
|
||||||
|
|
||||||
const FlowPage: FC<Props> = observer(() => {
|
const FlowPage: FC<Props> = observer(() => {
|
||||||
|
useGlobalLoader();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
updates,
|
updates,
|
||||||
nodes,
|
nodes,
|
||||||
|
|
|
@ -12,67 +12,63 @@ import { useNodePermissions } from '~/hooks/node/useNodePermissions';
|
||||||
import { NodeRelatedProvider } from '~/utils/providers/NodeRelatedProvider';
|
import { NodeRelatedProvider } from '~/utils/providers/NodeRelatedProvider';
|
||||||
import { useLoadNode } from '~/hooks/node/useLoadNode';
|
import { useLoadNode } from '~/hooks/node/useLoadNode';
|
||||||
import { observer } from 'mobx-react-lite';
|
import { observer } from 'mobx-react-lite';
|
||||||
|
import { useNodePageParams } from '~/hooks/node/useNodePageParams';
|
||||||
|
|
||||||
type Props = RouteComponentProps<{ id: string }> & {};
|
type Props = RouteComponentProps<{ id: string }> & {};
|
||||||
|
|
||||||
const NodePage: FC<Props> = observer(
|
const NodePage: FC<Props> = observer(() => {
|
||||||
({
|
const id = useNodePageParams();
|
||||||
match: {
|
const { node, isLoading, update, lastSeen } = useLoadNode(parseInt(id, 10));
|
||||||
params: { id },
|
|
||||||
},
|
|
||||||
}) => {
|
|
||||||
const { node, isLoading, update, lastSeen } = useLoadNode(parseInt(id, 10));
|
|
||||||
|
|
||||||
const onShowImageModal = useImageModal();
|
const onShowImageModal = useImageModal();
|
||||||
const {
|
const {
|
||||||
onLoadMoreComments,
|
onLoadMoreComments,
|
||||||
onDelete: onDeleteComment,
|
onDelete: onDeleteComment,
|
||||||
onEdit: onSaveComment,
|
onEdit: onSaveComment,
|
||||||
comments,
|
comments,
|
||||||
hasMore,
|
hasMore,
|
||||||
isLoading: isLoadingComments,
|
isLoading: isLoadingComments,
|
||||||
} = useNodeComments(parseInt(id, 10));
|
} = useNodeComments(parseInt(id, 10));
|
||||||
const { onDelete: onTagDelete, onChange: onTagsChange, onClick: onTagClick } = useNodeTags(
|
const { onDelete: onTagDelete, onChange: onTagsChange, onClick: onTagClick } = useNodeTags(
|
||||||
parseInt(id, 10)
|
parseInt(id, 10)
|
||||||
);
|
);
|
||||||
const [canEdit] = useNodePermissions(node);
|
const [canEdit] = useNodePermissions(node);
|
||||||
|
|
||||||
useScrollToTop([id, isLoadingComments]);
|
useScrollToTop([id, isLoadingComments]);
|
||||||
|
|
||||||
if (!node) {
|
if (!node) {
|
||||||
// TODO: do something here
|
// TODO: do something here
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<NodeContextProvider node={node} isLoading={isLoading} update={update}>
|
|
||||||
<NodeRelatedProvider id={parseInt(id, 10)} tags={node.tags}>
|
|
||||||
<CommentContextProvider
|
|
||||||
onSaveComment={onSaveComment}
|
|
||||||
comments={comments}
|
|
||||||
hasMore={hasMore}
|
|
||||||
lastSeenCurrent={lastSeen}
|
|
||||||
isLoading={isLoadingComments}
|
|
||||||
onShowImageModal={onShowImageModal}
|
|
||||||
onLoadMoreComments={onLoadMoreComments}
|
|
||||||
onDeleteComment={onDeleteComment}
|
|
||||||
>
|
|
||||||
<TagsContextProvider
|
|
||||||
tags={node.tags}
|
|
||||||
canAppend={canEdit}
|
|
||||||
canDelete={canEdit}
|
|
||||||
isLoading={isLoading}
|
|
||||||
onChange={onTagsChange}
|
|
||||||
onTagClick={onTagClick}
|
|
||||||
onTagDelete={onTagDelete}
|
|
||||||
>
|
|
||||||
<NodeLayout />
|
|
||||||
</TagsContextProvider>
|
|
||||||
</CommentContextProvider>
|
|
||||||
</NodeRelatedProvider>
|
|
||||||
</NodeContextProvider>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
return (
|
||||||
|
<NodeContextProvider node={node} isLoading={isLoading} update={update}>
|
||||||
|
<NodeRelatedProvider id={parseInt(id, 10)} tags={node.tags}>
|
||||||
|
<CommentContextProvider
|
||||||
|
onSaveComment={onSaveComment}
|
||||||
|
comments={comments}
|
||||||
|
hasMore={hasMore}
|
||||||
|
lastSeenCurrent={lastSeen}
|
||||||
|
isLoading={isLoadingComments}
|
||||||
|
onShowImageModal={onShowImageModal}
|
||||||
|
onLoadMoreComments={onLoadMoreComments}
|
||||||
|
onDeleteComment={onDeleteComment}
|
||||||
|
>
|
||||||
|
<TagsContextProvider
|
||||||
|
tags={node.tags}
|
||||||
|
canAppend={canEdit}
|
||||||
|
canDelete={canEdit}
|
||||||
|
isLoading={isLoading}
|
||||||
|
onChange={onTagsChange}
|
||||||
|
onTagClick={onTagClick}
|
||||||
|
onTagDelete={onTagDelete}
|
||||||
|
>
|
||||||
|
<NodeLayout />
|
||||||
|
</TagsContextProvider>
|
||||||
|
</CommentContextProvider>
|
||||||
|
</NodeRelatedProvider>
|
||||||
|
</NodeContextProvider>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
export default NodePage;
|
export default NodePage;
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { FlowStore } from '~/store/flow/FlowStore';
|
||||||
import { ModalStore } from '~/store/modal/ModalStore';
|
import { ModalStore } from '~/store/modal/ModalStore';
|
||||||
import { LabStore } from '~/store/lab/LabStore';
|
import { LabStore } from '~/store/lab/LabStore';
|
||||||
import { AuthStore } from '~/store/auth/AuthStore';
|
import { AuthStore } from '~/store/auth/AuthStore';
|
||||||
|
import { useStaticRendering } from 'mobx-react-lite';
|
||||||
|
|
||||||
export class Store {
|
export class Store {
|
||||||
flow = new FlowStore();
|
flow = new FlowStore();
|
||||||
|
@ -22,3 +23,6 @@ export class Store {
|
||||||
const defaultStore = new Store();
|
const defaultStore = new Store();
|
||||||
|
|
||||||
export const getMOBXStore = () => defaultStore;
|
export const getMOBXStore = () => defaultStore;
|
||||||
|
|
||||||
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||||
|
useStaticRendering(typeof window === 'undefined');
|
||||||
|
|
|
@ -3,5 +3,5 @@ export const CONFIG = {
|
||||||
remoteCurrent:
|
remoteCurrent:
|
||||||
process.env.REACT_APP_REMOTE_CURRENT || process.env.NEXT_PUBLIC_REMOTE_CURRENT || '',
|
process.env.REACT_APP_REMOTE_CURRENT || process.env.NEXT_PUBLIC_REMOTE_CURRENT || '',
|
||||||
// transitional prop, marks migration to nextjs
|
// transitional prop, marks migration to nextjs
|
||||||
isNextEnvironment: false,
|
isNextEnvironment: !!process.env.NEXT_PUBLIC_REMOTE_CURRENT || typeof window === 'undefined',
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue