From 742ca0e853943d027c59e68a74cfcc71e7b1b9ac Mon Sep 17 00:00:00 2001 From: Rexogamer Date: Fri, 29 Dec 2023 09:37:14 +0000 Subject: [PATCH] feat: channel creation !!! --- i18n/strings/en.json | 11 ++ src/Generic.tsx | 12 +- src/Modals.tsx | 36 +++++- .../server/ChannelSettingsSection.tsx | 102 ++++++++++++++-- src/components/modals/CreateChannelModal.tsx | 112 ++++++++++++++++++ src/components/modals/index.ts | 1 + src/lib/types.ts | 6 + 7 files changed, 264 insertions(+), 16 deletions(-) create mode 100644 src/components/modals/CreateChannelModal.tsx diff --git a/i18n/strings/en.json b/i18n/strings/en.json index 23d69079..bfd30e8b 100644 --- a/i18n/strings/en.json +++ b/i18n/strings/en.json @@ -5,6 +5,7 @@ "cancel": "Cancel", "close": "Close", "confirm": "Confirm", + "create_channel": "Create channel", "delete": "Delete", "save": "Save" }, @@ -47,6 +48,16 @@ "body_server": "Are you sure you want to delete <2>{{name}}?", "warning": "This cannot be undone." }, + "create_channel": { + "header": "Create a new channel", + "name_header": "Name", + "name_placeholder": "Channel name", + "type_header": "Type", + "type_text": "Text channel", + "type_voice": "Voice channel", + "nsfw_header": "NSFW", + "nsfw_label": "Mark channel as NSFW" + }, "edit_text": { "display_name_header": "Set display name", "display_name_placeholder": "Display name", diff --git a/src/Generic.tsx b/src/Generic.tsx index 3cc06173..936d13c7 100644 --- a/src/Generic.tsx +++ b/src/Generic.tsx @@ -6,9 +6,9 @@ import FastImage from 'react-native-fast-image'; import {API, Channel, Client, Message, Server} from 'revolt.js'; -import {setLanguage} from '../i18n/i18n'; -import {languages} from '../i18n/languages'; -import {setTheme, themes} from './Theme'; +import {setLanguage} from '@rvmob-i18n/i18n'; +import {languages} from '@rvmob-i18n/languages'; +import {setTheme, themes} from '@rvmob/Theme'; import { DEFAULT_API_URL, DEFAULT_MAX_SIDE, @@ -17,14 +17,15 @@ import { RE_INVITE, RE_BOT_INVITE, WIKI_URL, -} from './lib/consts'; +} from '@rvmob/lib/consts'; import { + CreateChannelModalProps, DeletableObject, ReplyingMessage, ReportedObject, Setting, TextEditingModalProps, -} from './lib/types'; +} from '@rvmob/lib/types'; const Image = FastImage; export const app = { @@ -335,6 +336,7 @@ export const app = { openReportMenu: (object: ReportedObject | null) => {}, openDeletionConfirmationModal: (object: DeletableObject | null) => {}, openTextEditModal: (object: TextEditingModalProps | null) => {}, + openCreateChannelModal: (object: CreateChannelModalProps | null) => {}, }; export function setFunction(name: string, func: any) { diff --git a/src/Modals.tsx b/src/Modals.tsx index cbf5b192..48588201 100644 --- a/src/Modals.tsx +++ b/src/Modals.tsx @@ -8,10 +8,18 @@ import MaterialCommunityIcon from 'react-native-vector-icons/MaterialCommunityIc import {API, Channel, Server, User} from 'revolt.js'; import {app, client, openUrl, setFunction} from './Generic'; -import {DeletableObject, TextEditingModalProps} from './lib/types'; +import { + CreateChannelModalProps, + DeletableObject, + TextEditingModalProps, +} from './lib/types'; import {currentTheme} from './Theme'; import {GapView} from './components/layout'; -import {ConfirmDeletionModal, TextEditModal} from './components/modals'; +import { + ConfirmDeletionModal, + CreateChannelModal, + TextEditModal, +} from './components/modals'; import { BotInviteSheet, ChannelInfoSheet, @@ -48,6 +56,9 @@ export const Modals = observer(() => { const [editingText, setEditingText] = React.useState( null as TextEditingModalProps | null, ); + const [createChannelObject, setCreateChannelObject] = React.useState( + null as CreateChannelModalProps | null, + ); setFunction('openDirectMessage', async (dm: Channel) => { app.openProfile(null); @@ -74,6 +85,12 @@ export const Modals = observer(() => { setEditingText(object); }, ); + setFunction( + 'openCreateChannelModal', + async (object: CreateChannelModalProps | null) => { + setCreateChannelObject(object); + }, + ); setFunction('openInvite', async (i: string) => { try { let community = await client.fetchInvite(i); @@ -229,6 +246,21 @@ export const Modals = observer(() => { + setEditingText(null)}> + + + + ); }); diff --git a/src/components/common/settings/sections/server/ChannelSettingsSection.tsx b/src/components/common/settings/sections/server/ChannelSettingsSection.tsx index f59fc0bd..31dfca6d 100644 --- a/src/components/common/settings/sections/server/ChannelSettingsSection.tsx +++ b/src/components/common/settings/sections/server/ChannelSettingsSection.tsx @@ -7,6 +7,7 @@ import MaterialIcon from 'react-native-vector-icons/MaterialIcons'; import {Server} from 'revolt.js'; +import {app} from '@rvmob/Generic'; import {ChannelSettingsSubsection} from '@rvmob/lib/types'; import {currentTheme, styles} from '@rvmob/Theme'; import {GapView} from '@rvmob/components/layout'; @@ -95,17 +96,100 @@ export const ChannelSettingsSection = observer( ) : ( <> - {t('app.servers.settings.channels.title')} + + + + {t('app.servers.settings.channels.title')} + + + {server.havePermission('ManageChannel') ? ( + { + app.openCreateChannelModal({ + server, + callback: () => {}, + }); + }} + style={{ + width: 30, + height: 20, + alignItems: 'center', + justifyContent: 'center', + }}> + + + + + ) : null} + {server.orderedChannels.map(cat => ( - - {cat.id === 'default' ? 'Uncategorised' : cat.title} - - {cat.id !== 'default' ? ( - - {cat.id} - - ) : null} + + + + {cat.id === 'default' ? 'Uncategorised' : cat.title} + + {cat.id !== 'default' ? ( + + {cat.id} + + ) : null} + + {/* uncomment when revolt lets you create channels in categories + {server.havePermission('ManageChannel') ? ( + { + app.openCreateChannelModal({ + server, + callback: () => {}, + category: cat.id, + }); + }} + style={{ + width: 30, + height: 20, + alignItems: 'center', + justifyContent: 'center', + }}> + + + + + ) : null} */} + + + + + + {cat.channels.map(c => ( { + const {t} = useTranslation(); + + const [name, setName] = React.useState(''); + const [type, setType] = React.useState('Text' as 'Text' | 'Voice'); + const [nsfw, setNSFW] = React.useState(false); + + return ( + + {t('app.modals.create_channel.header')} + + {t('app.modals.create_channel.name_header')} + { + setName(v); + }} + /> + {t('app.modals.create_channel.type_header')} + + {['Text', 'Voice'].map(ct => ( + { + // @ts-expect-error it's fine typescript, don't worry. lmk if you need a hug + setType(ct); + }}> + {ct} + + + + + ))} + + + {t('app.modals.create_channel.nsfw_label')} + { + setNSFW(!nsfw); + }} + /> + + + + + + ); + }, +); diff --git a/src/components/modals/index.ts b/src/components/modals/index.ts index cdab9ab7..853b59bd 100644 --- a/src/components/modals/index.ts +++ b/src/components/modals/index.ts @@ -1,2 +1,3 @@ export {ConfirmDeletionModal} from './ConfirmDeletionModal'; +export {CreateChannelModal} from './CreateChannelModal'; export {TextEditModal} from './TextEditModal'; diff --git a/src/lib/types.ts b/src/lib/types.ts index 616f34cc..4ce8bb3c 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -57,6 +57,12 @@ export type TextEditingModalProps = { callback: (s: string) => void; }; +export type CreateChannelModalProps = { + server: Server; + category?: string; + callback: (c: string) => void; +}; + export type Language = { name: string; englishName: string;