Refactored Forum Modal to use custom hooks.

This commit is contained in:
Qortal Dev 2024-10-04 14:06:02 -06:00
parent dd500a3ebb
commit 2884996c79
8 changed files with 158 additions and 123 deletions

View File

@ -9,7 +9,7 @@ import {
ComposeP,
InstanceContainer,
} from "../../Home/Home-styles";
import { ForumData, ForumModal } from "../ForumModal";
import { ForumData, ForumModal } from "../CreateForum/ForumModal";
export const forums = signal<ForumData[]>([]);
export const resetForumIndexes = (forums: Signal<ForumData[]>) => {

View File

@ -18,7 +18,7 @@ import {
NewMessageSendButton,
NewMessageSendP,
} from "../../Home/Home-styles";
import { publishForum } from "../ForumModal-Data";
import { publishForum } from "../CreateForum/ForumModal-State";
export interface ModalButtonProps {
onSubmit: () => Promise<boolean>;

View File

@ -1,11 +1,80 @@
import { FORUMS_ID } from "../../constants/Identifiers";
import { setNotification } from "../../state/features/notificationsSlice";
import { store } from "../../state/store";
import { getGroup } from "../../utils/QortalRequests";
import { objectToBase64 } from "../../utils/toBase64";
import { Signal, useComputed, useSignal } from "@preact/signals-react";
import { useSignals } from "@preact/signals-react/runtime";
import { useEffect } from "react";
import { FORUMS_ID } from "../../../constants/Identifiers";
import { setNotification } from "../../../state/features/notificationsSlice";
import { store } from "../../../state/store";
import { getGroup } from "../../../utils/QortalRequests";
import { objectToBase64 } from "../../../utils/toBase64";
import { resetForumIndexes } from "../Components/ActionBar";
import { ForumData } from "./ForumModal";
import { Group } from "./GroupPermissionsForm";
import { Group } from "./GroupPermissions";
export const useForumModalState = (forumData: Signal<ForumData[]>) => {
useSignals();
const tempData = useSignal<ForumData[]>([]);
const selectedForumIndex = useSignal<number>(0);
const selectedForum = useComputed<ForumData>(() => {
return tempData.value[selectedForumIndex.value];
});
const initializeTempData = () => {
tempData.value =
forumData.value.length === 0
? [emptyForum]
: deepCopyArray(forumData.value);
selectedForumIndex.value = 0;
};
useEffect(() => {
initializeTempData();
}, [forumData.value]);
const addForum = () => {
const newForum = { ...emptyForum };
newForum.listIndex = tempData.value.length;
tempData.value = [...tempData.value, newForum];
selectedForumIndex.value = newForum.listIndex;
};
const removeForum = () => {
if (tempData.value.length <= 1) {
tempData.value = [{ ...emptyForum }];
selectedForumIndex.value = 0;
} else {
tempData.value = tempData.value.filter(
(group, index) => index !== selectedForumIndex.value
);
if (selectedForumIndex.value > 0) selectedForumIndex.value -= 1;
else selectedForumIndex.value = 0;
}
resetForumIndexes(tempData);
};
const updateForums = () => {
tempData.value = [...tempData.value];
};
return {
tempData,
selectedForumIndex,
selectedForum,
addForum,
removeForum,
updateForums,
initializeTempData,
};
};
const emptyForum: ForumData = {
title: "",
encryption: "None",
groups: [],
descriptionHTML: "",
descriptionText: "",
listIndex: 0,
};
const getGroupsData = async (groups: Group[]) => {
const groupPromises = groups.map(group => getGroup(group.id));
return await Promise.all(groupPromises);

View File

@ -8,18 +8,23 @@ import {
import { useSignals } from "@preact/signals-react/runtime";
import React, { useEffect } from "react";
import { useSelector } from "react-redux";
import { SelectField } from "../../components/common/SelectField";
import { Spacer } from "../../components/common/Spacer";
import { TextEditor } from "../../components/common/TextEditor/TextEditor";
import { useTestIdentifiers } from "../../constants/Identifiers";
import { appOwner } from "../../constants/Misc";
import { RootState } from "../../state/store";
import { NewMessageInputRow } from "../Home/Home-styles";
import { resetForumIndexes } from "./Components/ActionBar";
import { ModalButton } from "./Components/ModalButton";
import { QmailTextField } from "./Components/QmailTextField";
import { deepCopyArray, forumToString, publishForum } from "./ForumModal-Data";
import { Group, GroupPermissionsForm } from "./GroupPermissionsForm";
import { SelectField } from "../../../components/common/SelectField";
import { Spacer } from "../../../components/common/Spacer";
import { TextEditor } from "../../../components/common/TextEditor/TextEditor";
import { useTestIdentifiers } from "../../../constants/Identifiers";
import { appOwner } from "../../../constants/Misc";
import { RootState } from "../../../state/store";
import { NewMessageInputRow } from "../../Home/Home-styles";
import { resetForumIndexes } from "../Components/ActionBar";
import { ModalButton } from "../Components/ModalButton";
import { QmailTextField } from "../Components/QmailTextField";
import {
deepCopyArray,
forumToString,
publishForum,
useForumModalState,
} from "./ForumModal-State";
import { Group, GroupPermissions } from "./GroupPermissions";
export type EncryptionType = "None" | "Group" | "GroupAdmin" | "";
export interface ForumData {
@ -45,64 +50,18 @@ interface NewForumModalProps {
}
export const ForumModal = ({ forumData }: NewForumModalProps) => {
useSignals();
const tempData = useSignal<ForumData[]>([]);
const emptyForum: ForumData = {
title: "",
encryption: "None",
groups: [],
descriptionHTML: "",
descriptionText: "",
listIndex: 0,
};
const { user } = useSelector((state: RootState) => state.auth);
const isRenderModal = user?.name === appOwner || useTestIdentifiers;
const selectedForumIndex = useSignal<number>(0);
const selectedForum = useComputed<ForumData>(() => {
return tempData.value[selectedForumIndex.value];
});
const initializeTempData = () => {
tempData.value =
forumData.value.length === 0
? [emptyForum]
: deepCopyArray(forumData.value);
selectedForumIndex.value = 0;
};
useEffect(() => {
initializeTempData();
}, [forumData.value]);
const addForum = () => {
const newForum = { ...emptyForum };
newForum.listIndex = tempData.value.length;
tempData.value = [...tempData.value, newForum];
selectedForumIndex.value = newForum.listIndex;
};
const removeForum = () => {
if (tempData.value.length <= 1) {
tempData.value = [{ ...emptyForum }];
selectedForumIndex.value = 0;
} else {
tempData.value = tempData.value.filter(
(group, index) => index !== selectedForumIndex.value
);
if (selectedForumIndex.value > 0) selectedForumIndex.value -= 1;
else selectedForumIndex.value = 0;
}
resetForumIndexes(tempData);
};
const updateForums = () => {
tempData.value = [...tempData.value];
};
const {
tempData,
selectedForumIndex,
selectedForum,
addForum,
removeForum,
updateForums,
initializeTempData,
} = useForumModalState(forumData);
return (
<ModalButton
@ -110,10 +69,10 @@ export const ForumModal = ({ forumData }: NewForumModalProps) => {
onClose={() => initializeTempData()}
onSubmit={async () => {
updateForums();
const pub = await publishForum(tempData.value);
const isPublished = await publishForum(tempData.value);
if (pub) forumData.value = tempData.value;
return pub;
if (isPublished) forumData.value = tempData.value;
return isPublished;
}}
modalLabel={"Manage Forums"}
buttonLabel={"Publish Forums"}
@ -189,7 +148,7 @@ export const ForumModal = ({ forumData }: NewForumModalProps) => {
}}
/>
</NewMessageInputRow>
<GroupPermissionsForm
<GroupPermissions
initialGroups={selectedForum.value?.groups}
afterChange={g => {
tempData.value[selectedForumIndex.value].groups = g;

View File

@ -0,0 +1,41 @@
import { useSignal } from "@preact/signals-react";
import { useSignals } from "@preact/signals-react/runtime";
import { useEffect } from "react";
import { Group } from "./GroupPermissions";
export const useGroupPermissionsState = (
initialGroups?: Group[],
afterChange?: (g: Group[]) => void
) => {
useSignals();
const newGroup = {
id: "",
permissions: "Read",
} as Group;
const groups = useSignal<Group[]>(initialGroups || [newGroup]);
useEffect(() => {
if (initialGroups)
groups.value = initialGroups?.length > 0 ? initialGroups : [newGroup];
}, [initialGroups]);
const addGroup = () => {
groups.value = [...groups.value, newGroup];
if (afterChange) afterChange(groups.value);
};
const removeGroup = (groupIndex: number) => {
if (groups.value.length > 1)
groups.value = groups.value.filter(
(group, index) => index !== groupIndex
);
else groups.value = [newGroup];
if (afterChange) afterChange(groups.value);
};
const updateGroups = () => {
if (afterChange) afterChange(groups.value);
};
return { groups, addGroup, removeGroup, updateGroups };
};

View File

@ -2,14 +2,12 @@ import AddIcon from "@mui/icons-material/Add";
import RemoveIcon from "@mui/icons-material/Remove";
import { Box, IconButton } from "@mui/material";
import { styled } from "@mui/material/styles";
import { Signal, useSignal } from "@preact/signals-react";
import { useSignals } from "@preact/signals-react/runtime";
import React, { useEffect } from "react";
import ShortUniqueId from "short-unique-id";
import { SelectField } from "../../components/common/SelectField";
import { NewMessageInputRow } from "../Home/Home-styles";
import { QmailTextField } from "./Components/QmailTextField";
import { SelectField } from "../../../components/common/SelectField";
import { NewMessageInputRow } from "../../Home/Home-styles";
import { QmailTextField } from "../Components/QmailTextField";
import { GroupPermissionType } from "./ForumModal";
import { useGroupPermissionsState } from "./GroupPermissions-State";
export interface Group {
id: string;
@ -19,47 +17,15 @@ export interface GroupPermissionsFormProps {
initialGroups?: Group[];
afterChange?: (g: Group[]) => void;
}
export const GroupPermissionsForm = ({
export const GroupPermissions = ({
initialGroups,
afterChange,
}: GroupPermissionsFormProps) => {
useSignals();
const newGroup = {
id: "",
permissions: "Read",
} as Group;
const groups = useSignal<Group[]>(initialGroups || [newGroup]);
useEffect(() => {
if (initialGroups)
groups.value = initialGroups?.length > 0 ? initialGroups : [newGroup];
}, [initialGroups]);
const { groups, addGroup, removeGroup, updateGroups } =
useGroupPermissionsState(initialGroups, afterChange);
const uid = new ShortUniqueId();
const addGroup = () => {
groups.value = [...groups.value, newGroup];
if (afterChange) afterChange(groups.value);
};
const removeGroup = (groupIndex: number) => {
if (groups.value.length > 1)
groups.value = groups.value.filter(
(group, index) => index !== groupIndex
);
else groups.value = [newGroup];
if (afterChange) afterChange(groups.value);
};
const updateGroups = () => {
if (afterChange) afterChange(groups.value);
};
const buttonStyle = {
width: "70px",
height: "70px",
};
const StyledIconButton = styled(IconButton)(`
width: 60px;
height: 60px;

View File

@ -9,8 +9,8 @@ import {
InstanceContainer,
} from "../Home/Home-styles";
import { GroupMail } from "../Mail/GroupMail";
import { Group } from "./GroupPermissionsForm";
import { EncryptionType, ForumData } from "./ForumModal";
import { Group } from "./CreateForum/GroupPermissions";
import { EncryptionType, ForumData } from "./CreateForum/ForumModal";
export const Forum = ({
title,

View File

@ -1,6 +1,6 @@
import { FORUMS_ID } from "../constants/Identifiers";
import { appOwner } from "../constants/Misc";
import { ForumData } from "../pages/Forum/ForumModal";
import { ForumData } from "../pages/Forum/CreateForum/ForumModal";
export interface GroupData {
groupId: number;