fix snippet toolbar logic

main
Mike Fix 3 years ago
parent 7557b5563e
commit 859abfe369
No known key found for this signature in database
GPG Key ID: 1D85E862314CA79F

@ -290,10 +290,18 @@ class Editor extends React.Component {
.then(() => .then(() =>
this.props.setToasts({ this.props.setToasts({
type: 'SET', type: 'SET',
toasts: [{ children: 'Snippet duplicated!', timeout: 3000 }], toasts: [{ children: 'Snippet created', timeout: 3000 }],
}) })
) )
handleSnippetUpdate = () =>
this.context.snippet.update(this.props.snippet.id, this.state).then(() =>
this.props.setToasts({
type: 'SET',
toast: { children: 'Snippet saved', timeout: 3000 },
})
)
handleSnippetDelete = () => handleSnippetDelete = () =>
this.context.snippet this.context.snippet
.delete(this.props.snippet.id) .delete(this.props.snippet.id)
@ -402,10 +410,9 @@ class Editor extends React.Component {
snippet={this.props.snippet} snippet={this.props.snippet}
onCreate={this.handleSnippetCreate} onCreate={this.handleSnippetCreate}
onDelete={this.handleSnippetDelete} onDelete={this.handleSnippetDelete}
onUpdate={this.handleSnippetUpdate}
name={config.name} name={config.name}
onChange={this.updateSetting} onChange={this.updateSetting}
setSnippet={this.props.setSnippet}
setToasts={this.props.setToasts}
/> />
<FontFace {...config} /> <FontFace {...config} />
<style jsx> <style jsx>

@ -25,12 +25,6 @@ function onReset() {
function toastsReducer(curr, action) { function toastsReducer(curr, action) {
switch (action.type) { switch (action.type) {
case 'ADD': {
if (!curr.find(t => t.children === action.toast.children)) {
return curr.concat(action.toast)
}
return curr
}
case 'SET': { case 'SET': {
return action.toasts return action.toasts
} }

@ -7,12 +7,11 @@ import Input from './Input'
import ConfirmButton from './ConfirmButton' import ConfirmButton from './ConfirmButton'
import Popout, { managePopout } from './Popout' import Popout, { managePopout } from './Popout'
import { Down as ArrowDown } from './svg/Arrows' import { Down as ArrowDown } from './svg/Arrows'
import { useAPI } from './ApiContext'
import { useAuth } from './AuthContext' import { useAuth } from './AuthContext'
import { COLORS } from '../lib/constants' import { COLORS } from '../lib/constants'
const popoutStyle = { width: '144px', right: 15, top: 40 } const popoutStyle = { width: '120px', right: -8, top: 40 }
function DeleteButton(props) { function DeleteButton(props) {
const [onClick, { loading }] = useAsyncCallback(props.onClick) const [onClick, { loading }] = useAsyncCallback(props.onClick)
@ -26,7 +25,7 @@ function DeleteButton(props) {
large large
color="#fff" color="#fff"
onClick={onClick} onClick={onClick}
style={{ color: COLORS.RED, borderTop: `1px solid ${COLORS.GREEN}` }} style={{ color: COLORS.RED }}
> >
{loading ? 'Deleting…' : 'Delete'} {loading ? 'Deleting…' : 'Delete'}
</ConfirmButton> </ConfirmButton>
@ -38,21 +37,26 @@ function DuplicateButton(props) {
return ( return (
<Button <Button
display="block" border
padding="8px"
flex="unset"
center
large large
center
color={COLORS.GREEN} color={COLORS.GREEN}
onClick={onClick} onClick={onClick}
data-cy="duplicate-button"
style={{ minWidth: 92 }}
title="Duplicate"
disabled={loading}
> >
{loading ? 'Duplicating…' : 'Duplicate'} {loading ? 'Duplicating…' : 'Duplicate'}
</Button> </Button>
) )
} }
function SaveButton({ loading, onClick }) { function SaveButton({ loading, onClick, sameUser }) {
useKeyboardListener('⌥-s', e => { useKeyboardListener('⌥-s', e => {
if (loading) {
return
}
e.preventDefault() e.preventDefault()
onClick() onClick()
}) })
@ -65,7 +69,11 @@ function SaveButton({ loading, onClick }) {
color={COLORS.GREEN} color={COLORS.GREEN}
onClick={onClick} onClick={onClick}
data-cy="save-button" data-cy="save-button"
style={{ minWidth: 84, borderBottomRightRadius: 0, borderTopRightRadius: 0 }} style={{
minWidth: 84,
borderBottomRightRadius: sameUser ? 0 : undefined,
borderTopRightRadius: sameUser ? 0 : undefined,
}}
title="Save" title="Save"
disabled={loading} disabled={loading}
> >
@ -74,51 +82,23 @@ function SaveButton({ loading, onClick }) {
) )
} }
function SnippetToolbar({ function SnippetToolbar({ toggleVisibility, isVisible, snippet, ...props }) {
toggleVisibility,
isVisible,
snippet,
setSnippet,
setToasts,
state,
...props
}) {
const user = useAuth() const user = useAuth()
const online = useOnline() const online = useOnline()
const api = useAPI()
const [update, { loading }] = useAsyncCallback(api.snippet.update) const [save, { loading }] = useAsyncCallback(() => {
if (snippet) {
return props.onUpdate()
} else {
return props.onCreate()
}
})
if (!online) return null if (!online) return null
if (!user) return null if (!user) return null
const sameUser = snippet && user.uid === snippet.userId const sameUser = snippet && user.uid === snippet.userId
// TODO move this to Editor
function saveSnippet() {
if (loading || !user) {
return
}
if (!snippet) {
update(undefined, state).then(newSnippet => {
if (newSnippet && newSnippet.id) {
setSnippet(newSnippet)
setToasts({
type: 'ADD',
toast: { children: 'Snippet saved!', closable: true },
})
}
})
} else if (sameUser) {
update(snippet.id, state).then(() => {
setToasts({
type: 'ADD',
toast: { children: 'Snippet saved!', closable: true },
})
})
}
}
return ( return (
<Toolbar <Toolbar
style={{ style={{
@ -126,31 +106,15 @@ function SnippetToolbar({
zIndex: 1, zIndex: 1,
marginTop: 16, marginTop: 16,
marginBottom: 0, marginBottom: 0,
flexDirection: 'row-reverse', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
}} }}
> >
<div className="flex"> <Popout hidden={!isVisible} borderColor={COLORS.GREEN} pointerRight="6px" style={popoutStyle}>
<SaveButton loading={loading} onClick={saveSnippet} /> <div className="menu flex">
<Button <DeleteButton onClick={props.onDelete} />
title="Save menu dropdown" </div>
border </Popout>
large
center
color={COLORS.GREEN}
padding="0 8px"
margin="0 8px 0 -1px"
onClick={toggleVisibility}
data-cy="save-button"
style={{
borderBottomLeftRadius: 0,
borderTopLeftRadius: 0,
maxWidth: '26px',
}}
>
<ArrowDown color={COLORS.GREEN} />
</Button>
</div>
<div style={{ marginRight: 'auto' }}> <div style={{ marginRight: 'auto' }}>
<Input <Input
align="left" align="left"
@ -160,12 +124,33 @@ function SnippetToolbar({
onChange={e => props.onChange('name', e.target.value)} onChange={e => props.onChange('name', e.target.value)}
/> />
</div> </div>
<Popout hidden={!isVisible} borderColor={COLORS.GREEN} pointerRight="6px" style={popoutStyle}> <div className="flex">
<div className="menu flex"> {snippet && !sameUser ? (
<DuplicateButton onClick={props.onCreate} /> <DuplicateButton onClick={props.onCreate} />
{sameUser && <DeleteButton onClick={props.onDelete} />} ) : (
</div> <SaveButton loading={loading} onClick={save} sameUser={sameUser} />
</Popout> )}
{sameUser && (
<Button
title="Save menu dropdown"
border
large
center
color={COLORS.GREEN}
padding="0 8px"
margin="0 0 0 -1px"
onClick={toggleVisibility}
data-cy="save-button"
style={{
borderBottomLeftRadius: 0,
borderTopLeftRadius: 0,
maxWidth: '26px',
}}
>
<ArrowDown color={COLORS.GREEN} />
</Button>
)}
</div>
<style jsx> <style jsx>
{` {`
.menu { .menu {

@ -15,14 +15,10 @@ const Toolbar = props => (
font-size: 14px; font-size: 14px;
} }
.toolbar > :global(div) { .toolbar > :global(div:not(:last-child)) {
margin-right: 8px; margin-right: 8px;
} }
.toolbar > :global(div):last-child {
margin-right: 0px;
}
@media (max-width: 920px) { @media (max-width: 920px) {
.toolbar { .toolbar {
max-width: 100%; max-width: 100%;

Loading…
Cancel
Save