Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance (Whiteboards): UX #8797

Merged
merged 24 commits into from
Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
1531be7
enhance: create new portal on alt+click ref
sprocketc Mar 8, 2023
9a8082b
Merge branch 'master' into enhance/whiteboards-ux
sprocketc Mar 9, 2023
e7f17c9
enable dev tools in logseq
sprocketc Mar 9, 2023
01200cc
refactor isDev
sprocketc Mar 9, 2023
2822a1b
enhance: zooming performance
sprocketc Mar 9, 2023
560fca4
remove transition effect
sprocketc Mar 9, 2023
913afd5
fix: clear brush area on exit
sprocketc Mar 9, 2023
223a684
enhance: auto remove arrow binding
sprocketc Mar 10, 2023
145d2e9
fix: statusbar styles
sprocketc Mar 10, 2023
0d5e192
chore: add tests
sprocketc Mar 10, 2023
c0162e1
fix: e2e tests
sprocketc Mar 10, 2023
9459148
fix: remove alt key
sprocketc Mar 10, 2023
b5056f8
fix: e2e tests
sprocketc Mar 10, 2023
7396fad
Merge branch 'enhance/whiteboards-ux' of github.com:logseq/logseq int…
sprocketc Mar 10, 2023
2ea3c14
fix: e2e tests
sprocketc Mar 10, 2023
39e21ab
Merge branch 'master' into enhance/whiteboards-ux
sprocketc Mar 13, 2023
9afb83b
fix: e2e tests
sprocketc Mar 13, 2023
7f99ead
fix: remove problematic test for now
sprocketc Mar 13, 2023
abc5764
Merge branch 'master' into enhance/whiteboards-ux
sprocketc Mar 16, 2023
8bb1da9
fix: e2e conflicts
sprocketc Mar 16, 2023
0bbeda9
Merge branch 'master' into enhance/whiteboards-ux
sprocketc Mar 18, 2023
2d7d766
Merge branch 'master' into enhance/whiteboards-ux
tiensonqin Mar 20, 2023
1a4119a
Merge branch 'master' into enhance/whiteboards-ux
sprocketc Mar 20, 2023
e29701c
use mod key to create new portals on click
sprocketc Mar 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
66 changes: 52 additions & 14 deletions e2e-tests/whiteboards.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,11 @@ test('draw a rectangle', async ({ page }) => {
await page.mouse.move(bounds.x + 5, bounds.y + 5)
await page.mouse.down()

await page.mouse.move(
bounds.x + bounds.width / 2,
bounds.y + bounds.height / 2
)
await page.mouse.move(bounds.x + 50, bounds.y + 50 )
await page.mouse.up()
await page.keyboard.press('Escape')

await expect(
page.locator('.logseq-tldraw .tl-positioned-svg rect')
).not.toHaveCount(0)
await expect(page.locator('.logseq-tldraw .tl-box-container')).toHaveCount(1)
})

