Skip to content

Commit

Permalink
feat: channel creation !!!
Browse files Browse the repository at this point in the history
  • Loading branch information
Rexogamer committed Dec 29, 2023
1 parent c0d415a commit 742ca0e
Show file tree
Hide file tree
Showing 7 changed files with 264 additions and 16 deletions.
11 changes: 11 additions & 0 deletions i18n/strings/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"cancel": "Cancel",
"close": "Close",
"confirm": "Confirm",
"create_channel": "Create channel",
"delete": "Delete",
"save": "Save"
},
Expand Down Expand Up @@ -47,6 +48,16 @@
"body_server": "Are you sure you want to delete <2>{{name}}</2>?",
"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",
Expand Down
12 changes: 7 additions & 5 deletions src/Generic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 = {
Expand Down Expand Up @@ -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) {
Expand Down
36 changes: 34 additions & 2 deletions src/Modals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -229,6 +246,21 @@ export const Modals = observer(() => {
<TextEditModal object={editingText!} />
</View>
</Modal>
<Modal
visible={!!createChannelObject}
transparent={true}
animationType="fade"
onRequestClose={() => setEditingText(null)}>
<View
style={{
flex: 1,
alignContent: 'center',
justifyContent: 'center',
backgroundColor: '#00000080',
}}>
<CreateChannelModal object={createChannelObject!} />
</View>
</Modal>
</>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -95,17 +96,100 @@ export const ChannelSettingsSection = observer(
</>
) : (
<>
<Text type={'h1'}>{t('app.servers.settings.channels.title')}</Text>
<View
style={{
flexDirection: 'row',
alignItems: 'center',
marginVertical: 4,
}}>
<View style={{flex: 1}}>
<Text type={'h1'}>
{t('app.servers.settings.channels.title')}
</Text>
</View>
{server.havePermission('ManageChannel') ? (
<Pressable
onPress={() => {
app.openCreateChannelModal({
server,
callback: () => {},
});
}}
style={{
width: 30,
height: 20,
alignItems: 'center',
justifyContent: 'center',
}}>
<View style={styles.iconContainer}>
<MaterialIcon
name={'add'}
size={20}
color={currentTheme.foregroundPrimary}
/>
</View>
</Pressable>
) : null}
</View>
{server.orderedChannels.map(cat => (
<View key={`channel-settings-category-${cat.id}`}>
<Text type={'h2'}>
{cat.id === 'default' ? 'Uncategorised' : cat.title}
</Text>
{cat.id !== 'default' ? (
<Text colour={currentTheme.foregroundSecondary}>
{cat.id}
</Text>
) : null}
<View
style={{
flexDirection: 'row',
alignItems: 'center',
marginVertical: 4,
}}>
<View style={{flex: 1}}>
<Text type={'h2'}>
{cat.id === 'default' ? 'Uncategorised' : cat.title}
</Text>
{cat.id !== 'default' ? (
<Text colour={currentTheme.foregroundSecondary}>
{cat.id}
</Text>
) : null}
</View>
{/* uncomment when revolt lets you create channels in categories
{server.havePermission('ManageChannel') ? (
<Pressable
onPress={() => {
app.openCreateChannelModal({
server,
callback: () => {},
category: cat.id,
});
}}
style={{
width: 30,
height: 20,
alignItems: 'center',
justifyContent: 'center',
}}>
<View style={styles.iconContainer}>
<MaterialIcon
name={'add'}
size={20}
color={currentTheme.foregroundPrimary}
/>
</View>
</Pressable>
) : null} */}
<Pressable
style={{
width: 30,
height: 20,
alignItems: 'center',
justifyContent: 'center',
}}>
<View style={styles.iconContainer}>
<MaterialIcon
name={'arrow-forward'}
size={20}
color={currentTheme.foregroundPrimary}
/>
</View>
</Pressable>
</View>
{cat.channels.map(c => (
<Pressable
style={styles.settingsEntry}
Expand Down
112 changes: 112 additions & 0 deletions src/components/modals/CreateChannelModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import React from 'react';
import {Pressable, TextInput, View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {observer} from 'mobx-react-lite';

import MaterialIcon from 'react-native-vector-icons/MaterialIcons';

import {app} from '@rvmob/Generic';
import {currentTheme, styles} from '@rvmob/Theme';
import {Button, Checkbox, Text} from '@rvmob/components/common/atoms';
import {CreateChannelModalProps} from '@rvmob/lib/types';

export const CreateChannelModal = observer(
({object}: {object: CreateChannelModalProps}) => {
const {t} = useTranslation();

const [name, setName] = React.useState('');
const [type, setType] = React.useState('Text' as 'Text' | 'Voice');
const [nsfw, setNSFW] = React.useState(false);

return (
<View
style={{
width: '80%',
borderRadius: 8,
padding: 20,
backgroundColor: currentTheme.backgroundPrimary,
justifyContent: 'center',
alignSelf: 'center',
}}>
<Text type={'h1'}>{t('app.modals.create_channel.header')}</Text>
<View
style={{
flexDirection: 'column',
justifyContent: 'center',
marginTop: 10,
}}>
<Text type={'h2'}>{t('app.modals.create_channel.name_header')}</Text>
<TextInput
style={{...styles.input, marginVertical: 4}}
value={name}
placeholder={t('app.modals.create_channel.name_placeholder')}
onChangeText={v => {
setName(v);
}}
/>
<Text type={'h2'}>{t('app.modals.create_channel.type_header')}</Text>
<View
style={{
marginVertical: 4,
borderRadius: 8,
minWidth: '100%',
backgroundColor: currentTheme.backgroundSecondary,
padding: 8,
}}>
{['Text', 'Voice'].map(ct => (
<Pressable
key={`channel-type-${ct}`}
style={styles.actionTile}
onPress={() => {
// @ts-expect-error it's fine typescript, don't worry. lmk if you need a hug
setType(ct);
}}>
<Text style={{flex: 1}}>{ct}</Text>
<View style={{...styles.iconContainer, marginRight: 0}}>
<MaterialIcon
name={`radio-button-${type === ct ? 'on' : 'off'}`}
size={28}
color={currentTheme.accentColor}
/>
</View>
</Pressable>
))}
</View>
<View
style={{
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
marginVertical: 4,
}}>
<Text>{t('app.modals.create_channel.nsfw_label')}</Text>
<Checkbox
key={'checkbox-channel-nsfw'}
value={nsfw}
callback={() => {
setNSFW(!nsfw);
}}
/>
</View>
<Button
onPress={() => {
app.openCreateChannelModal(null);
object.server.createChannel({name, type, nsfw}).then(c => {
object.callback(c._id);
});
}}
style={{marginHorizontal: 0}}>
<Text>{t('app.actions.create_channel')}</Text>
</Button>
<Button
onPress={() => {
app.openCreateChannelModal(null);
}}
style={{marginHorizontal: 0}}>
<Text>{t('app.actions.cancel')}</Text>
</Button>
</View>
</View>
);
},
);
1 change: 1 addition & 0 deletions src/components/modals/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export {ConfirmDeletionModal} from './ConfirmDeletionModal';
export {CreateChannelModal} from './CreateChannelModal';
export {TextEditModal} from './TextEditModal';
6 changes: 6 additions & 0 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 742ca0e

Please sign in to comment.