diff --git a/app/package-lock.json b/app/package-lock.json index d429ae715..7a5506d3a 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -32,6 +32,7 @@ "@uidotdev/usehooks": "^2.4.1", "autoprefixer": "^10.4.20", "beautiful-react-hooks": "^5.0.2", + "color2k": "^2.0.3", "dayjs": "^1.11.13", "deck.gl": "^9.0.27", "i18next": "^23.14.0", @@ -6980,6 +6981,11 @@ "simple-swizzle": "^0.2.2" } }, + "node_modules/color2k": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/color2k/-/color2k-2.0.3.tgz", + "integrity": "sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog==" + }, "node_modules/colorbrewer": { "version": "1.5.6", "resolved": "https://registry.npmjs.org/colorbrewer/-/colorbrewer-1.5.6.tgz", diff --git a/app/package.json b/app/package.json index 54205b3db..e9efdc935 100644 --- a/app/package.json +++ b/app/package.json @@ -48,6 +48,7 @@ "@uidotdev/usehooks": "^2.4.1", "autoprefixer": "^10.4.20", "beautiful-react-hooks": "^5.0.2", + "color2k": "^2.0.3", "dayjs": "^1.11.13", "deck.gl": "^9.0.27", "i18next": "^23.14.0", diff --git a/app/public/locales/en/translation.json b/app/public/locales/en/translation.json index f6637a601..891bfd71d 100644 --- a/app/public/locales/en/translation.json +++ b/app/public/locales/en/translation.json @@ -157,5 +157,8 @@ "resetHeaders": "Reset headers", "resetHeadersDesc": "Reset your loop's headers to the default headers.", "areYouSureYouWantToResetHeaders": "Are you sure you want to reset the loop's headers to defualt?", - "chatRoomOptions": "Chat Room Options" + "chatRoomOptions": "Chat Room Options", + "createRoom": "Create Room", + "roomName": "Room Name", + "roomColor": "Room Color" } diff --git a/app/src/components/Chat/ChatRoomSelect.tsx b/app/src/components/Chat/ChatRoomSelect.tsx index e04bc8813..35b5ded3f 100644 --- a/app/src/components/Chat/ChatRoomSelect.tsx +++ b/app/src/components/Chat/ChatRoomSelect.tsx @@ -1,18 +1,40 @@ -import { IonActionSheet, IonAlert, IonIcon, useIonAlert } from "@ionic/react"; +import { + IonActionSheet, + IonButton, + IonButtons, + IonContent, + IonHeader, + IonIcon, + IonInput, + IonItem, + IonLabel, + IonList, + IonModal, + IonTitle, + IonToolbar, + useIonAlert, +} from "@ionic/react"; import { Channel } from "@mattermost/types/channels"; -import { useState } from "react"; +import { useRef, useState } from "react"; import { useLongPress } from "use-long-press"; -import { addOutline, build as buildFilled } from "ionicons/icons"; +import { + addOutline, + bag, + build as buildFilled, + checkmarkCircle, + ellipse, +} from "ionicons/icons"; import { useTranslation } from "react-i18next"; import { IonAlertCustomEvent } from "@ionic/core"; import { UserGroup } from "@heroiclabs/nakama-js"; +import { readableColor } from "color2k"; interface Props { chainChannels: UserGroup[]; selectedChannel: UserGroup | null; isChainAdmin: boolean; onSelectChannel: (cr: UserGroup) => void; - onCreateChannel: (name: string) => void; + onCreateChannel: (name: string, color: string) => void; onDeleteChannelSubmit: () => void; onRenameChannelSubmit: (name: string) => void; selectedOldBulkyItems: boolean; @@ -34,13 +56,37 @@ export default function ChatRoomSelect(props: Props) { }, }, ); + const modal = useRef(null); + const [channelName, setChannelName] = useState(""); - function onCreateChannelSubmit(e: IonAlertCustomEvent) { - if (e?.detail?.role === "submit" && e.detail?.data?.values?.name) { - props.onCreateChannel(e.detail.data.values.name); - } - } + const channelColors = [ + "#C9843E", + "#AD8F22", + "#79A02D", + "#66926E", + "#199FBA", + "#6494C2", + "#1467B3", + "#A899C2", + "#513484", + "#B37EAD", + "#B76DAC", + "#F57BB0", + "#A35C7B", + "#E38C95", + "#C73643", + "#7D7D7D", + "#3C3C3B", + ]; + const [channelColor, setChannelColor] = useState(channelColors[2]); + function onCreateChannelSubmit() { + props.onCreateChannel(channelName, channelColor); + modal.current?.dismiss(); + } + function cancel() { + modal.current?.dismiss(); + } function handleChannelOptionSelect(value: "delete" | "rename") { if (value == "delete") { const handler = () => { @@ -92,7 +138,10 @@ export default function ChatRoomSelect(props: Props) { .group!.description!.split(" ") .map((word) => word[0]) .join(""); + const isSelected = cr.group!.id === props.selectedChannel?.group!.id; + + const textColor = readableColor(cr.group!.avatar_url || "#fff"); return ( ) : null} - + + + + + {t("cancel")} + + {t("createRoom")} + + + {t("Create")} + + + + + + + + (e.target as any as HTMLInputElement).select()} + onIonInput={(e) => + setChannelName(e.detail.value?.toString() || "") + } + /> + + + + {t("roomColor")} +
+ {channelColors.map((c) => { + const selected = c === channelColor; + return ( + setChannelColor(c)} + className="hover:!tw-opacity-100 tw-group" + > + + + ); + })} +
+
+
+
+
+
); } diff --git a/app/src/pages/Chat.tsx b/app/src/pages/Chat.tsx index 0313077d3..9178396c7 100644 --- a/app/src/pages/Chat.tsx +++ b/app/src/pages/Chat.tsx @@ -190,7 +190,7 @@ export default function Chat() { return _groups; } - async function onCreateChannel(name: string) { + async function onCreateChannel(name: string, color: string) { if (!chain || !nakamaClient || !nakama.session) { if (!chain) console.error("chain not found"); if (!nakamaClient) console.error("nClient not found"); @@ -202,7 +202,7 @@ export default function Chat() { const group = await nakamaClient.createGroup(nakama.session, { name: crypto.randomUUID().toString(), description: name, - avatar_url: "#ee33ee", + avatar_url: color, open: IS_GROUP_OPEN, }); await apiChat.chatCreateGroup(chain.uid, group.id!);