add databinding for editor actions and message

This commit is contained in:
41666 2021-07-05 21:35:53 -05:00
parent 67fac31ab4
commit b0c8b2378b
7 changed files with 57 additions and 16 deletions

View file

@ -94,18 +94,27 @@ const StyledTextarea = styled.textarea`
export const MultilineTextInput = ( export const MultilineTextInput = (
props: TextInputProps<HTMLTextAreaElement> & { rows?: number } props: TextInputProps<HTMLTextAreaElement> & { rows?: number }
) => { ) => {
const { ...rest } = props; const { children, ...rest } = props;
const [value, setValue] = React.useState(String(props.value)); const [value, setValue] = React.useState(String(props.value));
const rows = Math.min(10, Math.max(props.rows || 2, value.split(/\r?\n/).length)); const rows = React.useMemo(
() => Math.min(10, Math.max(props.rows || 2, value.split(/\r?\n/).length)),
[value]
);
React.useEffect(() => {
setValue(String(props.value));
}, [props.value]);
return ( return (
<StyledTextarea <StyledTextarea
{...rest} {...rest}
rows={rows} rows={rows}
value={value}
onChange={(eventData) => { onChange={(eventData) => {
setValue(eventData.target.value); setValue(eventData.target.value);
props.onChange?.(eventData); props.onChange?.(eventData);
}} }}
/> >
{value}
</StyledTextarea>
); );
}; };

View file

@ -2,9 +2,9 @@ import { palette } from '@roleypoly/design-system/atoms/colors';
import { fontCSS } from '@roleypoly/design-system/atoms/fonts'; import { fontCSS } from '@roleypoly/design-system/atoms/fonts';
import styled, { createGlobalStyle } from 'styled-components'; import styled, { createGlobalStyle } from 'styled-components';
export const Content = styled.div<{ small?: boolean }>` export const Content = styled.div<{ small?: boolean; double?: boolean }>`
margin: 0 auto; margin: 0 auto;
margin-top: 50px; margin-top: ${(props) => (props.double ? '100px' : '50px')};
width: ${(props) => (props.small ? '960px' : '1024px')}; width: ${(props) => (props.small ? '960px' : '1024px')};
max-width: 98vw; max-width: 98vw;
max-height: calc(100vh - 50px); max-height: calc(100vh - 50px);

View file

@ -11,6 +11,7 @@ export type AppShellProps = {
user?: DiscordUser; user?: DiscordUser;
showFooter?: boolean; showFooter?: boolean;
small?: boolean; small?: boolean;
double?: boolean;
activeGuildId?: string | null; activeGuildId?: string | null;
guilds?: GuildSlug[]; guilds?: GuildSlug[];
recentGuilds?: string[]; recentGuilds?: string[];
@ -56,7 +57,9 @@ export const AppShell = (props: AppShellProps) => (
)} )}
<OptionallyScroll shouldScroll={!props.skeleton}> <OptionallyScroll shouldScroll={!props.skeleton}>
<> <>
<Content small={props.small}>{props.children}</Content> <Content small={props.small} double={props.double}>
{props.children}
</Content>
{props.showFooter && <Footer />} {props.showFooter && <Footer />}
</> </>
</OptionallyScroll> </OptionallyScroll>

View file

@ -1,4 +1,8 @@
import { palette } from '@roleypoly/design-system/atoms/colors';
import { FaderOpacity } from '@roleypoly/design-system/atoms/fader';
import { Space } from '@roleypoly/design-system/atoms/space'; import { Space } from '@roleypoly/design-system/atoms/space';
import { MultilineTextInput } from '@roleypoly/design-system/atoms/text-input';
import { AmbientLarge, LargeText } from '@roleypoly/design-system/atoms/typography';
import { PickerCategory } from '@roleypoly/design-system/molecules/picker-category'; import { PickerCategory } from '@roleypoly/design-system/molecules/picker-category';
import { ServerMasthead } from '@roleypoly/design-system/molecules/server-masthead'; import { ServerMasthead } from '@roleypoly/design-system/molecules/server-masthead';
import { SecondaryEditing } from '@roleypoly/design-system/organisms/masthead'; import { SecondaryEditing } from '@roleypoly/design-system/organisms/masthead';
@ -7,11 +11,11 @@ import {
Container, Container,
MessageBox, MessageBox,
} from '@roleypoly/design-system/organisms/role-picker/RolePicker.styled'; } from '@roleypoly/design-system/organisms/role-picker/RolePicker.styled';
import { ReactifyNewlines } from '@roleypoly/misc-utils/ReactifyNewlines';
import { Category, CategoryType, PresentableGuild, Role } from '@roleypoly/types'; import { Category, CategoryType, PresentableGuild, Role } from '@roleypoly/types';
import deepEqual from 'deep-equal'; import deepEqual from 'deep-equal';
import { sortBy } from 'lodash'; import { sortBy } from 'lodash';
import React from 'react'; import React from 'react';
import { GoEyeClosed } from 'react-icons/go';
export type EditorShellProps = { export type EditorShellProps = {
guild: PresentableGuild; guild: PresentableGuild;
@ -23,6 +27,10 @@ export type EditorShellProps = {
export const EditorShell = (props: EditorShellProps) => { export const EditorShell = (props: EditorShellProps) => {
const [guild, setGuild] = React.useState<PresentableGuild>(props.guild); const [guild, setGuild] = React.useState<PresentableGuild>(props.guild);
React.useEffect(() => {
setGuild(props.guild);
}, [props.guild]);
const reset = () => { const reset = () => {
setGuild(props.guild); setGuild(props.guild);
}; };
@ -50,14 +58,33 @@ export const EditorShell = (props: EditorShellProps) => {
return ( return (
<> <>
<SecondaryEditing showReset={hasChanges} guild={props.guild.guild} /> <SecondaryEditing
<Container style={{ marginTop: 90 }}> showReset={hasChanges}
<Space /> guild={props.guild.guild}
onReset={reset}
onSubmit={() => props.onGuildChange?.(guild)}
/>
<Container style={{ marginTop: 95 }}>
<ServerMasthead guild={props.guild.guild} editable={false} /> <ServerMasthead guild={props.guild.guild} editable={false} />
<Space /> <Space />
<MessageBox> <MessageBox>
<ReactifyNewlines>{props.guild.data.message}</ReactifyNewlines> <LargeText>Server Message</LargeText>
<MultilineTextInput
rows={2}
value={guild.data.message}
onChange={(event) => onMessageChange(event.target.value)}
placeholder={`Hey friend from ${guild.guild.name}! Pick your roles!`}
>
{guild.data.message}
</MultilineTextInput>
<AmbientLarge style={{ display: 'flex', color: palette.taupe600 }}>
Shows a message to your server members.
<FaderOpacity isVisible={guild.data.message.trim().length === 0}>
&nbsp;Since the message is empty, this won't show up.&nbsp;&nbsp;&nbsp;
<GoEyeClosed style={{ position: 'relative', top: 2 }} />
</FaderOpacity>
</AmbientLarge>
</MessageBox> </MessageBox>
<Space /> <Space />

View file

@ -97,7 +97,7 @@ export const SecondaryBase = styled(MastheadBase)`
background-color: ${palette.taupe300}; background-color: ${palette.taupe300};
z-index: 99; z-index: 99;
padding: 0 15px; padding: 0 15px;
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2); box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.05);
`; `;
export const IconHolder = styled.div` export const IconHolder = styled.div`

