Skip to content

Commit

Permalink
Editor share dialog (#5174)
Browse files Browse the repository at this point in the history
* share dialog open flag

* iframe route and component split

* editor dialog component

* spacing

* add comment

* adjust for non-owner loads

* test

* fork instead of share for non-owners

* revert

* revert

* support for non-bff

* fixed dialog height

* fix import

* rename

* rename++

* separate fork button

* styling fork button

---------

Co-authored-by: lankaukk <[email protected]>
  • Loading branch information
ruggi and lankaukk authored Apr 8, 2024
1 parent ee9c393 commit 8814f9b
Show file tree
Hide file tree
Showing 16 changed files with 472 additions and 93 deletions.
6 changes: 6 additions & 0 deletions editor/src/components/editor/action-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,11 @@ export interface ExtractPropertyControlsFromDescriptorFiles {
paths: string[]
}

export interface SetSharingDialogOpen {
action: 'SET_SHARING_DIALOG_OPEN'
open: boolean
}

export type EditorAction =
| ClearSelection
| InsertJSXElement
Expand Down Expand Up @@ -1284,6 +1289,7 @@ export type EditorAction =
| SetForking
| SetCollaborators
| ExtractPropertyControlsFromDescriptorFiles
| SetSharingDialogOpen

export type DispatchPriority =
| 'everyone'
Expand Down
8 changes: 8 additions & 0 deletions editor/src/components/editor/actions/action-creators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ import type {
SetForking,
SetCollaborators,
ExtractPropertyControlsFromDescriptorFiles,
SetSharingDialogOpen,
SetCodeEditorComponentDescriptorErrors,
} from '../action-types'
import type { InsertionSubjectWrapper, Mode } from '../editor-modes'
Expand Down Expand Up @@ -1756,3 +1757,10 @@ export function extractPropertyControlsFromDescriptorFiles(
paths: paths,
}
}

export function setSharingDialogOpen(open: boolean): SetSharingDialogOpen {
return {
action: 'SET_SHARING_DIALOG_OPEN',
open: open,
}
}
1 change: 1 addition & 0 deletions editor/src/components/editor/actions/action-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ export function isTransientAction(action: EditorAction): boolean {
case 'SET_FORKING':
case 'SET_COLLABORATORS':
case 'EXTRACT_PROPERTY_CONTROLS_FROM_DESCRIPTOR_FILES':
case 'SET_SHARING_DIALOG_OPEN':
return true

case 'TRUE_UP_ELEMENTS':
Expand Down
13 changes: 9 additions & 4 deletions editor/src/components/editor/actions/actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,6 @@ import {
modifiableAttributeIsAttributeValue,
isJSExpression,
isJSXMapExpression,
isJSExpressionOtherJavaScript,
jsExpressionOtherJavaScriptSimple,
getDefinedElsewhereFromElement,
getDefinedElsewhereFromElementChild,
isJSXFragment,
jsxConditionalExpressionConditionOptic,
Expand Down Expand Up @@ -175,7 +172,7 @@ import {
} from '../../canvas/canvas-utils'
import type { SetFocus } from '../../common/actions'
import { openMenu } from '../../context-menu-side-effect'
import type { CodeResultCache, PropertyControlsInfo } from '../../custom-code/code-file'
import type { CodeResultCache } from '../../custom-code/code-file'
import {
codeCacheToBuildResult,
generateCodeResultCache,
Expand Down Expand Up @@ -332,6 +329,7 @@ import type {
SetCollaborators,
ExtractPropertyControlsFromDescriptorFiles,
SetCodeEditorComponentDescriptorErrors,
SetSharingDialogOpen,
} from '../action-types'
import { isLoggedIn } from '../action-types'
import type { Mode } from '../editor-modes'
Expand Down Expand Up @@ -945,6 +943,7 @@ export function restoreEditorState(
commentFilterMode: currentEditor.commentFilterMode,
forking: currentEditor.forking,
collaborators: currentEditor.collaborators,
sharingDialogOpen: currentEditor.sharingDialogOpen,
}
}

Expand Down Expand Up @@ -5746,6 +5745,12 @@ export const UPDATE_FNS = {
)
return state
},
SET_SHARING_DIALOG_OPEN: (action: SetSharingDialogOpen, editor: EditorModel): EditorModel => {
return {
...editor,
sharingDialogOpen: action.open,
}
},
}

