aboutsummaryrefslogtreecommitdiff
path: root/Timeline/ClientApp/src/app/views/home
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2020-10-27 19:21:35 +0800
committercrupest <crupest@outlook.com>2020-10-27 19:21:35 +0800
commitac769e656b122ff569c3f1534701b71e00fed586 (patch)
tree72966645ff1e25139d3995262e1c4349f2c14733 /Timeline/ClientApp/src/app/views/home
parent14e5848c23c643cea9b5d709770747d98c3d75e2 (diff)
downloadtimeline-ac769e656b122ff569c3f1534701b71e00fed586.tar.gz
timeline-ac769e656b122ff569c3f1534701b71e00fed586.tar.bz2
timeline-ac769e656b122ff569c3f1534701b71e00fed586.zip
Split front and back end.
Diffstat (limited to 'Timeline/ClientApp/src/app/views/home')
-rw-r--r--Timeline/ClientApp/src/app/views/home/BoardWithUser.tsx101
-rw-r--r--Timeline/ClientApp/src/app/views/home/BoardWithoutUser.tsx60
-rw-r--r--Timeline/ClientApp/src/app/views/home/OfflineBoard.tsx61
-rw-r--r--Timeline/ClientApp/src/app/views/home/TimelineBoard.tsx73
-rw-r--r--Timeline/ClientApp/src/app/views/home/TimelineCreateDialog.tsx53
-rw-r--r--Timeline/ClientApp/src/app/views/home/home.sass13
-rw-r--r--Timeline/ClientApp/src/app/views/home/index.tsx99
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;