diff --git a/src/Generic.tsx b/src/Generic.tsx
index 1dce1dc..2db6a77 100644
--- a/src/Generic.tsx
+++ b/src/Generic.tsx
@@ -296,6 +296,11 @@ export const app = {
);
},
openSettings: o => {},
+ openServerSettings: (s: Server | null) => {
+ console.log(
+ `[FUNCTIONS] Tried to run uninitialised function openServerSettings (args: ${s})`,
+ );
+ },
setMessageBoxInput: t => {},
setReplyingMessages: (m: ReplyingMessage[]) => {
console.log(
diff --git a/src/Modals.tsx b/src/Modals.tsx
index 4eb1027..935d50b 100644
--- a/src/Modals.tsx
+++ b/src/Modals.tsx
@@ -5,7 +5,7 @@ import {observer} from 'mobx-react-lite';
import ImageViewer from 'react-native-image-zoom-viewer';
import MaterialCommunityIcon from 'react-native-vector-icons/MaterialCommunityIcons';
-import {API, Channel, User} from 'revolt.js';
+import {API, Channel, Server, User} from 'revolt.js';
import {app, client, openUrl, setFunction} from './Generic';
import {currentTheme} from './Theme';
@@ -19,6 +19,7 @@ import {
ReportSheet,
ServerInfoSheet,
ServerInviteSheet,
+ ServerSettingsSheet,
SettingsSheet,
StatusSheet,
} from './components/sheets/';
@@ -28,6 +29,7 @@ export const Modals = observer(() => {
i: null as any,
});
const [settingsVisibility, setSettingsVisibility] = React.useState(false);
+ const [serverSettingsServer, setServerSettingsServer] = React.useState(null as Server | null)
const [inviteServer, setInviteServer] = React.useState({
inviteServer: null,
inviteServerCode: '',
@@ -47,6 +49,9 @@ export const Modals = observer(() => {
setFunction('openSettings', async (o: boolean) => {
setSettingsVisibility(o);
});
+ setFunction('openServerSettings', async (s: Server | null) => {
+ setServerSettingsServer(s);
+ });
setFunction('openInvite', async (i: string) => {
try {
let community = await client.fetchInvite(i);
@@ -162,6 +167,13 @@ export const Modals = observer(() => {
bot={inviteBot!}
/>
+ setServerSettingsServer(null)}>
+ setServerSettingsServer(null)} />
+
>
);
});
diff --git a/src/Theme.tsx b/src/Theme.tsx
index 1502336..4315783 100644
--- a/src/Theme.tsx
+++ b/src/Theme.tsx
@@ -294,6 +294,15 @@ function refreshStyles() {
textAlign: 'center',
marginTop: '30%',
},
+ serverSettingsInitials: {
+ borderRadius: 5000,
+ justifyContent: 'center',
+ alignItems: 'center',
+ width: 80,
+ height: 80,
+ backgroundColor: currentTheme.backgroundSecondary,
+ overflow: 'hidden',
+ },
serverIcon: {
width: 48,
height: 48,
diff --git a/src/components/sheets/ServerInfoSheet.tsx b/src/components/sheets/ServerInfoSheet.tsx
index f47d5f4..d212e7c 100644
--- a/src/components/sheets/ServerInfoSheet.tsx
+++ b/src/components/sheets/ServerInfoSheet.tsx
@@ -119,40 +119,55 @@ export const ServerInfoSheet = observer(() => {
alignItems: 'center',
justifyContent: 'center',
}}>
+ {server.havePermission("ManageServer") ? ( {
+ app.openServerSettings(server);
+ }}>
+
+
+
+ Server Settings
+ ) : null}
{app.settings.get('ui.showDeveloperFeatures') ? (
) : null}
{server.owner !== client.user?._id ? (
<>
- {
- app.openServer();
+ {
+ app.openReportMenu({object: server, type: 'Server'});
app.openServerContextMenu(null);
- server.delete();
}}>
- Leave Server
+ Report Server
{
- app.openReportMenu({object: server, type: 'Server'});
+ key={'server-ctx-menu-leave'}
+ onPress={async () => {
+ app.openServer();
+ app.openServerContextMenu(null);
+ server.delete();
}}>
- Report Server
+ Leave Server
>
) : null}
diff --git a/src/components/sheets/ServerSettingsSheet.tsx b/src/components/sheets/ServerSettingsSheet.tsx
new file mode 100644
index 0000000..b40deb0
--- /dev/null
+++ b/src/components/sheets/ServerSettingsSheet.tsx
@@ -0,0 +1,340 @@
+import React from 'react';
+import {Pressable, ScrollView, View} from 'react-native';
+import {observer} from 'mobx-react-lite';
+
+import Clipboard from '@react-native-clipboard/clipboard';
+import FastImage from 'react-native-fast-image';
+import MaterialCommunityIcon from 'react-native-vector-icons/MaterialCommunityIcons';
+import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
+
+import {Server} from 'revolt.js';
+
+import {app, client} from '../../Generic';
+import {MAX_SIDE_HQ} from '../../lib/consts';
+import {Setting, SettingsSection} from '../../lib/types';
+import {currentTheme, styles} from '../../Theme';
+import {ContextButton, InputWithButton, Link, Text} from '../common/atoms';
+import {GapView} from '../layout';
+const Image = FastImage;
+
+export const ServerSettingsSheet = observer(
+ ({server, setState}: {server: Server; setState: Function}) => {
+ const [renderCount, rerender] = React.useState(0);
+ const [section, setSection] = React.useState(null as SettingsSection);
+
+ const iconURL = React.useMemo(() => server.generateIconURL(), []);
+ const initials = React.useMemo(() => {
+ let i = '';
+ for (const word of server.name.split(' ')) {
+ i += word.charAt(0);
+ }
+ return i;
+ }, []);
+
+ // React.useEffect(() => {
+ // async function getAuthInfo() {
+ // const e = await client.api.get('/auth/account/');
+ // const m = await client.api.get('/auth/mfa/');
+ // const s = await client.api.get('/auth/session/all');
+ // setAuthInfo({
+ // email: e.email,
+ // mfaEnabled: m.totp_mfa ?? m.security_key_mfa ?? false,
+ // sessions: s,
+ // });
+ // }
+ // getAuthInfo();
+ // }, []);
+
+ return (
+
+ {section == null ? (
+ {
+ setState();
+ }}>
+
+
+ Close
+
+
+ ) : (
+ {
+ setSection(null);
+ }}>
+
+
+ Back
+
+
+ )}
+
+ {section == null ? (
+ <>
+
+ {iconURL ? (
+
+ ) : (
+
+
+ {initials}
+
+
+ )}
+
+ {server.name}
+
+ General
+ {
+ setSection('overview');
+ }}>
+
+
+
+ Overview
+
+ {
+ setSection('overview');
+ }}>
+
+
+
+ Channels
+
+ Customisation
+ {
+ setSection('roles');
+ }}>
+
+
+
+ Roles
+
+ {
+ setSection('emoji');
+ }}>
+
+
+
+ Emoji
+
+ User Management
+ {
+ setSection('members');
+ }}>
+
+
+
+ Members
+
+ {
+ setSection('invites');
+ }}>
+
+
+
+ Invites
+
+ {
+ setSection('bans');
+ }}>
+
+
+
+ Bans
+
+ {server.owner === client.user?._id ? (
+ {
+ console.log('sussy');
+ }}>
+
+
+
+ Delete Server
+
+ ) : null}
+ >
+ ) : section === 'overview' ? (
+
+ Overview
+
+ Server name
+
+ {
+ server.edit({
+ name: v,
+ });
+ }}
+ buttonContents={{
+ type: 'icon',
+ name: 'save',
+ pack: 'regular',
+ }}
+ backgroundColor={currentTheme.backgroundSecondary}
+ skipIfSame
+ cannotBeEmpty
+ emptyError={'Server names cannot be empty!'}
+ />
+
+
+ Server description
+
+
+
+ Server descriptions support Markdown formatting.
+
+
+
+
+ {
+ server.edit({
+ description: v,
+ });
+ }}
+ buttonContents={{type: 'string', content: 'Set description'}}
+ backgroundColor={currentTheme.backgroundSecondary}
+ skipIfSame
+ // @ts-expect-error this is passed down to the TextInput
+ multiline
+ extraStyles={{
+ container: {
+ flexDirection: 'column',
+ alignItems: 'flex-start',
+ },
+ input: {width: '100%'},
+ button: {marginHorizontal: 0},
+ }}
+ />
+
+ ) : section === 'info' ? (
+ <>
+ About
+ >
+ ) : null}
+
+
+ );
+ },
+);
diff --git a/src/components/sheets/index.tsx b/src/components/sheets/index.tsx
index 63d575c..e7270c7 100644
--- a/src/components/sheets/index.tsx
+++ b/src/components/sheets/index.tsx
@@ -6,5 +6,6 @@ export {ProfileSheet} from './ProfileSheet';
export {ReportSheet} from './ReportSheet';
export {ServerInfoSheet} from './ServerInfoSheet';
export {ServerInviteSheet} from './ServerInviteSheet';
+export {ServerSettingsSheet} from './ServerSettingsSheet';
export {SettingsSheet} from './SettingsSheet';
export {StatusSheet} from './StatusSheet';
diff --git a/src/lib/consts.ts b/src/lib/consts.ts
index 8126763..6484c24 100644
--- a/src/lib/consts.ts
+++ b/src/lib/consts.ts
@@ -34,6 +34,9 @@ export const DEFAULT_API_URL = 'https://api.revolt.chat'; // TODO: switch to htt
// default max side param - used to specify the size of images
export const DEFAULT_MAX_SIDE = '128';
+// higher max side param - used for the server settings menu
+export const MAX_SIDE_HQ = "1024";
+
// default amount of messages to load
export const DEFAULT_MESSAGE_LOAD_COUNT = 50;