diff options
author | crupest <crupest@outlook.com> | 2020-10-31 00:42:06 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-31 00:42:06 +0800 |
commit | a3c97f6fb6313da2e8c0fac0b4c08f2ef4265d0f (patch) | |
tree | ee006874b0c93e9bfc76f141a092a8b9585a1f95 /Timeline/ClientApp/src/app/views/home | |
parent | 0c4caaebe2480e77918d5d7df234f0edaeab74ba (diff) | |
parent | 7ce0846d9ec968da3ea4f7ebcc6db26db8e49089 (diff) | |
download | timeline-a3c97f6fb6313da2e8c0fac0b4c08f2ef4265d0f.tar.gz timeline-a3c97f6fb6313da2e8c0fac0b4c08f2ef4265d0f.tar.bz2 timeline-a3c97f6fb6313da2e8c0fac0b4c08f2ef4265d0f.zip |
Merge pull request #161 from crupest/upgrade
Upgrade packages and split front end and back end.
Diffstat (limited to 'Timeline/ClientApp/src/app/views/home')
7 files changed, 0 insertions, 460 deletions
diff --git a/Timeline/ClientApp/src/app/views/home/BoardWithUser.tsx b/Timeline/ClientApp/src/app/views/home/BoardWithUser.tsx deleted file mode 100644 index dcd39cbe..00000000 --- a/Timeline/ClientApp/src/app/views/home/BoardWithUser.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import React from "react"; -import { Row, Col } from "react-bootstrap"; -import { useTranslation } from "react-i18next"; - -import { UserWithToken } from "@/services/user"; -import { TimelineInfo } from "@/services/timeline"; -import { getHttpTimelineClient } from "@/http/timeline"; - -import TimelineBoard from "./TimelineBoard"; -import OfflineBoard from "./OfflineBoard"; - -const BoardWithUser: React.FC<{ user: UserWithToken }> = ({ user }) => { - const { t } = useTranslation(); - - const [ownTimelines, setOwnTimelines] = React.useState< - TimelineInfo[] | "offline" | "loading" - >("loading"); - const [joinTimelines, setJoinTimelines] = React.useState< - TimelineInfo[] | "offline" | "loading" - >("loading"); - - React.useEffect(() => { - let subscribe = true; - if (ownTimelines === "loading") { - void getHttpTimelineClient() - .listTimeline({ relate: user.username, relateType: "own" }) - .then( - (timelines) => { - if (subscribe) { - setOwnTimelines(timelines); - } - }, - () => { - setOwnTimelines("offline"); - } - ); - } - return () => { - subscribe = false; - }; - }, [user, ownTimelines]); - - React.useEffect(() => { - let subscribe = true; - if (joinTimelines === "loading") { - void getHttpTimelineClient() - .listTimeline({ relate: user.username, relateType: "join" }) - .then( - (timelines) => { - if (subscribe) { - setJoinTimelines(timelines); - } - }, - () => { - setJoinTimelines("offline"); - } - ); - } - return () => { - subscribe = false; - }; - }, [user, joinTimelines]); - - return ( - <Row className="my-2 justify-content-center"> - {ownTimelines === "offline" && joinTimelines === "offline" ? ( - <Col className="py-2" sm="8" lg="6"> - <OfflineBoard - onReload={() => { - setOwnTimelines("loading"); - setJoinTimelines("loading"); - }} - /> - </Col> - ) : ( - <> - <Col sm="6" lg="5" className="py-2"> - <TimelineBoard - title={t("home.ownTimeline")} - timelines={ownTimelines} - onReload={() => { - setOwnTimelines("loading"); - }} - /> - </Col> - <Col sm="6" lg="5" className="py-2"> - <TimelineBoard - title={t("home.joinTimeline")} - timelines={joinTimelines} - onReload={() => { - setJoinTimelines("loading"); - }} - /> - </Col> - </> - )} - </Row> - ); -}; - -export default BoardWithUser; diff --git a/Timeline/ClientApp/src/app/views/home/BoardWithoutUser.tsx b/Timeline/ClientApp/src/app/views/home/BoardWithoutUser.tsx deleted file mode 100644 index ebfddb50..00000000 --- a/Timeline/ClientApp/src/app/views/home/BoardWithoutUser.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import React from "react"; -import { Row, Col } from "react-bootstrap"; - -import { TimelineInfo } from "@/services/timeline"; -import { getHttpTimelineClient } from "@/http/timeline"; - -import TimelineBoard from "./TimelineBoard"; -import OfflineBoard from "./OfflineBoard"; - -const BoardWithoutUser: React.FC = () => { - const [publicTimelines, setPublicTimelines] = React.useState< - TimelineInfo[] | "offline" | "loading" - >("loading"); - - React.useEffect(() => { - let subscribe = true; - if (publicTimelines === "loading") { - void getHttpTimelineClient() - .listTimeline({ visibility: "Public" }) - .then( - (timelines) => { - if (subscribe) { - setPublicTimelines(timelines); - } - }, - () => { - setPublicTimelines("offline"); - } - ); - } - return () => { - subscribe = false; - }; - }, [publicTimelines]); - - return ( - <Row className="my-2 justify-content-center"> - {publicTimelines === "offline" ? ( - <Col sm="8" lg="6"> - <OfflineBoard - onReload={() => { - setPublicTimelines("loading"); - }} - /> - </Col> - ) : ( - <Col sm="8" lg="6"> - <TimelineBoard - timelines={publicTimelines} - onReload={() => { - setPublicTimelines("loading"); - }} - /> - </Col> - )} - </Row> - ); -}; - -export default BoardWithoutUser; diff --git a/Timeline/ClientApp/src/app/views/home/OfflineBoard.tsx b/Timeline/ClientApp/src/app/views/home/OfflineBoard.tsx deleted file mode 100644 index fc05bd74..00000000 --- a/Timeline/ClientApp/src/app/views/home/OfflineBoard.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import React from "react"; -import { Link } from "react-router-dom"; -import { Trans } from "react-i18next"; - -import { getAllCachedTimelineNames } from "@/services/timeline"; -import UserTimelineLogo from "../common/UserTimelineLogo"; -import TimelineLogo from "../common/TimelineLogo"; - -export interface OfflineBoardProps { - onReload: () => void; -} - -const OfflineBoard: React.FC<OfflineBoardProps> = ({ onReload }) => { - const [timelines, setTimelines] = React.useState<string[]>([]); - - React.useEffect(() => { - let subscribe = true; - void getAllCachedTimelineNames().then((t) => { - if (subscribe) setTimelines(t); - }); - return () => { - subscribe = false; - }; - }); - - return ( - <> - <Trans i18nKey="home.offlinePrompt"> - 0 - <a - href="#" - onClick={(e) => { - onReload(); - e.preventDefault(); - }} - > - 1 - </a> - 2 - </Trans> - {timelines.map((timeline) => { - const isPersonal = timeline.startsWith("@"); - const url = isPersonal - ? `/users/${timeline.slice(1)}` - : `/timelines/${timeline}`; - return ( - <div key={timeline} className="timeline-board-item"> - {isPersonal ? ( - <UserTimelineLogo className="icon" /> - ) : ( - <TimelineLogo className="icon" /> - )} - <Link to={url}>{timeline}</Link> - </div> - ); - })} - </> - ); -}; - -export default OfflineBoard; diff --git a/Timeline/ClientApp/src/app/views/home/TimelineBoard.tsx b/Timeline/ClientApp/src/app/views/home/TimelineBoard.tsx deleted file mode 100644 index a3d176e1..00000000 --- a/Timeline/ClientApp/src/app/views/home/TimelineBoard.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React from "react"; -import clsx from "clsx"; -import { Link } from "react-router-dom"; -import { Trans } from "react-i18next"; -import { Spinner } from "react-bootstrap"; - -import { TimelineInfo } from "@/services/timeline"; -import TimelineLogo from "../common/TimelineLogo"; -import UserTimelineLogo from "../common/UserTimelineLogo"; - -export interface TimelineBoardProps { - title?: string; - timelines: TimelineInfo[] | "offline" | "loading"; - onReload: () => void; - className?: string; -} - -const TimelineBoard: React.FC<TimelineBoardProps> = (props) => { - const { title, timelines, className } = props; - - return ( - <div className={clsx("timeline-board", className)}> - {title != null && <h3 className="text-center">{title}</h3>} - {(() => { - if (timelines === "loading") { - return ( - <div className="d-flex flex-grow-1 justify-content-center align-items-center"> - <Spinner variant="primary" animation="border" /> - </div> - ); - } else if (timelines === "offline") { - return ( - <div className="d-flex flex-grow-1 justify-content-center align-items-center"> - <Trans i18nKey="loadFailReload" parent="div"> - 0 - <a - href="#" - onClick={(e) => { - props.onReload(); - e.preventDefault(); - }} - > - 1 - </a> - 2 - </Trans> - </div> - ); - } else { - return timelines.map((timeline) => { - const { name } = timeline; - const isPersonal = name.startsWith("@"); - const url = isPersonal - ? `/users/${timeline.owner.username}` - : `/timelines/${name}`; - return ( - <div key={name} className="timeline-board-item"> - {isPersonal ? ( - <UserTimelineLogo className="icon" /> - ) : ( - <TimelineLogo className="icon" /> - )} - <Link to={url}>{name}</Link> - </div> - ); - }); - } - })()} - </div> - ); -}; - -export default TimelineBoard; diff --git a/Timeline/ClientApp/src/app/views/home/TimelineCreateDialog.tsx b/Timeline/ClientApp/src/app/views/home/TimelineCreateDialog.tsx deleted file mode 100644 index d9467719..00000000 --- a/Timeline/ClientApp/src/app/views/home/TimelineCreateDialog.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import React from "react"; -import { useHistory } from "react-router"; - -import { validateTimelineName, timelineService } from "@/services/timeline"; -import OperationDialog from "../common/OperationDialog"; - -interface TimelineCreateDialogProps { - open: boolean; - close: () => void; -} - -const TimelineCreateDialog: React.FC<TimelineCreateDialogProps> = (props) => { - const history = useHistory(); - - let nameSaved: string; - - return ( - <OperationDialog - open={props.open} - close={props.close} - titleColor="success" - title="home.createDialog.title" - inputScheme={[ - { - type: "text", - label: "home.createDialog.name", - helperText: "home.createDialog.nameFormat", - validator: (name) => { - if (name.length === 0) { - return "home.createDialog.noEmpty"; - } else if (name.length > 26) { - return "home.createDialog.tooLong"; - } else if (!validateTimelineName(name)) { - return "home.createDialog.badFormat"; - } else { - return null; - } - }, - }, - ]} - onProcess={([name]) => { - nameSaved = name as string; - return timelineService.createTimeline(nameSaved).toPromise(); - }} - onSuccessAndClose={() => { - history.push(`timelines/${nameSaved}`); - }} - failurePrompt={(e) => `${e as string}`} - /> - ); -}; - -export default TimelineCreateDialog; diff --git a/Timeline/ClientApp/src/app/views/home/home.sass b/Timeline/ClientApp/src/app/views/home/home.sass deleted file mode 100644 index f5d6ffc3..00000000 --- a/Timeline/ClientApp/src/app/views/home/home.sass +++ /dev/null @@ -1,13 +0,0 @@ -.timeline-board-item - font-size: 1.1em - @extend .my-2 - .icon - height: 1.3em - @extend .mr-2 - -.timeline-board - @extend .cru-card - @extend .d-flex - @extend .flex-column - @extend .p-3 - min-height: 200px diff --git a/Timeline/ClientApp/src/app/views/home/index.tsx b/Timeline/ClientApp/src/app/views/home/index.tsx deleted file mode 100644 index 760adcea..00000000 --- a/Timeline/ClientApp/src/app/views/home/index.tsx +++ /dev/null @@ -1,99 +0,0 @@ -import React from "react"; -import { useHistory } from "react-router"; -import { useTranslation } from "react-i18next"; -import { Row, Container, Button, Col } from "react-bootstrap"; - -import { useUser } from "@/services/user"; -import SearchInput from "../common/SearchInput"; - -import BoardWithoutUser from "./BoardWithoutUser"; -import BoardWithUser from "./BoardWithUser"; -import TimelineCreateDialog from "./TimelineCreateDialog"; - -const HomePage: React.FC = () => { - const history = useHistory(); - - const { t } = useTranslation(); - - const user = useUser(); - - const [navText, setNavText] = React.useState<string>(""); - - const [dialog, setDialog] = React.useState<"create" | null>(null); - - const goto = React.useCallback((): void => { - if (navText === "") { - history.push("users/crupest"); - } else if (navText.startsWith("@")) { - history.push(`users/${navText.slice(1)}`); - } else { - history.push(`timelines/${navText}`); - } - }, [navText, history]); - - return ( - <> - <Container fluid> - <Row className="justify-content-center"> - <Col xs={12} sm={10} md={8} lg={6}> - <SearchInput - className="justify-content-center" - value={navText} - onChange={setNavText} - onButtonClick={goto} - buttonText={t("home.go")} - placeholder="@crupest" - additionalButton={ - user != null && ( - <Button - variant="outline-success" - onClick={() => { - setDialog("create"); - }} - > - {t("home.createButton")} - </Button> - ) - } - /> - </Col> - </Row> - {(() => { - if (user == null) { - return <BoardWithoutUser />; - } else { - return <BoardWithUser user={user} />; - } - })()} - </Container> - <footer className="text-right"> - <a - className="mx-3 text-muted" - href="http://beian.miit.gov.cn/" - target="_blank" - rel="noopener noreferrer" - > - <small>鄂ICP备18030913号-1</small> - </a> - <a - className="mx-3 text-muted" - href="http://www.beian.gov.cn/" - target="_blank" - rel="noopener noreferrer" - > - <small className="white-space-no-wrap">公安备案 42112102000124</small> - </a> - </footer> - {dialog === "create" && ( - <TimelineCreateDialog - open - close={() => { - setDialog(null); - }} - /> - )} - </> - ); -}; - -export default HomePage; |