import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { convertI18nText, I18nText } from "@/common"; import { HttpUser } from "@/http/user"; import { getHttpSearchClient } from "@/http/search"; import { getHttpTimelineClient, HttpTimelineInfo } from "@/http/timeline"; import SearchInput from "../common/SearchInput"; import UserAvatar from "../common/user/UserAvatar"; import Button from "../common/button/Button"; import Dialog from "../common/dailog/Dialog"; import "./TimelineMember.css"; const TimelineMemberItem: React.FC<{ user: HttpUser; add?: boolean; onAction?: (username: string) => void; }> = ({ user, add, onAction }) => { return (
{user.nickname}
{"@" + user.username}
{onAction ? (
) : null}
); }; const TimelineMemberUserSearch: React.FC<{ timeline: HttpTimelineInfo; onChange: () => void; }> = ({ timeline, onChange }) => { const { t } = useTranslation(); const [userSearchText, setUserSearchText] = useState(""); const [userSearchState, setUserSearchState] = useState< | { type: "users"; data: HttpUser[]; } | { type: "error"; data: I18nText } | { type: "loading" } | { type: "init" } >({ type: "init" }); return ( <> { setUserSearchText(v); }} loading={userSearchState.type === "loading"} onButtonClick={() => { if (userSearchText === "") { setUserSearchState({ type: "error", data: "login.emptyUsername", }); return; } setUserSearchState({ type: "loading" }); getHttpSearchClient() .searchUsers(userSearchText) .then( (users) => { users = users.filter( (user) => timeline.members.findIndex( (m) => m.username === user.username ) === -1 && timeline.owner.username !== user.username ); setUserSearchState({ type: "users", data: users }); }, (e) => { setUserSearchState({ type: "error", data: { type: "custom", value: String(e) }, }); } ); }} /> {(() => { if (userSearchState.type === "users") { const users = userSearchState.data; if (users.length === 0) { return
{t("timeline.member.noUserAvailableToAdd")}
; } else { return (
{users.map((user) => ( { void getHttpTimelineClient() .memberPut(timeline.name, user.username) .then(() => { setUserSearchText(""); setUserSearchState({ type: "init" }); onChange(); }); }} /> ))}
); } } else if (userSearchState.type === "error") { return (
{convertI18nText(userSearchState.data, t)}
); } })()} ); }; export interface TimelineMemberProps { timeline: HttpTimelineInfo; onChange: () => void; } const TimelineMember: React.FC = (props) => { const { timeline, onChange } = props; const members = [timeline.owner, ...timeline.members]; return (
{members.map((member, index) => ( { void getHttpTimelineClient() .memberDelete(timeline.name, member.username) .then(onChange); } : undefined } /> ))}
{timeline.manageable ? ( ) : null}
); }; export default TimelineMember; export interface TimelineMemberDialogProps extends TimelineMemberProps { open: boolean; onClose: () => void; } export const TimelineMemberDialog: React.FC = ( props ) => { return ( ); };