aboutsummaryrefslogtreecommitdiff
path: root/FrontEnd/src
diff options
context:
space:
mode:
Diffstat (limited to 'FrontEnd/src')
-rw-r--r--FrontEnd/src/app/views/timeline-common/TimelineMember.tsx22
-rw-r--r--FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx14
-rw-r--r--FrontEnd/src/app/views/timeline-common/TimelinePageTemplateUI.tsx1
-rw-r--r--FrontEnd/src/app/views/timeline-common/TimelinePropertyChangeDialog.tsx9
-rw-r--r--FrontEnd/src/app/views/timeline/TimelineDeleteDialog.tsx4
-rw-r--r--FrontEnd/src/app/views/timeline/TimelineInfoCard.tsx10
-rw-r--r--FrontEnd/src/app/views/timeline/index.tsx5
-rw-r--r--FrontEnd/src/app/views/user/UserInfoCard.tsx10
-rw-r--r--FrontEnd/src/app/views/user/index.tsx19
9 files changed, 52 insertions, 42 deletions
diff --git a/FrontEnd/src/app/views/timeline-common/TimelineMember.tsx b/FrontEnd/src/app/views/timeline-common/TimelineMember.tsx
index dd8c7389..51512f15 100644
--- a/FrontEnd/src/app/views/timeline-common/TimelineMember.tsx
+++ b/FrontEnd/src/app/views/timeline-common/TimelineMember.tsx
@@ -46,9 +46,10 @@ const TimelineMemberItem: React.FC<{
);
};
-const TimelineMemberUserSearch: React.FC<{ timeline: HttpTimelineInfo }> = ({
- timeline,
-}) => {
+const TimelineMemberUserSearch: React.FC<{
+ timeline: HttpTimelineInfo;
+ onChange: () => void;
+}> = ({ timeline, onChange }) => {
const { t } = useTranslation();
const [userSearchText, setUserSearchText] = useState<string>("");
@@ -120,6 +121,7 @@ const TimelineMemberUserSearch: React.FC<{ timeline: HttpTimelineInfo }> = ({
.then(() => {
setUserSearchText("");
setUserSearchState({ type: "init" });
+ onChange();
});
}}
/>
@@ -139,14 +141,13 @@ const TimelineMemberUserSearch: React.FC<{ timeline: HttpTimelineInfo }> = ({
);
};
-// TODO: Trigger resync.
-
export interface TimelineMemberProps {
timeline: HttpTimelineInfo;
+ onChange: () => void;
}
const TimelineMember: React.FC<TimelineMemberProps> = (props) => {
- const { timeline } = props;
+ const { timeline, onChange } = props;
const members = [timeline.owner, ...timeline.members];
return (
@@ -159,10 +160,9 @@ const TimelineMember: React.FC<TimelineMemberProps> = (props) => {
onAction={
timeline.manageable && index !== 0
? () => {
- void getHttpTimelineClient().memberDelete(
- timeline.name,
- member.username
- );
+ void getHttpTimelineClient()
+ .memberDelete(timeline.name, member.username)
+ .then(onChange);
}
: undefined
}
@@ -170,7 +170,7 @@ const TimelineMember: React.FC<TimelineMemberProps> = (props) => {
))}
</ListGroup>
{timeline.manageable ? (
- <TimelineMemberUserSearch timeline={timeline} />
+ <TimelineMemberUserSearch timeline={timeline} onChange={onChange} />
) : null}
</Container>
);
diff --git a/FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx b/FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx
index caab1768..6a8dd63c 100644
--- a/FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx
+++ b/FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx
@@ -16,12 +16,14 @@ export interface TimelinePageTemplateProps<TManageItem> {
Omit<TimelinePageTemplateUIProps<TManageItem>, "CardComponent">
>;
notFoundI18nKey: string;
+ reloadKey: number;
+ onReload: () => void;
}
export default function TimelinePageTemplate<TManageItem>(
props: TimelinePageTemplateProps<TManageItem>
): React.ReactElement | null {
- const { name } = props;
+ const { name, reloadKey, onReload } = props;
const [dialog, setDialog] = React.useState<null | "property" | "member">(
null
@@ -68,7 +70,7 @@ export default function TimelinePageTemplate<TManageItem>(
return () => {
subscribe = false;
};
- }, [name]);
+ }, [name, reloadKey]);
let dialogElement: React.ReactElement | undefined;
const closeDialog = (): void => setDialog(null);
@@ -85,6 +87,7 @@ export default function TimelinePageTemplate<TManageItem>(
open
close={closeDialog}
timeline={timeline}
+ onChange={onReload}
/>
);
} else if (dialog === "member") {
@@ -95,7 +98,12 @@ export default function TimelinePageTemplate<TManageItem>(
}
dialogElement = (
- <TimelineMemberDialog open onClose={closeDialog} timeline={timeline} />
+ <TimelineMemberDialog
+ open
+ onClose={closeDialog}
+ timeline={timeline}
+ onChange={onReload}
+ />
);
}
diff --git a/FrontEnd/src/app/views/timeline-common/TimelinePageTemplateUI.tsx b/FrontEnd/src/app/views/timeline-common/TimelinePageTemplateUI.tsx
index 48263486..56be8cfe 100644
--- a/FrontEnd/src/app/views/timeline-common/TimelinePageTemplateUI.tsx
+++ b/FrontEnd/src/app/views/timeline-common/TimelinePageTemplateUI.tsx
@@ -134,7 +134,6 @@ export default function TimelinePageTemplateUI<TManageItems>(
className="fixed-bottom"
timeline={timeline}
onHeightChange={onPostEditHeightChange}
- timelineUniqueId={timeline.uniqueId}
/>
</>
) : null}
diff --git a/FrontEnd/src/app/views/timeline-common/TimelinePropertyChangeDialog.tsx b/FrontEnd/src/app/views/timeline-common/TimelinePropertyChangeDialog.tsx
index b99ec267..a5628a9a 100644
--- a/FrontEnd/src/app/views/timeline-common/TimelinePropertyChangeDialog.tsx
+++ b/FrontEnd/src/app/views/timeline-common/TimelinePropertyChangeDialog.tsx
@@ -10,12 +10,11 @@ import {
import OperationDialog from "../common/OperationDialog";
-// TODO: Trigger resync.
-
export interface TimelinePropertyChangeDialogProps {
open: boolean;
close: () => void;
timeline: HttpTimelineInfo;
+ onChange: () => void;
}
const labelMap: { [key in TimelineVisibility]: string } = {
@@ -27,7 +26,7 @@ const labelMap: { [key in TimelineVisibility]: string } = {
const TimelinePropertyChangeDialog: React.FC<TimelinePropertyChangeDialogProps> = (
props
) => {
- const { timeline } = props;
+ const { timeline, onChange } = props;
return (
<OperationDialog
@@ -66,7 +65,9 @@ const TimelinePropertyChangeDialog: React.FC<TimelinePropertyChangeDialogProps>
if (newDescription !== timeline.description) {
req.description = newDescription;
}
- return getHttpTimelineClient().patchTimeline(timeline.name, req);
+ return getHttpTimelineClient()
+ .patchTimeline(timeline.name, req)
+ .then(onChange);
}}
/>
);
diff --git a/FrontEnd/src/app/views/timeline/TimelineDeleteDialog.tsx b/FrontEnd/src/app/views/timeline/TimelineDeleteDialog.tsx
index 0d3199d6..f472c16a 100644
--- a/FrontEnd/src/app/views/timeline/TimelineDeleteDialog.tsx
+++ b/FrontEnd/src/app/views/timeline/TimelineDeleteDialog.tsx
@@ -2,7 +2,7 @@ import React from "react";
import { useHistory } from "react-router";
import { Trans } from "react-i18next";
-import { timelineService } from "@/services/timeline";
+import { getHttpTimelineClient } from "@/http/timeline";
import OperationDialog from "../common/OperationDialog";
@@ -43,7 +43,7 @@ const TimelineDeleteDialog: React.FC<TimelineDeleteDialog> = (props) => {
}
}}
onProcess={() => {
- return timelineService.deleteTimeline(name).toPromise();
+ return getHttpTimelineClient().deleteTimeline(name);
}}
onSuccessAndClose={() => {
history.replace("/");
diff --git a/FrontEnd/src/app/views/timeline/TimelineInfoCard.tsx b/FrontEnd/src/app/views/timeline/TimelineInfoCard.tsx
index 920f504d..63da6f3c 100644
--- a/FrontEnd/src/app/views/timeline/TimelineInfoCard.tsx
+++ b/FrontEnd/src/app/views/timeline/TimelineInfoCard.tsx
@@ -1,12 +1,10 @@
import React from "react";
-import { useAvatar } from "@/services/user";
-
-import BlobImage from "../common/BlobImage";
import TimelineCardTemplate, {
TimelineCardTemplateProps,
} from "../timeline-common/TimelineCardTemplate";
import { TimelineCardComponentProps } from "../timeline-common/TimelinePageTemplateUI";
+import UserAvatar from "../common/user/UserAvatar";
export type OrdinaryTimelineManageItem = "delete";
@@ -16,8 +14,6 @@ const TimelineInfoCard: React.FC<TimelineInfoCardProps> = (props) => {
const { timeline, operations } = props;
const { onManage, onMember } = operations;
- const avatar = useAvatar(timeline?.owner?.username);
-
return (
<TimelineCardTemplate
infoArea={
@@ -27,8 +23,8 @@ const TimelineInfoCard: React.FC<TimelineInfoCardProps> = (props) => {
<small className="ml-3 text-secondary">{timeline.name}</small>
</h3>
<div className="align-middle">
- <BlobImage
- blob={avatar}
+ <UserAvatar
+ username={timeline.owner.username}
className="avatar small rounded-circle mr-3"
/>
{timeline.owner.nickname}
diff --git a/FrontEnd/src/app/views/timeline/index.tsx b/FrontEnd/src/app/views/timeline/index.tsx
index 225a1a59..8048dd12 100644
--- a/FrontEnd/src/app/views/timeline/index.tsx
+++ b/FrontEnd/src/app/views/timeline/index.tsx
@@ -7,12 +7,13 @@ import TimelinePageUI from "./TimelinePageUI";
import { OrdinaryTimelineManageItem } from "./TimelineInfoCard";
import TimelineDeleteDialog from "./TimelineDeleteDialog";
-const TimelinePage: React.FC = (_) => {
+const TimelinePage: React.FC = () => {
const { name } = useParams<{ name: string }>();
const [dialog, setDialog] = React.useState<OrdinaryTimelineManageItem | null>(
null
);
+ const [reloadKey, setReloadKey] = React.useState<number>(0);
let dialogElement: React.ReactElement | undefined;
if (dialog === "delete") {
@@ -28,6 +29,8 @@ const TimelinePage: React.FC = (_) => {
UiComponent={TimelinePageUI}
onManage={(item) => setDialog(item)}
notFoundI18nKey="timeline.timelineNotExist"
+ reloadKey={reloadKey}
+ onReload={() => setReloadKey(reloadKey + 1)}
/>
{dialogElement}
</>
diff --git a/FrontEnd/src/app/views/user/UserInfoCard.tsx b/FrontEnd/src/app/views/user/UserInfoCard.tsx
index 01d2c096..24b7b979 100644
--- a/FrontEnd/src/app/views/user/UserInfoCard.tsx
+++ b/FrontEnd/src/app/views/user/UserInfoCard.tsx
@@ -1,12 +1,10 @@
import React from "react";
-import { useAvatar } from "@/services/user";
-
-import BlobImage from "../common/BlobImage";
import TimelineCardTemplate, {
TimelineCardTemplateProps,
} from "../timeline-common/TimelineCardTemplate";
import { TimelineCardComponentProps } from "../timeline-common/TimelinePageTemplateUI";
+import UserAvatar from "../common/user/UserAvatar";
export type PersonalTimelineManageItem = "avatar" | "nickname";
@@ -16,8 +14,6 @@ const UserInfoCard: React.FC<UserInfoCardProps> = (props) => {
const { timeline, operations } = props;
const { onManage, onMember } = operations;
- const avatar = useAvatar(timeline?.owner?.username);
-
return (
<TimelineCardTemplate
infoArea={
@@ -27,8 +23,8 @@ const UserInfoCard: React.FC<UserInfoCardProps> = (props) => {
<small className="ml-3 text-secondary">{timeline.name}</small>
</h3>
<div className="align-middle">
- <BlobImage
- blob={avatar}
+ <UserAvatar
+ username={timeline.owner.username}
className="avatar small rounded-circle mr-3"
/>
{timeline.owner.nickname}
diff --git a/FrontEnd/src/app/views/user/index.tsx b/FrontEnd/src/app/views/user/index.tsx
index bb986178..9b5acbba 100644
--- a/FrontEnd/src/app/views/user/index.tsx
+++ b/FrontEnd/src/app/views/user/index.tsx
@@ -1,10 +1,9 @@
import React, { useState } from "react";
import { useParams } from "react-router";
-import { userInfoService } from "@/services/user";
+import { getHttpUserClient } from "@/http/user";
import TimelinePageTemplate from "../timeline-common/TimelinePageTemplate";
-
import UserPageUI from "./UserPageUI";
import { PersonalTimelineManageItem } from "./UserInfoCard";
import ChangeNicknameDialog from "./ChangeNicknameDialog";
@@ -15,6 +14,8 @@ const UserPage: React.FC = (_) => {
const [dialog, setDialog] = useState<null | PersonalTimelineManageItem>(null);
+ const [reloadKey, setReloadKey] = React.useState<number>(0);
+
let dialogElement: React.ReactElement | undefined;
const closeDialog = (): void => setDialog(null);
@@ -24,9 +25,10 @@ const UserPage: React.FC = (_) => {
<ChangeNicknameDialog
open
close={closeDialog}
- onProcess={(newNickname) =>
- userInfoService.setNickname(username, newNickname)
- }
+ onProcess={async (newNickname) => {
+ await getHttpUserClient().patch(username, { nickname: newNickname });
+ setReloadKey(reloadKey + 1);
+ }}
/>
);
} else if (dialog === "avatar") {
@@ -34,7 +36,10 @@ const UserPage: React.FC = (_) => {
<ChangeAvatarDialog
open
close={closeDialog}
- process={(file) => userInfoService.setAvatar(username, file)}
+ process={async (file) => {
+ await getHttpUserClient().putAvatar(username, file);
+ setReloadKey(reloadKey + 1);
+ }}
/>
);
}
@@ -46,6 +51,8 @@ const UserPage: React.FC = (_) => {
UiComponent={UserPageUI}
onManage={(item) => setDialog(item)}
notFoundI18nKey="timeline.userNotExist"
+ reloadKey={reloadKey}
+ onReload={() => setReloadKey(reloadKey + 1)}
/>
{dialogElement}
</>