mirror of https://github.com/logseq/logseq
quick add block shape
parent
a2103a0d45
commit
fcd158fdc8
|
@ -193,7 +193,9 @@
|
|||
[shape]
|
||||
{:block/content (case (:type shape)
|
||||
"text" (:text shape)
|
||||
"logseq-portal" (str "[[" (:pageId shape) "]]")
|
||||
"logseq-portal" (if (= (:blockType shape) "P")
|
||||
(str "[[" (:pageId shape) "]]")
|
||||
(str "((" (:pageId shape) "))"))
|
||||
"line" (str "whiteboard arrow" (when-let [label (:label shape)] (str ": " label)))
|
||||
(str "whiteboard " (:type shape)))})
|
||||
|
||||
|
@ -218,7 +220,7 @@
|
|||
page-entity (build-page-entity {} file page-name page-name nil options)
|
||||
page-block (merge page-block page-entity (when-not (:block/uuid page-block) {:block/uuid (d/squuid)}))
|
||||
blocks (->> blocks
|
||||
(map #(merge % {:block/level 1
|
||||
(map #(merge % {:block/level 1 ;; fixme
|
||||
:block/uuid (or (:block/uuid %)
|
||||
(gp-block/get-custom-id-or-new-id (:block/properties %)))}
|
||||
(with-whiteboard-block-props %)))
|
||||
|
|
|
@ -62,7 +62,9 @@
|
|||
:Block block-cp
|
||||
:Breadcrumb breadcrumb
|
||||
:PageNameLink page-name-link}
|
||||
:searchHandler (comp clj->js vec search/page-search)
|
||||
:handlers (clj->js {:search (comp clj->js vec search/page-search)
|
||||
:addNewBlock (fn [content]
|
||||
(str (whiteboard-handler/add-new-block! name content)))})
|
||||
:onMount (fn [app] (set-tln ^js app))
|
||||
:onPersist (fn [app]
|
||||
(let [document (gobj/get app "serialized")]
|
||||
|
|
|
@ -75,10 +75,16 @@
|
|||
:block/original-name original-page-name
|
||||
:block/whiteboard? true
|
||||
:block/properties (dissoc tldr-data :shapes)}
|
||||
;; todo: use get-paginated-blocks instead?
|
||||
existing-blocks (model/get-page-blocks-no-cache page-name)
|
||||
shapes (:shapes tldr-data)
|
||||
blocks (mapv #(shape->block % page-name) shapes)
|
||||
block-ids (set (map :block/uuid blocks))
|
||||
block-ids (->> shapes
|
||||
(map (fn [shape] (when (= (:blockType shape) "B")
|
||||
(uuid (:pageId shape)))))
|
||||
(concat (map :block/uuid blocks))
|
||||
(remove nil?)
|
||||
(set))
|
||||
delete-shapes (filter (fn [shape]
|
||||
(not (block-ids (:block/uuid shape))))
|
||||
existing-blocks)
|
||||
|
@ -166,3 +172,14 @@
|
|||
point (js->clj (.. (get-tldr-app) -viewport (getPagePoint #js[client-x client-y])))
|
||||
shape (->logseq-portal-shape block-id point)]
|
||||
(.createShapes api (clj->js shape))))
|
||||
|
||||
(defn add-new-block!
|
||||
[page-name content]
|
||||
(let [uuid (d/squuid)
|
||||
tx {:block/uuid uuid
|
||||
:block/content (or content "")
|
||||
:block/format :markdown ; fixme
|
||||
:block/page {:block/name (util/page-name-sanity-lc page-name)}
|
||||
:block/parent {:block/name page-name}}]
|
||||
(db-utils/transact! [tx])
|
||||
uuid))
|
||||
|
|
|
@ -21,9 +21,11 @@
|
|||
[]
|
||||
(empty? @write-chan-batch-buf))
|
||||
|
||||
(def blocks-pull-keys-with-persisted-ids
|
||||
(def whiteboard-blocks-pull-keys-with-persisted-ids
|
||||
'[:block/properties
|
||||
:block/uuid
|
||||
:block/content
|
||||
:block/format
|
||||
{:block/page [:block/name :block/uuid]}
|
||||
{:block/left [:block/name :block/uuid]}
|
||||
{:block/parent [:block/name :block/uuid]}
|
||||
|
@ -33,8 +35,11 @@
|
|||
[repo page-db-id]
|
||||
(let [page-block (db/pull repo '[*] page-db-id)
|
||||
whiteboard? (:block/whiteboard? page-block)
|
||||
blocks (model/get-page-blocks-no-cache repo (:block/name page-block)
|
||||
{:pull-keys (if whiteboard? blocks-pull-keys-with-persisted-ids '[*])})]
|
||||
blocks (model/get-page-blocks-no-cache
|
||||
repo (:block/name page-block)
|
||||
{:pull-keys (if whiteboard? whiteboard-blocks-pull-keys-with-persisted-ids '[*])})
|
||||
blocks (map #(if (get-in % [:block/properties :ls-type] false)
|
||||
(dissoc % :block/content :block/format) %) blocks)]
|
||||
(when-not (and (= 1 (count blocks))
|
||||
(string/blank? (:block/content (first blocks)))
|
||||
(nil? (:block/file page-block)))
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
AppProvider,
|
||||
TLReactCallbacks,
|
||||
TLReactComponents,
|
||||
TLReactToolConstructor
|
||||
TLReactToolConstructor,
|
||||
} from '@tldraw/react'
|
||||
import * as React from 'react'
|
||||
import { AppUI } from '~components/AppUI'
|
||||
|
@ -22,8 +22,9 @@ import {
|
|||
LineTool,
|
||||
LogseqPortalTool,
|
||||
NuEraseTool,
|
||||
PencilTool, TextTool,
|
||||
YouTubeTool
|
||||
PencilTool,
|
||||
TextTool,
|
||||
YouTubeTool,
|
||||
} from '~lib/tools'
|
||||
|
||||
const components: TLReactComponents<Shape> = {
|
||||
|
@ -51,13 +52,16 @@ interface LogseqTldrawProps {
|
|||
Breadcrumb: React.FC
|
||||
PageNameLink: React.FC
|
||||
}
|
||||
searchHandler: (query: string) => string[]
|
||||
handlers: {
|
||||
search: (query: string) => string[]
|
||||
addNewBlock: (content: string) => string
|
||||
}
|
||||
model?: TLDocumentModel<Shape>
|
||||
onMount?: TLReactCallbacks<Shape>['onMount']
|
||||
onPersist?: TLReactCallbacks<Shape>['onPersist']
|
||||
}
|
||||
|
||||
export const App = function App({ searchHandler, ...props }: LogseqTldrawProps): JSX.Element {
|
||||
export const App = function App(props: LogseqTldrawProps): JSX.Element {
|
||||
const onFileDrop = useFileDrop()
|
||||
const onPaste = usePaste()
|
||||
const onQuickAdd = useQuickAdd()
|
||||
|
@ -71,7 +75,12 @@ export const App = function App({ searchHandler, ...props }: LogseqTldrawProps):
|
|||
}, [])
|
||||
|
||||
return (
|
||||
<LogseqContext.Provider value={{ renderers, search: searchHandler }}>
|
||||
<LogseqContext.Provider
|
||||
value={{
|
||||
renderers,
|
||||
handlers: props.handlers,
|
||||
}}
|
||||
>
|
||||
<AppProvider
|
||||
Shapes={shapes}
|
||||
Tools={tools}
|
||||
|
|
|
@ -15,6 +15,9 @@ export const LogseqContext = React.createContext<
|
|||
pageName: string
|
||||
}>
|
||||
}
|
||||
search: (query: string) => string[]
|
||||
handlers: {
|
||||
search: (query: string) => string[]
|
||||
addNewBlock: (content: string) => string // returns the new block uuid
|
||||
}
|
||||
}>
|
||||
>({})
|
||||
|
|
|
@ -30,17 +30,23 @@ interface LogseqQuickSearchProps {
|
|||
const LogseqQuickSearch = observer(({ onChange }: LogseqQuickSearchProps) => {
|
||||
const [q, setQ] = React.useState('')
|
||||
const rInput = React.useRef<HTMLInputElement>(null)
|
||||
const { search } = React.useContext(LogseqContext)
|
||||
const { handlers } = React.useContext(LogseqContext)
|
||||
|
||||
const commitChange = React.useCallback((id: string) => {
|
||||
setQ(id)
|
||||
const finishCreating = React.useCallback((id: string) => {
|
||||
onChange(id)
|
||||
rInput.current?.blur()
|
||||
}, [])
|
||||
|
||||
const onAddBlock = React.useCallback((content: string) => {
|
||||
const uuid = handlers?.addNewBlock(content)
|
||||
if (uuid) {
|
||||
finishCreating(uuid)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const options = React.useMemo(() => {
|
||||
return search?.(q)
|
||||
}, [search, q])
|
||||
return handlers?.search?.(q)
|
||||
}, [handlers?.search, q])
|
||||
|
||||
React.useEffect(() => {
|
||||
// autofocus seems not to be working
|
||||
|
@ -62,17 +68,19 @@ const LogseqQuickSearch = observer(({ onChange }: LogseqQuickSearchProps) => {
|
|||
onChange={q => setQ(q.target.value)}
|
||||
onKeyDown={e => {
|
||||
if (e.key === 'Enter') {
|
||||
commitChange(q)
|
||||
finishCreating(q)
|
||||
}
|
||||
}}
|
||||
className="tl-quick-search-input text-input"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="tl-quick-search-options">
|
||||
<div className="tl-quick-search-option" onClick={() => onAddBlock(q)}>
|
||||
New block{q.length > 0 ? `: ${q}` : ''}
|
||||
</div>
|
||||
{options?.map(name => (
|
||||
<div key={name} className="tl-quick-search-option" onClick={() => commitChange(name)}>
|
||||
<div key={name} className="tl-quick-search-option" onClick={() => finishCreating(name)}>
|
||||
{name}
|
||||
</div>
|
||||
))}
|
||||
|
@ -372,10 +380,12 @@ export class LogseqPortalShape extends TLBoxShape<LogseqPortalShapeProps> {
|
|||
|
||||
const onPageNameChanged = React.useCallback((id: string) => {
|
||||
this.initialHeightCalculated = false
|
||||
const blockType = validUUID(id) ? 'B' : 'P'
|
||||
this.update({
|
||||
pageId: id,
|
||||
size: [600, 320],
|
||||
blockType: validUUID(id) ? 'B' : 'P',
|
||||
size: [400, 320],
|
||||
blockType: blockType,
|
||||
compact: blockType === 'B',
|
||||
})
|
||||
app.selectTool('select')
|
||||
app.history.resume()
|
||||
|
|
|
@ -146,7 +146,10 @@ export default function App() {
|
|||
Breadcrumb,
|
||||
PageNameLink,
|
||||
}}
|
||||
searchHandler={q => (q ? list : [])}
|
||||
handlers={{
|
||||
search: q => (q ? list : []),
|
||||
addNewBlock: q => q,
|
||||
}}
|
||||
model={documentModel}
|
||||
onPersist={onPersist}
|
||||
/>
|
||||
|
|
Loading…
Reference in New Issue