fix: enhance pan / overscroll check

pull/5775/head
Peng Xiao 2022-05-18 06:43:15 +08:00
parent 5dc06093ec
commit 6e5e686a52
8 changed files with 96 additions and 25 deletions

View File

@ -298,6 +298,7 @@
:route-match route-match}) :route-match route-match})
[:div#main-content-container.scrollbar-spacing.w-full.flex.justify-center.flex-row [:div#main-content-container.scrollbar-spacing.w-full.flex.justify-center.flex-row
{:data-is-margin-less-pages margin-less-pages?}
[:div.cp__sidebar-main-content [:div.cp__sidebar-main-content
{:data-is-margin-less-pages margin-less-pages? {:data-is-margin-less-pages margin-less-pages?

View File

@ -46,11 +46,15 @@
#main-content { #main-content {
position: relative; position: relative;
height: calc(100vh - var(--ls-headbar-height)); height: calc(100vh - var(--ls-headbar-height));
}
&-container { #main-content-container {
@apply p-4 sm:px-8; @apply p-4 sm:px-8;
font-size: 1em; font-size: 1em;
} }
#main-content-container[data-is-margin-less-pages=true] {
padding: 0;
} }
.left-sidebar-inner { .left-sidebar-inner {

View File

@ -35,4 +35,7 @@
[state] [state]
(let [name (get-whiteboard-name state) (let [name (get-whiteboard-name state)
tldr-name (str "draws/" name ".tldr")] tldr-name (str "draws/" name ".tldr")]
(tldraw-app {:file tldr-name}))) [:div.absolute.w-full.h-full
;; makes sure the whiteboard will not cover the borders
{:style {:padding "0.5px"}}
(tldraw-app {:file tldr-name})]))

View File

@ -0,0 +1,3 @@
.logseq-tldraw .tl-container {
background-color: var(--ls-secondary-background-color);
}

View File

@ -24,22 +24,21 @@
[state data option] [state data option]
(let [{:keys [file]} option] (let [{:keys [file]} option]
(when file (when file
[:div.overflow-hidden.draw.tldraw [:div.draw.tldraw.relative.w-full.h-full
{:style {:overscroll-behavior "none"}} {:style {:overscroll-behavior "none"}
[:div.draw-wrap.relative :on-blur #(state/set-block-component-editing-mode! false)
{:on-blur #(state/set-block-component-editing-mode! false) ;; wheel -> overscroll may cause browser navigation
:on-wheel util/stop-propagation ;; wheel -> overscroll may cause browser navigation :on-wheel util/stop-propagation}
:style {:height "calc(100vh - 80px)"}}
(tldraw {:PageComponent page (tldraw {:PageComponent page
:searchHandler (comp clj->js vec search/page-search) :searchHandler (comp clj->js vec search/page-search)
:onPersist (fn [app] :onPersist (fn [app]
(let [document (gobj/get app "serialized") (let [document (gobj/get app "serialized")
s (js/JSON.stringify document)] s (js/JSON.stringify document)]
(draw-handler/save-draw! file s))) (draw-handler/save-draw! file s)))
:model data :model data
:onApp (fn [app] :onApp (fn [app]
(state/set-state! [:ui/whiteboards (::id state)] app))})]]))) (state/set-state! [:ui/whiteboards (::id state)] app))})])))
(rum/defc tldraw-app (rum/defc tldraw-app
[option] [option]

View File

@ -8,7 +8,7 @@ export const AppUI = observer(function AppUI() {
return ( return (
<> <>
{/* <ToolBar /> */} {/* <ToolBar /> */}
<StatusBar /> {/* <StatusBar /> */}
<PrimaryTools /> <PrimaryTools />
</> </>
) )

View File

@ -0,0 +1,57 @@
import * as React from 'react'
import { useApp } from '@tldraw/react'
import { useGesture } from '@use-gesture/react'
import type { TLViewport } from '@tldraw/core'
function useSampling(fn: () => void, rate: number) {
React.useEffect(() => {
const interval = setInterval(fn, 1000 / rate)
return () => clearInterval(interval)
}, [fn, rate])
}
function now() {
return new Date().getTime()
}
export function useCameraMovingRef(bias = 10, timeout = 1000) {
const app = useApp()
const movingRef = React.useRef<boolean>(false)
const prevCamera = React.useRef<TLViewport['camera']>()
const lastMovingRef = React.useRef<number>(now())
const sampleFn = React.useCallback(() => {
const { point, zoom } = app.viewport.camera
if (prevCamera.current) {
const { point: prevPoint } = prevCamera.current
const moving = Math.abs(point[0] - prevPoint[0]) + Math.abs(point[1] - prevPoint[1]) > bias
if (moving) {
movingRef.current = true
lastMovingRef.current = now()
} else if (now() - lastMovingRef.current > timeout) {
movingRef.current = false
}
}
prevCamera.current = {
point: [...point],
zoom,
}
}, [app])
useGesture(
{
// immediately set moving to false
onMouseDown: () => {
movingRef.current = false
},
},
{
eventOptions: {
capture: true,
},
target: window
}
)
useSampling(sampleFn, 30)
return movingRef
}

View File

@ -9,6 +9,7 @@ import { CustomStyleProps, withClampedStyles } from './style-props'
import { TextInput } from '~components/inputs/TextInput' import { TextInput } from '~components/inputs/TextInput'
import { LogseqContext } from '~lib/logseq-context' import { LogseqContext } from '~lib/logseq-context'
import type { Shape } from '~lib' import type { Shape } from '~lib'
import { useCameraMovingRef } from '~hooks/useCameraMoving'
export interface LogseqPortalShapeProps extends TLBoxShapeProps, CustomStyleProps { export interface LogseqPortalShapeProps extends TLBoxShapeProps, CustomStyleProps {
type: 'logseq-portal' type: 'logseq-portal'
@ -100,17 +101,20 @@ export class LogseqPortalShape extends TLBoxShape<LogseqPortalShapeProps> {
} = this } = this
const app = useApp<Shape>() const app = useApp<Shape>()
const isMoving = useCameraMovingRef()
const { Page } = React.useContext(LogseqContext) const { Page } = React.useContext(LogseqContext)
const isSelected = app.selectedIds.has(this.id) const isSelected = app.selectedIds.has(this.id)
const disableTlEvents = !isEditing && !isSelected && app.selectedTool.id !== 'select' const enableTlEvents = () => {
return isMoving.current || isEditing || isSelected || app.selectedTool.id !== 'select'
}
const stop = React.useCallback( const stop = React.useCallback(
e => { e => {
if (!disableTlEvents) { if (!enableTlEvents()) {
e.stopPropagation() e.stopPropagation()
} }
}, },
[disableTlEvents] [enableTlEvents]
) )
if (!Page) { if (!Page) {
@ -147,7 +151,7 @@ export class LogseqPortalShape extends TLBoxShape<LogseqPortalShapeProps> {
width: '100%', width: '100%',
overflow: 'auto', overflow: 'auto',
overscrollBehavior: 'none', overscrollBehavior: 'none',
height: pageId ? 'calc(100% - 32px)' : '100%', height: pageId ? 'calc(100% - 33px)' : '100%',
pointerEvents: isSelected ? 'none' : 'all', pointerEvents: isSelected ? 'none' : 'all',
userSelect: 'none', userSelect: 'none',
opacity: isSelected ? 0.5 : 1, opacity: isSelected ? 0.5 : 1,