mirror of
https://github.com/urbit/shrub.git
synced 2024-12-25 04:52:06 +03:00
Merge pull request #3808 from tylershuster/add-group
launch: adds new group button
This commit is contained in:
commit
c485f0827e
@ -10,7 +10,10 @@ import Tiles from './components/tiles';
|
||||
import Tile from './components/tiles/tile';
|
||||
import Welcome from './components/welcome';
|
||||
import Groups from './components/Groups';
|
||||
import ModalButton from './components/ModalButton';
|
||||
import { writeText } from '~/logic/lib/util';
|
||||
import { NewGroup } from "~/views/landscape/components/NewGroup";
|
||||
import { JoinGroup } from "~/views/landscape/components/JoinGroup";
|
||||
|
||||
const ScrollbarLessBox = styled(Box)`
|
||||
scrollbar-width: none !important;
|
||||
@ -39,19 +42,18 @@ export default function LaunchApp(props) {
|
||||
pt={0}
|
||||
>
|
||||
<Tile
|
||||
bg="transparent"
|
||||
color="green"
|
||||
bg="white"
|
||||
color="scales.black20"
|
||||
to="/~landscape/home"
|
||||
p={0}
|
||||
>
|
||||
<Box p={2} height='100%' width='100%' bg='green'>
|
||||
<Box p={2} height='100%' width='100%' bg='scales.black20'>
|
||||
<Row alignItems='center'>
|
||||
<Icon
|
||||
color="white"
|
||||
// fill="rgba(0,0,0,0)"
|
||||
icon="Boot"
|
||||
color="black"
|
||||
icon="Mail"
|
||||
/>
|
||||
<Text ml="1" mt='1px' color="white">DMs + Drafts</Text>
|
||||
<Text ml="1" mt='1px' color="black">DMs + Drafts</Text>
|
||||
</Row>
|
||||
</Box>
|
||||
</Tile>
|
||||
@ -62,7 +64,23 @@ export default function LaunchApp(props) {
|
||||
location={props.userLocation}
|
||||
weather={props.weather}
|
||||
/>
|
||||
<Box display={["none", "block"]} width="100%" gridColumn="1 / -1"></Box>
|
||||
<ModalButton
|
||||
icon="Plus"
|
||||
bg="blue"
|
||||
color="#fff"
|
||||
text="Join a Group"
|
||||
style={{ gridColumnStart: 1 }}
|
||||
>
|
||||
<JoinGroup {...props} />
|
||||
</ModalButton>
|
||||
<ModalButton
|
||||
icon="CreateGroup"
|
||||
bg="green"
|
||||
color="#fff"
|
||||
text="Create a Group"
|
||||
>
|
||||
<NewGroup {...props} />
|
||||
</ModalButton>
|
||||
<Groups unreads={props.unreads} groups={props.groups} associations={props.associations} />
|
||||
</Box>
|
||||
</ScrollbarLessBox>
|
||||
|
@ -34,7 +34,7 @@ export default function Groups(props: GroupsProps & Parameters<typeof Box>[0]) {
|
||||
|
||||
return (
|
||||
<>
|
||||
{groups.map((group) => {
|
||||
{groups.map((group, index) => {
|
||||
const path = group?.["group-path"];
|
||||
const unreadCount = (["chat", "graph"] as const)
|
||||
.map(getUnreads(path))
|
||||
@ -42,6 +42,7 @@ export default function Groups(props: GroupsProps & Parameters<typeof Box>[0]) {
|
||||
.reduce(f.add, 0);
|
||||
return (
|
||||
<Group
|
||||
first={index === 0}
|
||||
unreads={unreadCount}
|
||||
path={group?.["group-path"]}
|
||||
title={group.metadata.title}
|
||||
@ -56,11 +57,12 @@ interface GroupProps {
|
||||
path: string;
|
||||
title: string;
|
||||
unreads: number;
|
||||
first: boolean;
|
||||
}
|
||||
function Group(props: GroupProps) {
|
||||
const { path, title, unreads } = props;
|
||||
const { path, title, unreads, first = false } = props;
|
||||
return (
|
||||
<Tile to={`/~landscape${path}`}>
|
||||
<Tile to={`/~landscape${path}`} gridColumnStart={first ? '1' : null}>
|
||||
<Col height="100%" justifyContent="space-between">
|
||||
<Text>{title}</Text>
|
||||
{unreads > 0 &&
|
||||
|
@ -0,0 +1,81 @@
|
||||
import React, { useState, useEffect } from "react"
|
||||
import { Box, Button, Icon, Text } from "@tlon/indigo-react"
|
||||
import { NewGroup } from "~/views/landscape/components/NewGroup";
|
||||
import { JoinGroup } from "~/views/landscape/components/JoinGroup";
|
||||
|
||||
const ModalButton = (props) => {
|
||||
const {
|
||||
childen,
|
||||
icon,
|
||||
text,
|
||||
bg,
|
||||
color,
|
||||
...rest
|
||||
} = props;
|
||||
const [modalShown, setModalShown] = useState(false);
|
||||
|
||||
const handleKeyDown = (event) => {
|
||||
if (event.key === 'Escape') {
|
||||
setModalShown(false);
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('keydown', handleKeyDown);
|
||||
};
|
||||
}, [modalShown]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{modalShown && (
|
||||
<Box
|
||||
backgroundColor='scales.black30'
|
||||
left="0px"
|
||||
top="0px"
|
||||
width="100%"
|
||||
height="100%"
|
||||
zIndex={4}
|
||||
position="fixed"
|
||||
display="flex"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
onClick={() => setModalShown(false)}
|
||||
>
|
||||
<Box
|
||||
maxWidth="500px"
|
||||
width="100%"
|
||||
bg="white"
|
||||
borderRadius={2}
|
||||
border={[0, 1]}
|
||||
borderColor={["washedGray", "washedGray"]}
|
||||
onClick={e => e.stopPropagation()}
|
||||
display="flex"
|
||||
alignItems="stretch"
|
||||
flexDirection="column"
|
||||
>
|
||||
{props.children}
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
<Box
|
||||
onClick={() => setModalShown(true)}
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
cursor="pointer"
|
||||
bg={bg}
|
||||
p={2}
|
||||
borderRadius={2}
|
||||
boxShadow="0 0 0px 1px inset"
|
||||
color="scales.black20"
|
||||
{...rest}
|
||||
>
|
||||
<Icon icon={props.icon} mr={2} color={color}></Icon><Text color={color}>{props.text}</Text>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default ModalButton;
|
@ -23,7 +23,7 @@ const routeList = defaultApps.map(a => `/~${a}`);
|
||||
|
||||
export default class Tile extends React.Component {
|
||||
render() {
|
||||
const { bg, to, href, p, boxShadow, ...props } = this.props;
|
||||
const { bg, to, href, p, boxShadow, gridColumnStart, ...props } = this.props;
|
||||
|
||||
let childElement = (
|
||||
<Box p={typeof p === 'undefined' ? 2 : p} width="100%" height="100%">
|
||||
@ -32,7 +32,7 @@ export default class Tile extends React.Component {
|
||||
);
|
||||
|
||||
if (to) {
|
||||
if (routeList.indexOf(to) !== -1 || to === '/~landscape/home' || to === '/~profile' || to.startsWith('/~landscape/ship')) {
|
||||
if (routeList.indexOf(to) !== -1 || to === '/~profile' || to.startsWith('/~landscape/')) {
|
||||
childElement= (<Link to={to}>{childElement}</Link>);
|
||||
} else {
|
||||
childElement= (<a href={to}>{childElement}</a>);
|
||||
@ -48,6 +48,7 @@ export default class Tile extends React.Component {
|
||||
bg={bg || "white"}
|
||||
color={props?.color || 'scales.black20'}
|
||||
boxShadow={boxShadow || '0 0 0px 1px inset'}
|
||||
style={{ gridColumnStart }}
|
||||
>
|
||||
<Box
|
||||
{...props}
|
||||
|
@ -52,7 +52,7 @@ export class OmniboxResult extends Component {
|
||||
} else if (icon === 'profile') {
|
||||
graphic = <Sigil color={sigilFill} classes='dib flex-shrink-0 v-mid mr2' ship={window.ship} size={16} icon padded />;
|
||||
} else if (icon === 'home') {
|
||||
graphic = <Icon display='inline-block' verticalAlign='middle' icon='Boot' mr='2' size='16px' color={iconFill} />;
|
||||
graphic = <Icon display='inline-block' verticalAlign='middle' icon='Mail' mr='2' size='16px' color={iconFill} />;
|
||||
} else if (icon === 'notifications') {
|
||||
graphic = <Icon display='inline-block' verticalAlign='middle' icon='Inbox' mr='2' size='16px' color={iconFill} />;
|
||||
} else {
|
||||
|
@ -118,7 +118,7 @@ export function GroupSwitcher(props: {
|
||||
mr={2}
|
||||
color="gray"
|
||||
display="block"
|
||||
icon="Boot"
|
||||
icon="Mail"
|
||||
/>
|
||||
<Text>DMs + Drafts</Text>
|
||||
</GroupSwitcherItem>}
|
||||
@ -127,11 +127,11 @@ export function GroupSwitcher(props: {
|
||||
associations={props.associations}
|
||||
/>
|
||||
<GroupSwitcherItem to="/~landscape/new">
|
||||
<Icon mr="2" color="gray" icon="Plus" />
|
||||
<Icon mr="2" color="gray" icon="CreateGroup" />
|
||||
<Text> New Group</Text>
|
||||
</GroupSwitcherItem>
|
||||
<GroupSwitcherItem to="/~landscape/join">
|
||||
<Icon mr="2" color="gray" icon="Boot" />
|
||||
<Icon mr="2" color="gray" icon="Plus" />
|
||||
<Text> Join Group</Text>
|
||||
</GroupSwitcherItem>
|
||||
{workspace.type === "group" && (
|
||||
|
@ -79,8 +79,8 @@ export function JoinGroup(props: JoinGroupProps & RouteComponentProps) {
|
||||
);
|
||||
|
||||
return (
|
||||
<Body>
|
||||
<Col maxWidth="300px" overflowY="auto" p="3">
|
||||
<>
|
||||
<Col overflowY="auto" p="3">
|
||||
<Box mb={3}>
|
||||
<Text fontWeight="bold">Join Group</Text>
|
||||
</Box>
|
||||
@ -103,6 +103,6 @@ export function JoinGroup(props: JoinGroupProps & RouteComponentProps) {
|
||||
</Form>
|
||||
</Formik>
|
||||
</Col>
|
||||
</Body>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -78,8 +78,8 @@ export function NewGroup(props: NewGroupProps & RouteComponentProps) {
|
||||
);
|
||||
|
||||
return (
|
||||
<Body>
|
||||
<Col maxWidth="300px" overflowY="auto" p="3">
|
||||
<>
|
||||
<Col overflowY="auto" p="3">
|
||||
<Box mb={3}>
|
||||
<Text fontWeight="bold">New Group</Text>
|
||||
</Box>
|
||||
@ -112,6 +112,6 @@ export function NewGroup(props: NewGroupProps & RouteComponentProps) {
|
||||
</Form>
|
||||
</Formik>
|
||||
</Col>
|
||||
</Body>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ import { NewGroup } from './components/NewGroup';
|
||||
import { JoinGroup } from './components/JoinGroup';
|
||||
|
||||
import { cite } from '~/logic/lib/util';
|
||||
import { Body } from '../components/Body';
|
||||
import { Box } from '@tlon/indigo-react';
|
||||
|
||||
|
||||
type LandscapeProps = StoreState & {
|
||||
@ -95,12 +97,16 @@ export default class Landscape extends Component<LandscapeProps, {}> {
|
||||
<Route path="/~landscape/new"
|
||||
render={routeProps=> {
|
||||
return (
|
||||
<NewGroup
|
||||
groups={props.groups}
|
||||
contacts={props.contacts}
|
||||
api={props.api}
|
||||
{...routeProps}
|
||||
/>
|
||||
<Body>
|
||||
<Box maxWidth="300px">
|
||||
<NewGroup
|
||||
groups={props.groups}
|
||||
contacts={props.contacts}
|
||||
api={props.api}
|
||||
{...routeProps}
|
||||
/>
|
||||
</Box>
|
||||
</Body>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
@ -115,13 +121,17 @@ export default class Landscape extends Component<LandscapeProps, {}> {
|
||||
const { ship, name } = routeProps.match.params;
|
||||
const autojoin = ship && name ? `${ship}/${name}` : null;
|
||||
return (
|
||||
<JoinGroup
|
||||
groups={props.groups}
|
||||
contacts={props.contacts}
|
||||
api={props.api}
|
||||
autojoin={autojoin}
|
||||
{...routeProps}
|
||||
/>
|
||||
<Body>
|
||||
<Box maxWidth="300px">
|
||||
<JoinGroup
|
||||
groups={props.groups}
|
||||
contacts={props.contacts}
|
||||
api={props.api}
|
||||
autojoin={autojoin}
|
||||
{...routeProps}
|
||||
/>
|
||||
</Box>
|
||||
</Body>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
Loading…
Reference in New Issue
Block a user