Skip to content

Commit

Permalink
Feat/loro (#93)
Browse files Browse the repository at this point in the history
* feat: add loro

* feat: sync from blocky to loro

* fix: search context

* fix: sync states

* feat: async get loro

* feat: introduce idb

* feat: write data to store

* feat: add active state

* feat: adjust color

* refactor: themeSwitch

* feat: upgrade loro for new data structures

* feat: bind text events

* fix: build errors
  • Loading branch information
vincentdchan authored Nov 27, 2023
1 parent 796abe2 commit 5f14f42
Show file tree
Hide file tree
Showing 20 changed files with 631 additions and 63 deletions.
2 changes: 1 addition & 1 deletion packages/blocky-core/src/block/textBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ export class TextBlock extends ContentBlock {
}

if (textType === TextType.Normal) {
return { x: 0, y: 2 };
return { x: 0, y: -2 };
}

return { x: 0, y: 0 };
Expand Down
2 changes: 1 addition & 1 deletion packages/blocky-core/src/block/titleBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class TitleBlock extends Block {
changeset.forceUpdate = true;
}

this.editor.textInput.next(
this.editor.textInput$.next(
new TextInputEvent(beforeDelta, diff, blockElement)
);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/blocky-core/src/data/change.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ describe("merge", () => {
});
const state = new State("User-1", document);
const change = new Changeset(state);
change.deleteChildrenAt(document, 0, 1);
change.deleteChildrenAt(document.body, 0, 1);
change.textEdit(textBlock2, "textContent", () => new Delta().insert("a"));
const finalizedChangeset = change.finalize();
expect(finalizedChangeset.operations.length).toBe(2);
Expand Down
24 changes: 20 additions & 4 deletions packages/blocky-core/src/data/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import type { ElementChangedEvent } from "./events";

export interface DeltaChangedEvent {
oldDelta: Delta;
newDelta: Delta;
newDelta?: Delta;
apply: Delta;
}

export interface AttributesObject {
Expand Down Expand Up @@ -52,6 +53,7 @@ export class BlockyTextModel {
#delta = new Delta();
#cachedString: string | undefined;
#cachedLength: number | undefined;
changed$ = new Subject<DeltaChangedEvent>();

constructor(delta?: Delta) {
this.#delta = delta ?? new Delta();
Expand Down Expand Up @@ -100,6 +102,12 @@ export class BlockyTextModel {
this.#delta = newDelta;
this.#cachedString = undefined;
this.#cachedLength = undefined;

this.changed$.next({
oldDelta,
newDelta,
apply: v,
});
}

toString(): string {
Expand Down Expand Up @@ -208,6 +216,11 @@ export class DataBaseElement implements DataBaseNode {
const oldValue = this.#attributes[name];
this.#attributes[name] = value;

if (value instanceof DataBaseElement) {
value.parent = this;
this.doc?.reportBlockyNodeInserted(value);
}

if (typeof value === "object" && typeof value.t === "string") {
this.__backMap.set(value, name);
}
Expand Down Expand Up @@ -686,6 +699,7 @@ export class BlockyDocument extends DataElement {
readonly blockElementRemoved = new Subject<BlockDataElement>();

constructor(props?: Partial<DocumentInitProps>) {
super("document", undefined, []);
let title: BlockDataElement | undefined;
if (!isUndefined(props?.title)) {
if (props?.title instanceof BlockDataElement) {
Expand All @@ -701,16 +715,13 @@ export class BlockyDocument extends DataElement {
const body =
props?.body ??
new DataElement("body", undefined, props?.bodyChildren ?? []);
super("document", undefined, []);

this.__setAttribute("title", title);
this.__setAttribute("body", body);

if (this.title) {
this.__symInsertAfter(this.title);
this.reportBlockyNodeInserted(this.title);
}
this.__symInsertAfter(this.body);
this.reportBlockyNodeInserted(this.body);
}

Expand Down Expand Up @@ -762,6 +773,11 @@ export function traverseNode(
fun(node);

if (node instanceof DataElement) {
for (const value of Object.values(node.getAttributes())) {
if (value instanceof DataBaseElement) {
traverseNode(value, fun);
}
}
let ptr = node.firstChild;
while (ptr) {
traverseNode(ptr, fun);
Expand Down
9 changes: 8 additions & 1 deletion packages/blocky-core/src/model/searchContext.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IDisposable } from "blocky-common/es";
import { Subject } from "rxjs";
import { elem, removeNode, ContainerWithCoord } from "blocky-common/es/dom";
import { BlockDataElement, DataBaseNode } from "@pkg/data";
import { BlockDataElement, DataBaseElement, DataBaseNode } from "@pkg/data";
import { isString, isObject } from "lodash-es";
import { Editor } from "@pkg/view/editor";

Expand Down Expand Up @@ -210,6 +210,13 @@ export class SearchContext implements IDisposable {
}

#iterateNode(node: DataBaseNode) {
if (node instanceof DataBaseElement) {
for (const value of Object.values(node.getAttributes())) {
if (value instanceof DataBaseElement) {
this.#iterateNode(value);
}
}
}
if (node instanceof BlockDataElement) {
this.#searchBlockElement(node);
}
Expand Down
29 changes: 17 additions & 12 deletions packages/blocky-core/src/view/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
} from "@pkg/data";
import type { Editor } from "@pkg/view/editor";
import { TextBlock } from "@pkg/block/textBlock";
import { TitleBlock } from "@pkg/block/titleBlock";

function ensureChild<K extends keyof HTMLElementTagNameMap>(
dom: HTMLElement,
Expand Down Expand Up @@ -133,20 +134,24 @@ export class DocRenderer {
const state = this.editor.state;
const blockElement = state.getBlockElementById(operation.id);
if (!blockElement) {
// has been deleted?
console.warn("blockElement not found", operation.id);
return;
}
if (blockElement.t !== TextBlock.Name) {
return;
}
const block = state.blocks.get(operation.id);
const dom = state.domMap.get(operation.id);
if (block && dom) {
block.render?.(dom as HTMLElement, {
changeset,
operation,
flags: RenderFlag.Incremental,
});
if (blockElement.t === TextBlock.Name) {
const block = state.blocks.get(operation.id);
const dom = state.domMap.get(operation.id);
if (block && dom) {
block.render?.(dom as HTMLElement, {
changeset,
operation,
flags: RenderFlag.Incremental,
});
}
} else if (blockElement.t === TitleBlock.Name) {
const dom = state.domMap.get(operation.id);
if (dom) {
this.renderTitle(dom as HTMLElement, blockElement);
}
}
}

Expand Down
20 changes: 5 additions & 15 deletions packages/blocky-example/app/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
max-width: 260px;
border-right-style: solid;
border-right-width: 1px;
border-right-color: grey;
border-right-color: var(--border-color);
flex-shrink: 0;
padding-top: 1rem;

Expand All @@ -36,7 +36,6 @@
}
}


.blocky-example-container {
height: 100%;
overflow-x: hidden;
Expand All @@ -60,12 +59,16 @@ body {

:root {
--bg-color: white;
--border-color: #e0e0e0;
--hover-color: rgba(0, 0, 0, 0.1);
--primary-text-color: black;
--danger-color: rgb(201, 56, 56);
}

[data-theme="dark"] {
--bg-color: #161625;
--border-color: #1d1d2b;
--hover-color: rgba(255, 255, 255, 0.1);
--primary-text-color: #c3c3bf;
}

Expand Down Expand Up @@ -104,19 +107,6 @@ body {
}
}

/*Simple css to style it like a toggle switch*/
.theme-switch-wrapper {
display: flex;
align-items: center;

p {
margin-left: 10px;
font-size: 13px;
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
color: var(--primary-text-color);
}
}

.theme-switch {
display: inline-block;
height: 20px;
Expand Down
13 changes: 13 additions & 0 deletions packages/blocky-example/app/loro/loroExample.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

.editorContainer {
width: 100%;
display: flex;

:global(.blocky-editor-container) {
flex: 1;
}

:global(.blocky-documents) {
width: 580px;
}
}
Loading

1 comment on commit 5f14f42

@vercel
Copy link

@vercel vercel bot commented on 5f14f42 Nov 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.