Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 43 additions & 5 deletions src/cloud/components/Blocks/BlockContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
mdiPackageVariantClosed,
mdiCodeTags,
mdiFileDocumentOutline,
mdiTable,
} from '@mdi/js'
import EmbedForm from './forms/EmbedForm'
import { Block, BlockCreateRequestBody, ContainerBlock } from '../../api/blocks'
Expand All @@ -28,6 +29,12 @@ import {
useSidebarCollapse,
} from '../../lib/stores/sidebarCollapse'
import { FoldingProps } from '../../../design/components/atoms/FoldingWrapper'
import {
markdownBlockEventEmitter,
tableBlockEventEmitter,
} from '../../lib/utils/events'
import { sleep } from '../../../lib/sleep'
import cc from 'classcat'

export interface Canvas extends SerializedDocWithBookmark {
rootBlock: ContainerBlock
Expand All @@ -43,7 +50,7 @@ interface BlockContentProps {

const BlockContent = ({ doc }: BlockContentProps) => {
const { currentUserIsCoreMember } = usePage()
const { state, actions } = useDocBlocks(doc.rootBlock.id)
const { state, actions, sendingMap } = useDocBlocks(doc.rootBlock.id)
const { openModal, closeAllModals } = useModal()
const [currentBlock, setCurrentBlock] = useState<Block | null>(null)
const [provider] = useRealtime({
Expand All @@ -65,9 +72,27 @@ const BlockContent = ({ doc }: BlockContentProps) => {
const createBlock = useCallback(
async (block: BlockCreateRequestBody) => {
try {
const newBlock = await actions.create(block, doc.rootBlock)
const res = await actions.create(block, doc.rootBlock, {
afterSuccess: (block) => {
setCurrentBlock(block)
},
})
if (!res.err) {
const block = res.data
await sleep(100) //rendering delay
if (block.type === 'markdown') {
markdownBlockEventEmitter.dispatch({
type: 'edit',
id: block.id,
})
} else if (block.type === 'table') {
tableBlockEventEmitter.dispatch({
type: 'focus-title',
id: block.id,
})
}
}
closeAllModals()
setCurrentBlock(newBlock)
} catch (error) {
pushApiErrorMessage(error)
}
Expand Down Expand Up @@ -171,6 +196,7 @@ const BlockContent = ({ doc }: BlockContentProps) => {
onDelete={actions.remove}
idPrefix='nav'
showFoldEvents={true}
sendingMap={sendingMap}
/>
))}
</Scroller>
Expand Down Expand Up @@ -225,7 +251,7 @@ const BlockContent = ({ doc }: BlockContentProps) => {
<Icon path={mdiPlus} size={16} />
</Flexbox>
}
icon={{ type: 'icon', path: mdiPackageVariantClosed }}
icon={{ type: 'icon', path: mdiTable }}
/>
<NavigationItem
labelClick={createEmbed}
Expand All @@ -246,7 +272,12 @@ const BlockContent = ({ doc }: BlockContentProps) => {
</UpDownList>
<div className='block__editor__view'>
<Scroller
className='block__editor__view__wrapper'
className={cc([
'block__editor__view__wrapper',
currentBlock != null &&
currentBlock.type === 'embed' &&
'block__editor__view__wrapper--padding-less',
])}
id='block__editor__view__wrapper'
ref={contentScrollerRef}
>
Expand All @@ -264,6 +295,7 @@ const BlockContent = ({ doc }: BlockContentProps) => {
setCurrentBlock={setCurrentBlock}
scrollToElement={scrollToElement}
currentUserIsCoreMember={currentUserIsCoreMember}
sendingMap={sendingMap}
/>
</Scroller>
<div id='block__editor__view__toolbar-portal' />
Expand All @@ -277,6 +309,10 @@ const StyledBlockContent = styled.div`
flex: 1 1 auto;
overflow: hidden;

.block__editor__view__wrapper--padding-less {
padding: 0 !important;
}

& > .block__editor__nav {
padding-top: ${({ theme }) => theme.sizes.spaces.df}px;
display: flex;
Expand All @@ -294,6 +330,8 @@ const StyledBlockContent = styled.div`
flex: 1 1 auto;
height: 100%;
position: relative;
width: 100%;
overflow: hidden;
}

& .block__editor__view__wrapper {
Expand Down
1 change: 1 addition & 0 deletions src/cloud/components/Blocks/BlockLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ function hexToRgb(hex: string) {
const BlockLayoutContainer = styled.div`
width: 100%;
position: relative;
z-index: 0;
transition: all 0.3s ease-in-out;
background: ${({ theme }) => theme.colors.background.primary};
padding: ${({ theme }) => theme.sizes.spaces.md}px
Expand Down
15 changes: 13 additions & 2 deletions src/cloud/components/Blocks/BlockTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,18 @@ import { min } from 'ramda'
import cc from 'classcat'
import { FoldingProps } from '../../../design/components/atoms/FoldingWrapper'
import { blockTitle } from '../../lib/utils/blocks'
import { BlockActionRemove } from '../../lib/hooks/useDocBlocks'

interface BlockTreeProps {
idPrefix?: string
root: Block & { folding?: FoldingProps; folded?: boolean }
onSelect: (block: Block) => void
onDelete?: (block: Block) => void
onDelete?: BlockActionRemove
active?: Block
depth?: number
className?: string
showFoldEvents?: boolean
sendingMap: Map<string, string>
}

const BlockTree = ({
Expand All @@ -29,6 +31,7 @@ const BlockTree = ({
active,
className,
showFoldEvents,
sendingMap,
}: BlockTreeProps) => {
const parentDepth = min(depth || 1, 6)
return (
Expand All @@ -53,7 +56,14 @@ const BlockTree = ({
controls={
onDelete == null || depth === 0
? []
: [{ icon: mdiTrashCan, onClick: () => onDelete(root) }]
: [
{
icon: mdiTrashCan,
onClick: () => onDelete(root),
disabled: sendingMap.has(root.id),
spinning: sendingMap.get(root.id) === 'delete-block',
},
]
}
/>
{(!showFoldEvents || !root.folded) &&
Expand All @@ -68,6 +78,7 @@ const BlockTree = ({
active={active}
depth={parentDepth + 1}
showFoldEvents={showFoldEvents}
sendingMap={sendingMap}
/>
))}
</StyledBlockTree>
Expand Down
9 changes: 8 additions & 1 deletion src/cloud/components/Blocks/forms/EmbedForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,14 @@ function getEmbedURL(url: string) {
url
)}`
}
return getEmbedURL
const isYoutubeVideoURL = new RegExp(
/^(?:https:\/\/)?(?:m.)?(?:www\.)?(?:(?:youtube\.com\/watch\?v=)|(?:youtu.be)\/)([A-z0-9_-]*)/,
'gim'
).exec(url)
if (isYoutubeVideoURL != null) {
return `https://www.youtube.com/embed/${isYoutubeVideoURL[1]}`
}
return url
}

export default EmbedForm
36 changes: 12 additions & 24 deletions src/cloud/components/Blocks/views/Container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ import {
} from '../../../api/blocks'
import styled from '../../../../design/lib/styled'
import { BlockView, ViewProps } from '.'
import { getBlockDomId } from '../../../lib/blocks/dom'
import { domBlockCreationHandler, getBlockDomId } from '../../../lib/blocks/dom'
import { useModal } from '../../../../design/lib/stores/modal'
import BlockCreationModal from '../BlockCreationModal'
import BlockToolbar from '../BlockToolbar'
import BlockLayout from '../BlockLayout'
import { getTableBlockInputId } from './Table'
import { markdownBlockEventEmitter } from '../../../lib/utils/events'

interface ContainerViewProps extends ViewProps<ContainerBlock> {
setCurrentBlock: React.Dispatch<React.SetStateAction<Block | null>>
Expand All @@ -28,42 +26,31 @@ const ContainerView = ({
isChild,
realtime,
currentUserIsCoreMember,
sendingMap,
scrollToElement,
setCurrentBlock,
}: ContainerViewProps) => {
const { openModal, closeAllModals } = useModal()

const createBlock = useCallback(
async (newBlock: BlockCreateRequestBody) => {
const createdBlock = await actions.create(newBlock, block)
await actions.create(newBlock, block, {
afterSuccess: (createdBlock) => {
if (canvas.rootBlock.id === block.id) {
setCurrentBlock(createdBlock)
}
domBlockCreationHandler(scrollToElement, createdBlock)
},
})
closeAllModals()

if (canvas.rootBlock.id === block.id) {
setCurrentBlock(createdBlock)
return
}
const blockElem = document.getElementById(getBlockDomId(createdBlock))
scrollToElement(blockElem)

if (createdBlock.type === 'table') {
const titleElement = document.getElementById(
getTableBlockInputId(createdBlock)
)
if (titleElement != null) titleElement.focus()
} else if (newBlock.type === 'markdown') {
markdownBlockEventEmitter.dispatch({
type: 'edit',
id: createdBlock.id,
})
}
},
[
block,
actions,
closeAllModals,
scrollToElement,
canvas.rootBlock.id,
setCurrentBlock,
scrollToElement,
]
)

Expand Down Expand Up @@ -135,6 +122,7 @@ const ContainerView = ({
scrollToElement={scrollToElement}
setCurrentBlock={setCurrentBlock}
currentUserIsCoreMember={currentUserIsCoreMember}
sendingMap={sendingMap}
/>
)
})}
Expand Down
61 changes: 43 additions & 18 deletions src/cloud/components/Blocks/views/GithubIssue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import GithubLabelsData from '../data/GithubLabelsData'
import { useModal } from '../../../../design/lib/stores/modal'
import DataTypeMenu from '../props/DataTypeMenu'
import { capitalize } from '../../../lib/utils/string'
import { getBlockDomId } from '../../../lib/blocks/dom'
import { domBlockCreationHandler, getBlockDomId } from '../../../lib/blocks/dom'
import Flexbox from '../../../../design/components/atoms/Flexbox'
import { ExternalLink } from '../../../../design/components/atoms/Link'
import BlockCreationModal from '../BlockCreationModal'
Expand All @@ -29,17 +29,17 @@ import InfoBlock, {
InfoBlockRow,
} from '../../../../design/components/organisms/InfoBlock'
import BlockLayout from '../BlockLayout'
import { getTableBlockInputId } from './Table'
import MetadataContainer from '../../../../design/components/organisms/MetadataContainer'
import { markdownBlockEventEmitter } from '../../../lib/utils/events'
import Button from '../../../../design/components/atoms/Button'
import { StyledUserIcon } from '../../UserIcon'

const GithubIssueView = ({
block,
realtime,
actions: blockActions,
canvas,
currentUserIsCoreMember,
sendingMap,
scrollToElement,
setCurrentBlock,
}: ViewProps<GithubIssueBlock>) => {
Expand Down Expand Up @@ -114,22 +114,12 @@ const GithubIssueView = ({

const createBlock = useCallback(
async (newBlock: BlockCreateRequestBody) => {
const createdBlock = await blockActions.create(newBlock, block)
await blockActions.create(newBlock, block, {
afterSuccess: (createdBlock) => {
domBlockCreationHandler(scrollToElement, createdBlock)
},
})
closeAllModals()
const blockElem = document.getElementById(getBlockDomId(createdBlock))
scrollToElement(blockElem)

if (createdBlock.type === 'table') {
const titleElement = document.getElementById(
getTableBlockInputId(createdBlock)
)
if (titleElement != null) titleElement.focus()
} else if (newBlock.type === 'markdown') {
markdownBlockEventEmitter.dispatch({
type: 'edit',
id: createdBlock.id,
})
}
},
[blockActions, block, closeAllModals, scrollToElement]
)
Expand Down Expand Up @@ -166,6 +156,17 @@ const GithubIssueView = ({
<h1>{block.data.title}</h1>
</Flexbox>
<InfoBlock className='github-issue__view__info'>
{block.data.repository != null &&
block.data.repository.organization != null && (
<InfoBlockRow label='Organization'>
<ExternalLink
showIcon={true}
href={block.data.repository.organization.html_url}
>
{block.data.repository.organization.login}
</ExternalLink>
</InfoBlockRow>
)}
{htmlURLRegexes.repoUrl != null && (
<InfoBlockRow label='Repository'>
<ExternalLink href={htmlURLRegexes.repoUrl[1]} showIcon={true}>
Expand All @@ -187,6 +188,16 @@ const GithubIssueView = ({
</ExternalLink>
</InfoBlockRow>
)}
{block.data.creator != null && (
<InfoBlockRow label='Creator'>
<StyledUserIcon className='subtle'>
<img
src={block.data.user.avatar_url}
alt={block.data.user.login[0]}
/>
</StyledUserIcon>
</InfoBlockRow>
)}
<InfoBlockRow label='Assignees'>
<GitHubAssigneesData data={block.data} onUpdate={updateBlock} />
</InfoBlockRow>
Expand All @@ -196,6 +207,11 @@ const GithubIssueView = ({
<InfoBlockRow label='Labels'>
<GithubLabelsData data={block.data} onUpdate={updateBlock} />
</InfoBlockRow>
{block.data.body != null && block.data.body.trim() !== '' && (
<InfoBlockRow label='Body'>
<div className='github-issue__body'>{block.data.body}</div>{' '}
</InfoBlockRow>
)}
{props.map(([key, value]) => {
return (
<InfoBlockRow label={getPropName(key)} key={`custom-${key}`}>
Expand Down Expand Up @@ -233,6 +249,7 @@ const GithubIssueView = ({
setCurrentBlock={setCurrentBlock}
scrollToElement={scrollToElement}
currentUserIsCoreMember={currentUserIsCoreMember}
sendingMap={sendingMap}
/>
)
})}
Expand Down Expand Up @@ -266,6 +283,14 @@ const StyledGithubIssueView = styled.div`
margin: 0;
}

.github-issue__body {
padding: ${({ theme }) => theme.sizes.spaces.xsm}px
${({ theme }) => theme.sizes.spaces.sm}px;
background: ${({ theme }) => theme.colors.background.secondary};
white-space: break-spaces;
display: block;
}

.github-issue__view__title .icon {
margin-right: ${({ theme }) => theme.sizes.spaces.sm}px;
}
Expand Down
Loading