test('undo the rectangle action', async ({ page }) => {
Expand All @@ -94,6 +90,54 @@ test('undo the rectangle action', async ({ page }) => {
await expect(page.locator('.logseq-tldraw .tl-positioned-svg rect')).toHaveCount(0)
})

test('redo the rectangle action', async ({ page }) => {
await page.keyboard.press(modKey + '+Shift+z')

await page.keyboard.press('Escape')
await page.waitForTimeout(100)

await expect(page.locator('.logseq-tldraw .tl-box-container')).toHaveCount(1)
})

test('clone the rectangle', async ({ page }) => {
const canvas = await page.waitForSelector('.logseq-tldraw')
const bounds = (await canvas.boundingBox())!

await page.mouse.move(bounds.x + 20, bounds.y + 20, {steps: 5})

await page.keyboard.down('Alt')
await page.mouse.down()

await page.mouse.move(bounds.x + 100, bounds.y + 100, {steps: 5})
await page.mouse.up()
await page.keyboard.up('Alt')

await expect(page.locator('.logseq-tldraw .tl-box-container')).toHaveCount(2)
})

test('connect rectangles with an arrow', async ({ page }) => {
const canvas = await page.waitForSelector('.logseq-tldraw')
const bounds = (await canvas.boundingBox())!

await page.keyboard.press('c')

await page.mouse.move(bounds.x + 20, bounds.y + 20)
await page.mouse.down()

await page.mouse.move(bounds.x + 100, bounds.y + 100, {steps: 5}) // will fail without steps
await page.mouse.up()
await page.keyboard.press('Escape')


await expect(page.locator('.logseq-tldraw .tl-line-container')).toHaveCount(1)
})

test('cleanup the shapes', async ({ page }) => {
await page.keyboard.press(`${modKey}+a`)
await page.keyboard.press('Delete')
await expect(page.locator('[data-type=Shape]')).toHaveCount(0)
})

test('create a block', async ({ page }) => {
const canvas = await page.waitForSelector('.logseq-tldraw')
const bounds = (await canvas.boundingBox())!
Expand Down Expand Up @@ -183,13 +227,7 @@ test('copy/paste youtube video url to create a Youtube shape', async ({ page })

await page.keyboard.press(modKey + '+v')

await expect( page.locator('.logseq-tldraw .tl-youtube-container')).toHaveCount(1)
})

test('cleanup the shapes', async ({ page }) => {
await page.keyboard.press(`${modKey}+a`)
await page.keyboard.press('Delete')
await expect(page.locator('[data-type=Shape]')).toHaveCount(0)
await expect(page.locator('.logseq-tldraw .tl-youtube-container')).toHaveCount(1)
})

test('zoom in', async ({ page }) => {
Expand Down
7 changes: 6 additions & 1 deletion src/main/frontend/components/block.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,11 @@
(:db/id page-entity)
:page))

(and (gobj/get e "altKey") (whiteboard-handler/inside-portal? (.-target e)))
(whiteboard-handler/add-new-block-portal-shape!
page-name
(whiteboard-handler/closest-shape (.-target e)))

whiteboard-page?
(route-handler/redirect-to-whiteboard! page-name)

Expand Down Expand Up @@ -884,7 +889,7 @@
(:db/id block)
:block-ref)

(whiteboard-handler/inside-portal? (.-target e))
(and (gobj/get e "altKey") (whiteboard-handler/inside-portal? (.-target e)))
(whiteboard-handler/add-new-block-portal-shape!
(:block/uuid block)
(whiteboard-handler/closest-shape (.-target e)))
Expand Down
7 changes: 3 additions & 4 deletions tldraw/apps/tldraw-logseq/src/components/AppUI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ import { ActionBar } from './ActionBar'
import { DevTools } from './Devtools'
import { PrimaryTools } from './PrimaryTools'
import { StatusBar } from './StatusBar'

const isDev = process.env.NODE_ENV === 'development'
import { isDev } from '@tldraw/core'

export const AppUI = observer(function AppUI() {
return (
<>
{isDev && <StatusBar />}
{isDev && <DevTools />}
{isDev() && <StatusBar />}
{isDev() && <DevTools />}
<PrimaryTools />
<ActionBar />
</>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useApp } from '@tldraw/react'
import { MOD_KEY, AlignType, DistributeType } from '@tldraw/core'
import { MOD_KEY, AlignType, DistributeType, isDev } from '@tldraw/core'
import { observer } from 'mobx-react-lite'
import { TablerIcon } from '../icons'
import { Button } from '../Button'
Expand Down Expand Up @@ -27,10 +27,7 @@ export const ContextMenu = observer(function ContextMenu({
}

const developerMode = React.useMemo(() => {
return (
window?.logseq?.api?.get_state_from_store?.('ui/developer-mode?') ||
process.env.NODE_ENV === 'development'
)
return isDev()
}, [])

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ export const DevTools = observer(() => {
<>
{originPoint}
{rendererStatus}
<HistoryStack />
</>
)
})
2 changes: 1 addition & 1 deletion tldraw/apps/tldraw-logseq/src/lib/shapes/BoxShape.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export class BoxShape extends TLBoxShape<BoxShapeProps> {
)

return (
<div {...events} style={{ width: '100%', height: '100%', overflow: 'hidden' }}>
<div {...events} style={{ width: '100%', height: '100%', overflow: 'hidden' }} className="tl-box-container">
<TextLabel
font={font}
text={label}
Expand Down
2 changes: 1 addition & 1 deletion tldraw/apps/tldraw-logseq/src/lib/shapes/LineShape.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export class LineShape extends TLLineShape<LineShapeProps> {
[label]
)
return (
<div {...events} style={{ width: '100%', height: '100%', overflow: 'hidden' }}>
<div {...events} style={{ width: '100%', height: '100%', overflow: 'hidden' }} className="tl-line-container">
<TextLabel
font={font}
text={label}
Expand Down
6 changes: 2 additions & 4 deletions tldraw/apps/tldraw-logseq/src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -243,17 +243,15 @@ html[data-theme='light'] {
}

.tl-statusbar {
@apply fixed flex items-center w-full bottom-0;
@apply absolute flex items-center w-full bottom-0;

background: var(--ls-secondary-background-color);
font-family: monospace;
font-size: 10px;
grid-row: 3;
padding: 8px;
color: black;
z-index: 100000;
user-select: none;
background: white;
border-top: 1px solid var(--ls-secondary-border-color);
flex-shrink: 0;
height: 32px;
}
Expand Down
17 changes: 17 additions & 0 deletions tldraw/packages/core/src/lib/TLApp/TLApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,23 @@ export class TLApp<
}
})

const deleteBinding = (shapeA: string, shapeB: string) => {
if ([...ids].includes(shapeA) && this.getShapeById(shapeB)?.type === "line")
ids.add(shapeB)
}

this.currentPage.shapes
.flatMap(s => Object.values(s.props.handles ?? {}))
.flatMap(h => h.bindingId)
.filter(isNonNullable)
.map(binding => {
const toId = this.currentPage.bindings[binding]?.toId
const fromId = this.currentPage.bindings[binding]?.fromId
if (toId && fromId) {
deleteBinding(toId, fromId)
deleteBinding(fromId, toId)
}})

const allShapesToDelete = [...ids].map(id => this.getShapeById(id)!)

this.setSelectedShapes(this.selectedShapesArray.filter(shape => !ids.has(shape.id)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export class BrushingState<
onExit = () => {
this.initialSelectedIds = []
this.tree.clear()
this.app.setBrush(undefined)
}

onPointerMove: TLEvents<S>['pointer'] = () => {
Expand Down
4 changes: 4 additions & 0 deletions tldraw/packages/core/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ export function isDarwin(): boolean {
return /Mac|iPod|iPhone|iPad/.test(window.navigator.platform)
}

export function isDev():boolean {
return window?.logseq?.api?.get_state_from_store?.('ui/developer-mode?') || process.env.NODE_ENV === 'development'
}

/**
* Migrated from frontend.util/safari?
*/
Expand Down
12 changes: 9 additions & 3 deletions tldraw/packages/react/src/hooks/useZoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,22 @@ import { autorun } from 'mobx'
import * as React from 'react'
import { useApp } from './useApp'
import { useRendererContext } from './useRendererContext'
import { debounce } from '@tldraw/core'

export function useZoom(ref: React.RefObject<HTMLDivElement>) {
const { viewport } = useRendererContext()
const app = useApp()

React.useLayoutEffect(() => {
return autorun(() => {
const zoom = viewport.camera.zoom
if (app.inputs.state !== 'pinching' && zoom != null) {
ref.current?.style.setProperty('--tl-zoom', zoom.toString())
const debouncedZoom = debounce(() => {
ref.current?.style.setProperty('--tl-zoom', viewport.camera.zoom.toString())
}, 200);

if (app.inputs.state !== 'pinching' && viewport.camera.zoom != null) {
debouncedZoom()
}
})
}, [])

}