View file

@ -15,6 +15,8 @@ import {
type SecondaryEditingProps = { type SecondaryEditingProps = {
guild: GuildSlug; guild: GuildSlug;
showReset: boolean; showReset: boolean;
onReset?: () => void;
onSubmit?: () => void;
}; };
export const SecondaryEditing = (props: SecondaryEditingProps) => ( export const SecondaryEditing = (props: SecondaryEditingProps) => (
@ -30,12 +32,12 @@ export const SecondaryEditing = (props: SecondaryEditingProps) => (
</MastheadLeft> </MastheadLeft>
<MastheadRight> <MastheadRight>
<FaderOpacity isVisible={props.showReset}> <FaderOpacity isVisible={props.showReset}>
<Button size="small" color="silent"> <Button size="small" color="silent" onClick={props.onReset}>
Reset Reset
</Button> </Button>
</FaderOpacity> </FaderOpacity>
&nbsp;&nbsp; &nbsp;&nbsp;
<Button size="small"> <Button size="small" onClick={props.onSubmit}>
Done <GoCheck /> Done <GoCheck />
</Button> </Button>
</MastheadRight> </MastheadRight>

View file

@ -10,7 +10,7 @@ export const EditorTemplate = (
const { guild, onCategoryChange, onMessageChange, onGuildChange, ...appShellProps } = const { guild, onCategoryChange, onMessageChange, onGuildChange, ...appShellProps } =
props; props;
return ( return (
<AppShell {...appShellProps} activeGuildId={guild.id}> <AppShell {...appShellProps} activeGuildId={guild.id} small double>
<EditorShell guild={guild} onGuildChange={onGuildChange} /> <EditorShell guild={guild} onGuildChange={onGuildChange} />
</AppShell> </AppShell>
); );