function copySelectionToClipboardMutating(
Expand Down
2 changes: 2 additions & 0 deletions editor/src/components/editor/editor-component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ import { CommentMaintainer } from '../../core/commenting/comment-maintainer'
import { useIsLoggedIn, useLiveblocksConnectionListener } from '../../core/shared/multiplayer-hooks'
import { ForkSearchParamKey, ProjectForkFlow } from './project-fork-flow'
import { isRoomId, projectIdToRoomId } from '../../utils/room-id'
import { SharingDialog } from './sharing-dialog'
import { AccessLevelParamKey } from './persistence/persistence-backend'

const liveModeToastId = 'play-mode-toast'
Expand Down Expand Up @@ -498,6 +499,7 @@ export const EditorComponentInner = React.memo((props: EditorProps) => {
<GithubRepositoryCloneFlow />
<ProjectForkFlow />
<LockedOverlay />
<SharingDialog />
</SimpleFlexRow>
<EditorCommon
mouseDown={onWindowMouseDown}
Expand Down
144 changes: 144 additions & 0 deletions editor/src/components/editor/sharing-dialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { motion } from 'framer-motion'
import React from 'react'
import { getProjectID } from '../../common/env-vars'
import { Button, Icons, useColorTheme, UtopiaStyles } from '../../uuiui'
import { GithubSpinner } from '../navigator/left-pane/github-pane/github-spinner'
import { useDispatch } from './store/dispatch-context'
import { useEditorState, Substores } from './store/store-hook'
import { unless, when } from '../../utils/react-conditionals'
import { setSharingDialogOpen } from './actions/action-creators'
import { editorShareDialogIframeUrl } from '../../common/server'

const BaseIframeHeight = 80
const LoadedIframeHeight = 300
const RadixDialogSpacing = 135
const SharingIframeWidth = 580 // px
const LoadingDialogWidth = 260 // px

export const SharingDialog = React.memo(() => {
const dispatch = useDispatch()
const colorTheme = useColorTheme()

const projectId = getProjectID()

const sharingDialogOpen: boolean = useEditorState(
Substores.restOfEditor,
(store) => store.editor.sharingDialogOpen,
'SharingDialog sharingDialogOpen',
)

const [iframeLoaded, setIframeLoaded] = React.useState(false)
const [iframeHeight, setIframeHeight] = React.useState(BaseIframeHeight)

const sharingIframeRef = React.useRef<HTMLIFrameElement | null>(null)

const onSharingIframeLoaded = React.useCallback(() => {
setIframeLoaded(true)
setIframeHeight(LoadedIframeHeight + RadixDialogSpacing)
}, [])

const handleDismiss = React.useCallback(() => {
dispatch([setSharingDialogOpen(false)])
setIframeLoaded(false)
setIframeHeight(BaseIframeHeight)
}, [dispatch])

const stopPropagation = React.useCallback((e: React.MouseEvent) => {
e.stopPropagation()
}, [])

if (projectId == null) {
return null
}

return (
<div
style={{
position: 'fixed',
top: 0,
left: 0,
bottom: 0,
right: 0,
pointerEvents: !sharingDialogOpen ? 'none' : 'all',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: !sharingDialogOpen ? 'transparent' : '#00000033',
}}
onClick={handleDismiss}
>
{when(
sharingDialogOpen,
<motion.div
initial={{ opacity: 0, height: BaseIframeHeight }}
animate={{ opacity: 1, transition: { duration: 0.1 }, height: iframeHeight }}
exit={{ opacity: 0, transition: { duration: 0.1 } }}
style={{
background: colorTheme.bg0.value,
boxShadow: UtopiaStyles.popup.boxShadow,
borderRadius: 10,
width: '100%',
maxWidth: iframeLoaded ? SharingIframeWidth : LoadingDialogWidth,
position: 'relative',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
onClick={stopPropagation}
>
{when(
iframeLoaded,
<Button
highlight
style={{
position: 'absolute',
top: 14,
right: 14,
width: 22,
height: 22,
}}
onClick={handleDismiss}
>
<Icons.Cross />
</Button>,
)}
<iframe
ref={sharingIframeRef}
onLoad={onSharingIframeLoaded}
style={{
background: colorTheme.bg0.value,
border: 'none',
opacity: iframeLoaded ? 1 : 0,
width: '100%',
height: '100%',
borderRadius: 10,
}}
src={editorShareDialogIframeUrl(projectId)}
/>
{unless(
iframeLoaded,
<div
style={{
fontStyle: 'italic',
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
borderRadius: 10,
gap: 6,
}}
>
<GithubSpinner stroke='#000' />
Loading share details…
</div>,
)}
</motion.div>,
)}
</div>
)
})
SharingDialog.displayName = 'SharingDialog'
5 changes: 5 additions & 0 deletions editor/src/components/editor/store/editor-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1490,6 +1490,7 @@ export interface EditorState {
commentFilterMode: CommentFilterMode
forking: boolean
collaborators: Collaborator[]
sharingDialogOpen: boolean
}

export function editorState(
Expand Down Expand Up @@ -1574,6 +1575,7 @@ export function editorState(
commentFilterMode: CommentFilterMode,
forking: boolean,
collaborators: Collaborator[],
sharingDialogOpen: boolean,
): EditorState {
return {
id: id,
Expand Down Expand Up @@ -1657,6 +1659,7 @@ export function editorState(
commentFilterMode: commentFilterMode,
forking: forking,
collaborators: collaborators,
sharingDialogOpen: sharingDialogOpen,
}
}

Expand Down Expand Up @@ -2620,6 +2623,7 @@ export function createEditorState(dispatch: EditorDispatch): EditorState {
commentFilterMode: 'all',
forking: false,
collaborators: [],
sharingDialogOpen: false,
}
}

Expand Down Expand Up @@ -3005,6 +3009,7 @@ export function editorModelFromPersistentModel(
commentFilterMode: 'all',
forking: false,
collaborators: [],
sharingDialogOpen: false,
}
return editor
}
Expand Down
2 changes: 2 additions & 0 deletions editor/src/components/editor/store/editor-update.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,8 @@ export function runSimpleLocalEditorAction(
workers,
dispatch,
)
case 'SET_SHARING_DIALOG_OPEN':
return UPDATE_FNS.SET_SHARING_DIALOG_OPEN(action, state)
default:
return state
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4830,6 +4830,11 @@ export const EditorStateKeepDeepEquality: KeepDeepEqualityCall<EditorState> = (
newValue.collaborators,
)

const sharingDialogOpenResults = BooleanKeepDeepEquality(
oldValue.sharingDialogOpen,
newValue.sharingDialogOpen,
)

const areEqual =
idResult.areEqual &&
forkedFromProjectIdResult.areEqual &&
Expand Down Expand Up @@ -4910,7 +4915,8 @@ export const EditorStateKeepDeepEquality: KeepDeepEqualityCall<EditorState> = (
activeFramesResults.areEqual &&
commentFilterModeResults.areEqual &&
forkingResults.areEqual &&
collaboratorsResults.areEqual
collaboratorsResults.areEqual &&
sharingDialogOpenResults.areEqual

if (areEqual) {
return keepDeepEqualityResult(oldValue, true)
Expand Down Expand Up @@ -4997,6 +5003,7 @@ export const EditorStateKeepDeepEquality: KeepDeepEqualityCall<EditorState> = (
commentFilterModeResults.value,
forkingResults.value,
collaboratorsResults.value,
sharingDialogOpenResults.value,
)

return keepDeepEqualityResult(newEditorState, false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,5 @@ export const EmptyEditorStateForKeysOnly: EditorState = {
commentFilterMode: 'all',
forking: false,
collaborators: [],
sharingDialogOpen: false,
}
Loading

0 comments on commit 8814f9b

Please sign in to comment.