+
{
onScrollEnd={handleScroll}
class="h-full list flex flex-col p-2 pt-18 pb-24 overflow-y-auto scrollbar-thin scrollbar-thumb-gray-500 scrollbar-track-gray-800"
>
- {messages().map((message, messageIndex, allMessages) => (
-
- ))}
+ {messages().map(mapMessage)}
{channelInfo() ? (
) : undefined}
diff --git a/src/views/CommunitySettingsModalView/CommunitySettingsModalView.tsx b/src/views/CommunitySettingsModalView/CommunitySettingsModalView.tsx
index b4b20bd..34a71f3 100644
--- a/src/views/CommunitySettingsModalView/CommunitySettingsModalView.tsx
+++ b/src/views/CommunitySettingsModalView/CommunitySettingsModalView.tsx
@@ -1,6 +1,15 @@
-import { createSignal, type Component, type JSXElement } from "solid-js";
+import {
+ createEffect,
+ createSignal,
+ type Component,
+ type JSXElement,
+} from "solid-js";
import { ICommunitySettingsModalViewProps } from "./types";
-import CommunitySettingsProfilePage from "./pages/SettingsProfilePage/CommunitySettingsProfilePage";
+import CommunitySettingsProfilePage from "./pages/CommunitySettingsProfilePage/CommunitySettingsProfilePage";
+import CommunitySettingsChannelsPage from "./pages/CommunitySettingsChannelsPage/CommunitySettingsChannelsPage";
+import CommunitySettingsRolesPage from "./pages/CommunitySettingsRolesPage/CommunitySettingsRolesPage";
+import CommunitySettingsMembersPage from "./pages/CommunitySettingsMembersPage/CommunitySettingsMembersPage";
+import CommunitySettingsInvitesPage from "./pages/CommunitySettingsInvitesPage/CommunitySettingsInvitesPage";
import { Dynamic } from "solid-js/web";
import { SettingsItem } from "../../components/SettingsItem";
import { getActiveCommunity } from "../../store/community";
@@ -8,12 +17,27 @@ import { getActiveCommunity } from "../../store/community";
const CommunitySettingsModalView: Component<
ICommunitySettingsModalViewProps
> = (props: ICommunitySettingsModalViewProps) => {
+ const [getSelectedCommunityId, setSelectedCommunityId] = createSignal<
+ string | undefined
+ >(undefined);
const [getSelectedPage, setSelectedPage] = createSignal
(
undefined,
);
+ createEffect(() => {
+ const comunity = getActiveCommunity();
+ if (getSelectedCommunityId() !== comunity?.id) {
+ setSelectedCommunityId(comunity?.id);
+ setSelectedPage();
+ }
+ });
+
const pages = new Map([
["Community Profile", CommunitySettingsProfilePage],
+ ["Channels", CommunitySettingsChannelsPage],
+ ["Roles", CommunitySettingsRolesPage],
+ ["Members", CommunitySettingsMembersPage],
+ ["Invites", CommunitySettingsInvitesPage],
]);
const getCurrentPage = (): JSXElement => {
diff --git a/src/views/CommunitySettingsModalView/pages/CommunitySettingsChannelsPage/CommunitySettingsChannelsPage.tsx b/src/views/CommunitySettingsModalView/pages/CommunitySettingsChannelsPage/CommunitySettingsChannelsPage.tsx
new file mode 100644
index 0000000..34a99bf
--- /dev/null
+++ b/src/views/CommunitySettingsModalView/pages/CommunitySettingsChannelsPage/CommunitySettingsChannelsPage.tsx
@@ -0,0 +1,270 @@
+import {
+ Component,
+ createMemo,
+ createSignal,
+ JSXElement,
+ onMount,
+} from "solid-js";
+import { Input } from "../../../../components/Input";
+import { state } from "../../../../store/state";
+import { IChannel } from "../../../../store/channel";
+import { SettingsItem } from "../../../../components/SettingsItem";
+import { getActiveCommunity } from "../../../../store/community";
+import { fetchCommunityChannels } from "../../../../services/community";
+import { removeChannel, updateChannel } from "../../../../services/channel";
+import { CheckIcon, HashIcon, PlusIcon, TrashIcon } from "../../../../icons";
+import { setCreateChannelOpen } from "../../../../store/app";
+import { ISelectOption, Select } from "../../../../components/Select";
+
+const UNCATEGORIZED_VALUE = "Uncategorized";
+
+const CommunitySettingsChannelsPage: Component = () => {
+ const [getSelectedChannelId, setSelectedChannelId] = createSignal<
+ string | undefined
+ >(undefined);
+ const [getManualCategory, setManualCategory] = createSignal(false);
+ const [getSettingsChannelName, setSettingsChannelName] =
+ createSignal("");
+ const [getSettingsChannelDescription, setSettingsChannelDescription] =
+ createSignal("");
+ const [getSettingsChannelCategory, setSettingsChannelCategory] =
+ createSignal("");
+
+ onMount(() => {
+ if (state.community.active) {
+ fetchCommunityChannels(state.community.active);
+ }
+ });
+
+ const getSelectedChannel = (): IChannel | undefined => {
+ const selectedChannelId = getSelectedChannelId();
+ if (!selectedChannelId) {
+ return;
+ }
+
+ return state.channel.channels[selectedChannelId];
+ };
+
+ const onSelectChannel = (id: string) => {
+ const channel = state.channel.channels[id];
+ if (!channel) {
+ return undefined;
+ }
+
+ setSelectedChannelId(id);
+
+ setManualCategory(false);
+
+ setSettingsChannelName(channel.name ?? "");
+ setSettingsChannelDescription(channel.description ?? "");
+ setSettingsChannelCategory(channel.category ?? "");
+ };
+
+ const channelIds = createMemo(() => {
+ const community = getActiveCommunity();
+ if (!community) {
+ return [];
+ }
+
+ return community.channels ?? [];
+ });
+
+ const channels = createMemo(() => {
+ return channelIds()
+ .map((channelId) => {
+ const channel = state.channel.channels[channelId];
+ if (!channel) {
+ return {
+ id: channelId,
+ };
+ }
+
+ return channel;
+ })
+ .filter((channel) => channel.id !== "")
+ .sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
+ });
+
+ const categoryOptions = createMemo(() => {
+ const options = channelIds()
+ .map((channelId) => {
+ const category =
+ state.channel.channels[channelId]?.category ?? "";
+ return { value: category, label: category };
+ })
+ .filter((option) => option.value !== "");
+
+ const uncategorized = {
+ value: UNCATEGORIZED_VALUE,
+ label: UNCATEGORIZED_VALUE,
+ };
+
+ const finalOptions = [uncategorized, ...options];
+
+ return [
+ ...new Map(
+ finalOptions.map((option) => [option.value, option]),
+ ).values(),
+ ];
+ });
+
+ const onAddChannel = () => {
+ setCreateChannelOpen(true);
+ };
+
+ const onSaveChannel = () => {
+ const channel = getSelectedChannel();
+ if (!channel) {
+ return;
+ }
+
+ const name = getSettingsChannelName().trim();
+ const description = getSettingsChannelDescription().trim();
+ const category = getSettingsChannelCategory().trim();
+
+ updateChannel({
+ id: channel.id,
+ name: name.length > 0 ? name : channel.name,
+ description: description,
+ category: category === UNCATEGORIZED_VALUE ? null : category,
+ });
+ };
+
+ const onDeleteChannel = () => {
+ const channel = getSelectedChannel();
+ if (!channel) {
+ return;
+ }
+
+ removeChannel(channel.id);
+
+ setSelectedChannelId();
+ };
+
+ const mapChannel = (channel: IChannel): JSXElement => {
+ return (
+
+ );
+ };
+
+ const categoryHtml = (): JSXElement => {
+ if (getManualCategory()) {
+ return (
+ setManualCategory(false)}
+ />
+ );
+ } else {
+ return (
+