From 030d743af9b0aac22609054d88377d00a03c9a0c Mon Sep 17 00:00:00 2001
From: Paul <paulmakles@gmail.com>
Date: Fri, 2 Jul 2021 22:08:03 +0100
Subject: [PATCH] Fix i18n for server settings. Start work on roles. Add
 temporary age gate.

---
 .../navigation/BottomNavigation.tsx           |  18 +++-
 src/pages/channels/Channel.tsx                |  18 +++-
 src/pages/settings/GenericSettings.tsx        |   9 +-
 src/pages/settings/ServerSettings.tsx         |  11 +-
 src/pages/settings/server/Panes.module.scss   |  25 +++--
 src/pages/settings/server/Roles.tsx           | 102 +++++++++---------
 6 files changed, 109 insertions(+), 74 deletions(-)

diff --git a/src/components/navigation/BottomNavigation.tsx b/src/components/navigation/BottomNavigation.tsx
index 00bd0ab..f8f0477 100644
--- a/src/components/navigation/BottomNavigation.tsx
+++ b/src/components/navigation/BottomNavigation.tsx
@@ -5,6 +5,8 @@ import { useSelf } from "../../context/revoltjs/hooks";
 import { useHistory, useLocation } from "react-router";
 import ConditionalLink from "../../lib/ConditionalLink";
 import { Message, Group } from "@styled-icons/boxicons-solid";
+import { LastOpened } from "../../redux/reducers/last_opened";
+import { connectState } from "../../redux/connector";
 
 const NavigationBase = styled.div`
     z-index: 100;
@@ -26,15 +28,23 @@ const Button = styled.a<{ active: boolean }>`
     ` }
 `;
 
