diff --git a/src/components/common/settings/sections/server/InviteSettingsSection.tsx b/src/components/common/settings/sections/server/InviteSettingsSection.tsx new file mode 100644 index 0000000..949311a --- /dev/null +++ b/src/components/common/settings/sections/server/InviteSettingsSection.tsx @@ -0,0 +1,74 @@ +import React, {useEffect, useState} from 'react'; +import {Pressable, View} from 'react-native'; +import {observer} from 'mobx-react-lite'; + +import MaterialIcon from 'react-native-vector-icons/MaterialIcons'; + +import {API, Server} from 'revolt.js'; + +import {currentTheme, styles} from '../../../../../Theme'; +import {Text} from '../../../atoms'; + +export const InviteSettingsSection = observer(({server}: {server: Server}) => { + const [reload, triggerReload] = useState(0); + const [invites, setInvites] = useState(null as API.Invite[] | null); + useEffect(() => { + async function fetchInvites() { + const i = await server.fetchInvites(); + setInvites(i); + } + + fetchInvites(); + }, [server, reload]); + + return ( + <> + Invites + {invites ? ( + invites.length ? ( + invites.map(i => ( + + + + {i._id} + + + @{i.creator} - #{i.channel} + + + {i._id.length === 8 ? ( + { + server.client.deleteInvite(i._id); + triggerReload(reload + 1); + }}> + + + + + ) : null} + + )) + ) : ( + No invites + ) + ) : ( + Fetching invites... + )} + + ); +}); diff --git a/src/components/common/settings/sections/server/OverviewSettingsSection.tsx b/src/components/common/settings/sections/server/OverviewSettingsSection.tsx new file mode 100644 index 0000000..c11c416 --- /dev/null +++ b/src/components/common/settings/sections/server/OverviewSettingsSection.tsx @@ -0,0 +1,92 @@ +import React from 'react'; +import {View} from 'react-native'; +import {observer} from 'mobx-react-lite'; + +import {Server} from 'revolt.js'; + +import {currentTheme} from '../../../../../Theme'; +import {GapView} from '../../../../layout'; +import {InputWithButton, Link, Text} from '../../../atoms'; + +export const OverviewSettingsSection = observer( + ({server}: {server: Server}) => { + return ( + <> + 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}, + }} + /> + + System messages + + When members join/leave or are kicked/banned, you can receive + messages. (not final copy) + + + new {server.system_messages?.user_joined} leave{' '} + {server.system_messages?.user_left} kick{' '} + {server.system_messages?.user_kicked} ban{' '} + {server.system_messages?.user_banned} + + + ); + }, +); diff --git a/src/components/common/settings/sections/server/RoleSettingsSection.tsx b/src/components/common/settings/sections/server/RoleSettingsSection.tsx new file mode 100644 index 0000000..1eb40f9 --- /dev/null +++ b/src/components/common/settings/sections/server/RoleSettingsSection.tsx @@ -0,0 +1,122 @@ +import React from 'react'; +import {Pressable, View} from 'react-native'; +import {observer} from 'mobx-react-lite'; + +import MaterialIcon from 'react-native-vector-icons/MaterialIcons'; + +import {Server} from 'revolt.js'; + +import {SettingsSection} from '../../../../../lib/types'; +import {currentTheme, styles} from '../../../../../Theme'; +import {GapView} from '../../../../layout'; +import {Text} from '../../../atoms'; + +export const RoleSettingsSection = observer( + ({server, callback}: {server: Server; callback: Function}) => { + const [subsection, setSubsection] = React.useState(null as SettingsSection); + + return ( + <> + { + subsection ? setSubsection(null) : callback(); + }}> + + + Back + + + {subsection ? ( + <> + + {server.roles![subsection].name} + + {subsection} + + Rank + {/* { + setRankValue(v); + }} + /> */} + {server.roles![subsection].rank} + + Permissions + {server.roles![subsection].permissions.a} + + Colour + {server.roles![subsection].colour} + + ) : ( + <> + Roles + {server.orderedRoles.map(r => ( + + + + {r.name} + + {r.id} + + { + setSubsection(r.id); + }}> + + + + + + ))} + + )} + + ); + }, +); diff --git a/src/components/common/settings/sections/server/index.ts b/src/components/common/settings/sections/server/index.ts new file mode 100644 index 0000000..7255f3b --- /dev/null +++ b/src/components/common/settings/sections/server/index.ts @@ -0,0 +1,3 @@ +export {InviteSettingsSection} from './InviteSettingsSection'; +export {OverviewSettingsSection} from './OverviewSettingsSection'; +export {RoleSettingsSection} from './RoleSettingsSection'; diff --git a/src/components/sheets/ServerSettingsSheet.tsx b/src/components/sheets/ServerSettingsSheet.tsx index b39ca73..9916f94 100644 --- a/src/components/sheets/ServerSettingsSheet.tsx +++ b/src/components/sheets/ServerSettingsSheet.tsx @@ -12,7 +12,12 @@ import {app, client} from '../../Generic'; import {MAX_SIDE_HQ} from '../../lib/consts'; import {SettingsSection} from '../../lib/types'; import {currentTheme, styles} from '../../Theme'; -import {ContextButton, InputWithButton, Link, Text} from '../common/atoms'; +import {ContextButton, Text} from '../common/atoms'; +import { + InviteSettingsSection, + RoleSettingsSection, + OverviewSettingsSection, +} from '../common/settings/sections/server'; import {GapView} from '../layout'; const Image = FastImage; @@ -30,20 +35,6 @@ export const ServerSettingsSheet = observer( return i; }, [server.name]); - // 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 !== 'roles' ? ( - )} + ) : 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 === 'roles' ? ( + setSection(null)} + /> + ) : section === 'invites' ? ( + ) : section === 'info' ? ( <> About