diff options
Diffstat (limited to 'Timeline/ClientApp/src/app/home')
-rw-r--r-- | Timeline/ClientApp/src/app/home/BoardWithUser.tsx | 101 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/home/BoardWithoutUser.tsx | 60 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/home/Home.tsx | 102 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/home/OfflineBoard.tsx | 61 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/home/TimelineBoard.tsx | 73 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/home/TimelineCreateDialog.tsx | 53 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/home/home.sass | 13 |
7 files changed, 0 insertions, 463 deletions
diff --git a/Timeline/ClientApp/src/app/home/BoardWithUser.tsx b/Timeline/ClientApp/src/app/home/BoardWithUser.tsx deleted file mode 100644 index 22a4667c..00000000 --- a/Timeline/ClientApp/src/app/home/BoardWithUser.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import React from "react"; -import { Row, Col } from "reactstrap"; -import { useTranslation } from "react-i18next"; - -import { UserWithToken } from "../data/user"; -import { TimelineInfo } from "../data/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/home/BoardWithoutUser.tsx b/Timeline/ClientApp/src/app/home/BoardWithoutUser.tsx deleted file mode 100644 index 972c1b25..00000000 --- a/Timeline/ClientApp/src/app/home/BoardWithoutUser.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import React from "react"; -import { Row, Col } from "reactstrap"; - -import { TimelineInfo } from "../data/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/home/Home.tsx b/Timeline/ClientApp/src/app/home/Home.tsx deleted file mode 100644 index 910c9a01..00000000 --- a/Timeline/ClientApp/src/app/home/Home.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import React from "react"; -import { useHistory } from "react-router"; -import { Row, Container, Button, Col } from "reactstrap"; -import { useTranslation } from "react-i18next"; - -import { useUser } from "../data/user"; -import AppBar from "../common/AppBar"; -import SearchInput from "../common/SearchInput"; - -import BoardWithoutUser from "./BoardWithoutUser"; -import BoardWithUser from "./BoardWithUser"; -import TimelineCreateDialog from "./TimelineCreateDialog"; - -const Home: 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 ( - <> - <AppBar /> - <Container fluid style={{ marginTop: "56px" }}> - <Row> - <Col> - <SearchInput - className="justify-content-center" - value={navText} - onChange={setNavText} - onButtonClick={goto} - buttonText={t("home.go")} - placeholder="@crupest" - additionalButton={ - user != null && ( - <Button - color="success" - outline - 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 Home; diff --git a/Timeline/ClientApp/src/app/home/OfflineBoard.tsx b/Timeline/ClientApp/src/app/home/OfflineBoard.tsx deleted file mode 100644 index fbd37efd..00000000 --- a/Timeline/ClientApp/src/app/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 "../data/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/home/TimelineBoard.tsx b/Timeline/ClientApp/src/app/home/TimelineBoard.tsx deleted file mode 100644 index 21dcac3f..00000000 --- a/Timeline/ClientApp/src/app/home/TimelineBoard.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React from "react"; -import clsx from "clsx"; -import { Link } from "react-router-dom"; -import { Spinner } from "reactstrap"; -import { Trans } from "react-i18next"; - -import { TimelineInfo } from "../data/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 color="primary" /> - </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/home/TimelineCreateDialog.tsx b/Timeline/ClientApp/src/app/home/TimelineCreateDialog.tsx deleted file mode 100644 index 911dd60c..00000000 --- a/Timeline/ClientApp/src/app/home/TimelineCreateDialog.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import React from "react"; -import { useHistory } from "react-router"; - -import { validateTimelineName, timelineService } from "../data/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/home/home.sass b/Timeline/ClientApp/src/app/home/home.sass deleted file mode 100644 index f5d6ffc3..00000000 --- a/Timeline/ClientApp/src/app/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 |