-export default function BottomNavigation() {
+interface Props {
+    lastOpened: LastOpened
+}
+
+export function BottomNavigation({ lastOpened }: Props) {
     const user = useSelf();
     const history = useHistory();
     const path = useLocation().pathname;
 
+    const channel_id = lastOpened['home'];
+
     const friendsActive = path.startsWith("/friends");
     const settingsActive = path.startsWith("/settings");
     const homeActive = !(friendsActive || settingsActive);
 
+    // console.info(channel_id);
+
     return (
         <NavigationBase>
             <Button active={homeActive}>
@@ -70,3 +80,9 @@ export default function BottomNavigation() {
         </NavigationBase>
     );
 }
+
+export default connectState(BottomNavigation, state => {
+    return {
+        lastOpened: state.lastOpened
+    }
+});
diff --git a/src/pages/channels/Channel.tsx b/src/pages/channels/Channel.tsx
index 6732f54..c6119eb 100644
--- a/src/pages/channels/Channel.tsx
+++ b/src/pages/channels/Channel.tsx
@@ -1,8 +1,10 @@
 import styled from "styled-components";
-import { useState } from "preact/hooks";
+import { useEffect, useState } from "preact/hooks";
 import ChannelHeader from "./ChannelHeader";
 import { useParams } from "react-router-dom";
 import { MessageArea } from "./messaging/MessageArea";
+import Checkbox from "../../components/ui/Checkbox";
+import Button from "../../components/ui/Button";
 // import { useRenderState } from "../../lib/renderer/Singleton";
 import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
 import MessageBox from "../../components/common/messaging/MessageBox";
@@ -44,6 +46,20 @@ export function Channel({ id }: { id: string }) {
 function TextChannel({ channel }: { channel: Channel }) {
     const [ showMembers, setMembers ] = useState(true);
 
+    if ((channel.channel_type === 'TextChannel' || channel.channel_type === 'Group') && channel.name.includes('nsfw')) {
+        const [ consent, setConsent ] = useState(false);
+        const [ ageGate, setAgeGate ] = useState(false);
+        if (!ageGate) {
+            return (
+                <div style={{ maxWidth: '480px' }}>
+                    <h3>this channel is marked as nsfw</h3>
+                    <Checkbox checked={consent} onChange={v => setConsent(v)}>I am at least 18 years old</Checkbox>
+                    <Button onClick={() => consent && setAgeGate(true)}>view content</Button>
+                </div>
+            )
+        }
+    }
+
     let id = channel._id;
     return <>
         <ChannelHeader channel={channel} toggleSidebar={() => setMembers(!showMembers)} />
diff --git a/src/pages/settings/GenericSettings.tsx b/src/pages/settings/GenericSettings.tsx
index a370060..6b20e0c 100644
--- a/src/pages/settings/GenericSettings.tsx
+++ b/src/pages/settings/GenericSettings.tsx
@@ -13,11 +13,12 @@ import ButtonItem from "../../components/navigation/items/ButtonItem";
 
 interface Props {
     pages: {
-        category?: Children,
-        divider?: boolean,
-        id: string,
+        category?: Children
+        divider?: boolean
+        id: string
         icon: Children
         title: Children
+        hideTitle?: boolean
     }[]
     custom?: Children
     children: Children
@@ -96,7 +97,7 @@ export function GenericSettings({ pages, switchPage, category, custom, children,
             )}
             {(!isTouchscreenDevice || typeof page === "string") && (
                 <div className={styles.content}>
-                    {!isTouchscreenDevice && (
+                    {!isTouchscreenDevice && !(pages.find(x => x.id === page && x.hideTitle)) && (
                         <h1>
                             <Text
                                 id={`app.settings.${category}.${page ?? defaultPage}.title`}
diff --git a/src/pages/settings/ServerSettings.tsx b/src/pages/settings/ServerSettings.tsx
index 5d34d01..2c5148a 100644
--- a/src/pages/settings/ServerSettings.tsx
+++ b/src/pages/settings/ServerSettings.tsx
@@ -34,27 +34,28 @@ export default function ServerSettings() {
                     category: <Category variant="uniform" text={server.name} />, //TOFIX: Just add the server.name as a string, otherwise it makes a duplicate category
                     id: 'overview',
                     icon: <ListUl size={20} />,
-                    title: <Text id="app.settings.channel_pages.overview.title" />
+                    title: <Text id="app.settings.server_pages.overview.title" />
                 },
                 {
                     id: 'members',
                     icon: <Group size={20} />,
-                    title: "Members"
+                    title: <Text id="app.settings.server_pages.members.title" />
                 },
                 {
                     id: 'invites',
                     icon: <Share size={20} />,
-                    title: "Invites"
+                    title: <Text id="app.settings.server_pages.invites.title" />
                 },
                 {
                     id: 'bans',
                     icon: <XSquare size={20} />,
-                    title: "Bans"
+                    title: <Text id="app.settings.server_pages.bans.title" />
                 },
                 {
                     id: 'roles',
                     icon: <ListCheck size={20} />,
-                    title: "Roles"
+                    title: <Text id="app.settings.server_pages.roles.title" />,
+                    hideTitle: true
                 }
             ]}
             children={[
diff --git a/src/pages/settings/server/Panes.module.scss b/src/pages/settings/server/Panes.module.scss
index b34d3b7..fe16fd4 100644
--- a/src/pages/settings/server/Panes.module.scss
+++ b/src/pages/settings/server/Panes.module.scss
@@ -78,16 +78,21 @@
 }
 
 .roles {
-    .overview {
-        height: 85vh; //TOFIX change later
-        display: flex;
-        
-        .list {
-            overflow-y: scroll;
-        }
+    gap: 12px;
+    height: 100%;
+    display: flex;
 
-        .permissions {
-            overflow-y: scroll;
-        }
+    .list {
+        width: 160px;
+        overflow-y: scroll;
+    }
+
+    .permissions {
+        flex-grow: 1;
+        overflow-y: scroll;
+    }
+
+    h2 {
+        margin: 8px 0;
     }
 }
\ No newline at end of file
diff --git a/src/pages/settings/server/Roles.tsx b/src/pages/settings/server/Roles.tsx
index 2db9baf..a411809 100644
--- a/src/pages/settings/server/Roles.tsx
+++ b/src/pages/settings/server/Roles.tsx
@@ -1,4 +1,4 @@
-import Tip from "../../../components/ui/Tip";
+import { Text } from "preact-i18n";
 import styles from './Panes.module.scss';
 import Button from "../../../components/ui/Button";
 import { Servers } from "revolt.js/dist/api/objects";
@@ -7,7 +7,7 @@ import Checkbox from "../../../components/ui/Checkbox";
 import { useContext, useEffect, useState } from "preact/hooks";
 import { AppContext } from "../../../context/revoltjs/RevoltClient";
 import { ChannelPermission, ServerPermission } from "revolt.js/dist/api/permissions";
-import { Styleshare } from "@styled-icons/simple-icons";
+import Tip from "../../../components/ui/Tip";
 
 interface Props {
     server: Servers.Server;
@@ -46,61 +46,57 @@ export function Roles({ server }: Props) {
     return (
         <div className={styles.roles}>
             <Tip warning>This section is under construction.</Tip>
-            <div className={styles.overview}>
-                <div className={styles.list}>
-                    <h2>select role</h2>
-                    { selected }
-                    { keys
-                        .map(id => {
-                            let role: Servers.Role = id === 'default' ? defaultRole : roles[id];
+            <div className={styles.list}>
+                <h1><Text id="app.settings.server_pages.roles.title" /></h1>
+                { keys
+                    .map(id => {
+                        let role: Servers.Role = id === 'default' ? defaultRole : roles[id];
 
-                            return (
-                                <Checkbox checked={selected === id} onChange={selected => selected && setSelected(id)}>
-                                    { role.name }
-                                </Checkbox>
-                            )
-                        })
-                    }
-                    <Button disabled={selected === 'default'} error onClick={() => {
-                        setSelected('default');
-                        client.servers.deleteRole(server._id, selected);
-                    }}>delete role</Button><br/>
-                    <InputBox placeholder="role name" value={name} onChange={e => setName(e.currentTarget.value)} />
-                    <Button contrast onClick={() => {
-                        client.servers.createRole(server._id, name);
-                    }}>create</Button>
-                </div>
-                <div className={styles.permissions}>
-                    <h2>serverm permmissions</h2>
-                    { Object.keys(ServerPermission)
-                        .map(perm => {
-                            let value = ServerPermission[perm as keyof typeof ServerPermission];
+                        return (
+                            <Checkbox checked={selected === id} onChange={selected => selected && setSelected(id)}>
+                                { role.name }
+                            </Checkbox>
+                        )
+                    })
+                }
+                <Button disabled={selected === 'default'} error onClick={() => {
+                    setSelected('default');
+                    client.servers.deleteRole(server._id, selected);
+                }}>delete role</Button><br/>
+                <InputBox placeholder="role name" value={name} onChange={e => setName(e.currentTarget.value)} />
+                <Button contrast onClick={() => {
+                    client.servers.createRole(server._id, name);
+                }}>create</Button>
+            </div>
+            <div className={styles.permissions}>
+                <h2>{ selectedRole.name }</h2>
+                { Object.keys(ServerPermission)
+                    .map(perm => {
+                        let value = ServerPermission[perm as keyof typeof ServerPermission];
 
-                            return (
-                                <Checkbox checked={(p[0] & value) > 0} onChange={c => setPerm([ c ? (p[0] | value) : (p[0] ^ value), p[1] ])}>
-                                    { perm }
-                                </Checkbox>
-                            )
-                        })
-                    }
-                    <h2>channel permmissions</h2>
-                    { Object.keys(ChannelPermission)
-                        .map(perm => {
-                            let value = ChannelPermission[perm as keyof typeof ChannelPermission];
+                        return (
+                            <Checkbox checked={(p[0] & value) > 0} onChange={c => setPerm([ c ? (p[0] | value) : (p[0] ^ value), p[1] ])}>
+                                { perm }
+                            </Checkbox>
+                        )
+                    })
+                }
+                <h2>channel permmissions</h2>
+                { Object.keys(ChannelPermission)
+                    .map(perm => {
+                        let value = ChannelPermission[perm as keyof typeof ChannelPermission];
 
-                            return (
-                                <Checkbox checked={((p[1] >>> 0) & value) > 0} onChange={c => setPerm([ p[0], c ? (p[1] | value) : (p[1] ^ value) ])}>
-                                    { perm }
-                                </Checkbox>
-                            )
-                        })
-                    }
-                    <Button contrast onClick={() => {
-                        client.servers.setPermissions(server._id, selected, { server: p[0], channel: p[1] });
-                    }}>click here to save permissions for role</Button>
-                </div>
+                        return (
+                            <Checkbox checked={((p[1] >>> 0) & value) > 0} onChange={c => setPerm([ p[0], c ? (p[1] | value) : (p[1] ^ value) ])}>
+                                { perm }
+                            </Checkbox>
+                        )
+                    })
+                }
+                <Button contrast onClick={() => {
+                    client.servers.setPermissions(server._id, selected, { server: p[0], channel: p[1] });
+                }}>click here to save permissions for role</Button>
             </div>
-            
         </div>
     );
 }
-- 
GitLab