Style tweaks in ProjectDetailPanel

This commit is contained in:
Aria Minaei 2021-08-20 21:51:06 +02:00
parent efc52592ba
commit 5f8cdfd886
4 changed files with 154 additions and 73 deletions

View file

@ -10,7 +10,7 @@ import {
} from '@theatre/studio/panels/BasePanel/common'
import {pointerEventsAutoInNormalMode} from '@theatre/studio/css'
import ObjectDetails from './ObjectDetails'
import ProjectDetails from './ProjectDetails'
import ProjectDetails from './ProjectDetails/ProjectDetails'
const Container = styled.div`
background-color: transparent;

View file

@ -1,13 +1,12 @@
import type Project from '@theatre/core/projects/Project'
import {val} from '@theatre/dataverse'
import {usePrism} from '@theatre/dataverse-react'
import getStudio from '@theatre/studio/getStudio'
import {generateDiskStateRevision} from '@theatre/studio/StudioStore/generateDiskStateRevision'
import BasicPopover from '@theatre/studio/uiComponents/Popover/BasicPopover'
import usePopover from '@theatre/studio/uiComponents/Popover/usePopover'
import React, {useCallback, useState} from 'react'
import styled from 'styled-components'
import {rowBgColor} from './propEditors/utils/SingleRowPropEditor'
import {rowBgColor} from '@theatre/studio/panels/DetailPanel/propEditors/utils/SingleRowPropEditor'
import StateConflictRow from './StateConflictRow'
import DetailPanelButton from '@theatre/studio/uiComponents/DetailPanelButton'
const Container = styled.div`
background-color: ${rowBgColor};
@ -20,26 +19,6 @@ const TheExportRow = styled.div`
align-items: stretch;
`
const Button = styled.button<{disabled?: boolean}>`
text-align: center;
padding: 8px;
border-radius: 2px;
border: 1px solid #627b7b87;
background-color: #4b787d3d;
color: #eaeaea;
font-weight: 400;
display: block;
appearance: none;
flex-grow: 1;
cursor: ${(props) => (props.disabled ? 'none' : 'pointer')};
opacity: ${(props) => (props.disabled ? 0.4 : 1)};
&:hover {
background-color: #7dc1c878;
border-color: #9ebcbf;
}
`
const ExportTooltip = styled(BasicPopover)`
width: 280px;
padding: 1em;
@ -51,51 +30,6 @@ const ProjectDetails: React.FC<{
const project = projects[0]
const projectId = project.address.projectId
const nn = usePrism(() => {
const loadingState = val(
getStudio().atomP.ephemeral.coreByProject[projectId].loadingState,
)
if (!loadingState) return
if (loadingState.type === 'browserStateIsNotBasedOnDiskState') {
/**
* This stuff is not undo-safe, but once we switch to the new persistence
* scheme, these will be unnecessary anyway.
*/
const useBrowserState = () => {
getStudio().transaction(({drafts, stateEditors}) => {
stateEditors.coreByProject.historic.revisionHistory.add({
projectId,
revision: loadingState.onDiskState.revisionHistory[0],
})
stateEditors.coreByProject.historic.revisionHistory.add({
projectId,
revision: generateDiskStateRevision(),
})
drafts.ephemeral.coreByProject[projectId].loadingState = {
type: 'loaded',
}
})
}
const useOnDiskState = () => {
getStudio().transaction(({drafts}) => {
drafts.historic.coreByProject[projectId] = loadingState.onDiskState
drafts.ephemeral.coreByProject[projectId].loadingState = {
type: 'loaded',
}
})
}
return (
<div>
Browser state is not based on disk state.
<button onClick={useBrowserState}>Use browser's state</button>
<button onClick={useOnDiskState}>Use disk state</button>
</div>
)
}
}, [project])
const [downloaded, setDownloaded] = useState(false)
@ -140,11 +74,11 @@ const ProjectDetails: React.FC<{
return (
<>
{nn}
{tooltip}
<Container>
<StateConflictRow projectId={projectId} />
<TheExportRow>
<Button
<DetailPanelButton
onMouseEnter={(e) =>
openExportTooltip(e, e.target as unknown as HTMLButtonElement)
}
@ -152,7 +86,7 @@ const ProjectDetails: React.FC<{
disabled={downloaded}
>
{downloaded ? '(Exported)' : `Export ${projectId} to JSON`}
</Button>
</DetailPanelButton>
</TheExportRow>
</Container>
</>

View file

@ -0,0 +1,124 @@
import {useVal} from '@theatre/dataverse-react'
import getStudio from '@theatre/studio/getStudio'
import React from 'react'
import styled from 'styled-components'
import {generateDiskStateRevision} from '@theatre/studio/StudioStore/generateDiskStateRevision'
import type {ProjectEphemeralState} from '@theatre/core/projects/store/storeTypes'
import useTooltip from '@theatre/studio/uiComponents/Popover/useTooltip'
import BasicTooltip from '@theatre/studio/uiComponents/Popover/BasicTooltip'
import type {$FixMe} from '@theatre/shared/utils/types'
import DetailPanelButton from '@theatre/studio/uiComponents/DetailPanelButton'
const Container = styled.div`
padding: 8px 10px;
position: relative;
background-color: #6d232352;
&:before {
position: absolute;
content: ' ';
display: block;
left: 0;
top: 0;
bottom: 0;
width: 2px;
background-color: #ff000070;
}
`
const Message = styled.div`
margin-bottom: 1em;
`
const ChooseStateRow = styled.div`
display: flex;
gap: 8px;
`
const StateConflictRow: React.FC<{projectId: string}> = ({projectId}) => {
const loadingState = useVal(
getStudio().atomP.ephemeral.coreByProject[projectId].loadingState,
)
if (!loadingState) return null
if (loadingState.type === 'browserStateIsNotBasedOnDiskState') {
return <InConflict loadingState={loadingState} projectId={projectId} />
} else {
return null
}
}
const InConflict: React.FC<{
projectId: string
loadingState: Extract<
ProjectEphemeralState['loadingState'],
{type: 'browserStateIsNotBasedOnDiskState'}
>
}> = ({projectId, loadingState}) => {
/**
* This stuff is not undo-safe, but once we switch to the new persistence
* scheme, these will be unnecessary anyway.
*/
const useBrowserState = () => {
getStudio().transaction(({drafts, stateEditors}) => {
stateEditors.coreByProject.historic.revisionHistory.add({
projectId,
revision: loadingState.onDiskState.revisionHistory[0],
})
stateEditors.coreByProject.historic.revisionHistory.add({
projectId,
revision: generateDiskStateRevision(),
})
drafts.ephemeral.coreByProject[projectId]!.loadingState = {
type: 'loaded',
}
})
}
const useOnDiskState = () => {
getStudio().transaction(({drafts}) => {
drafts.historic.coreByProject[projectId] = loadingState.onDiskState
drafts.ephemeral.coreByProject[projectId]!.loadingState = {
type: 'loaded',
}
})
}
const [browserStateNode, browserStateRef] = useTooltip({}, () => (
<BasicTooltip>
The browser's state will override the disk state.
</BasicTooltip>
))
const [diskStateNode, diskStateRef] = useTooltip({}, () => (
<BasicTooltip>
The disk's state will override the browser's state.
</BasicTooltip>
))
return (
<Container>
<Message>Browser state is not based on disk state.</Message>
<ChooseStateRow>
{browserStateNode}
<DetailPanelButton
onClick={useBrowserState}
ref={browserStateRef as $FixMe}
>
Use browser's state
</DetailPanelButton>
{diskStateNode}
<DetailPanelButton
onClick={useOnDiskState}
ref={diskStateRef as $FixMe}
>
Use disk state
</DetailPanelButton>
</ChooseStateRow>
</Container>
)
}
export default StateConflictRow

View file

@ -0,0 +1,23 @@
import styled from 'styled-components'
const DetailPanelButton = styled.button<{disabled?: boolean}>`
text-align: center;
padding: 8px;
border-radius: 2px;
border: 1px solid #627b7b87;
background-color: #4b787d3d;
color: #eaeaea;
font-weight: 400;
display: block;
appearance: none;
flex-grow: 1;
cursor: ${(props) => (props.disabled ? 'none' : 'pointer')};
opacity: ${(props) => (props.disabled ? 0.4 : 1)};
&:hover {
background-color: #7dc1c878;
border-color: #9ebcbf;
}
`
export default DetailPanelButton