Commit Graph

305 Commits

Author SHA1 Message Date
L-Sun
d8727c2001 fix(editor): close embed edit modal on editor unmount (#9765)
Close [BS-2436](https://linear.app/affine-design/issue/BS-2436/should-close-embed-card-edit-modal-after-editor-unmount)

### What Changes:
- fix(editor): close embed edit modal on editor unmount
- test(editor): add test to embed edit modal when switching mode
2025-01-17 11:53:09 +00:00
donteatfriedrice
df910d7013 feat(editor): add affine inline footnote (#9745)
[BS-2369](https://linear.app/affine-design/issue/BS-2369/新增-affinetextattribute-footnote)  [BS-2370](https://linear.app/affine-design/issue/BS-2370/支持-footnote-自定义渲染行内内容) [BS-2372](https://linear.app/affine-design/issue/BS-2372/提供-footnoteconfigextension) [BS-2375](https://linear.app/affine-design/issue/BS-2375/footnote-自定义渲染-popup)

### Add new AffineTextAttribute: footnote

```
/**
 * FootNote is used to reference a doc, attachment or url.
 */
export interface AffineTextAttributes {
  ...
  footnote?: {
    label: string; // label of the footnote
    reference: {
      type: 'doc' | 'attachment' | 'url'; // type of reference
      docId?: string; // the id of the reference doc
      url?: string; //  the url of the reference network resource
      blobId?: string; // the id of the reference attachment
      fileName?: string; // the name of the reference attachment
      fileType?: string; // the type of the reference attachment
    }
  } | null
}
```

### FootNoteNodeConfigProvider Extension

#### FootNoteNodeConfig Type Definition

```
type FootNoteNodeRenderer = (
  footnote: FootNote,
  std: BlockStdScope
) => TemplateResult<1>;

type FootNotePopupRenderer = (
  footnote: FootNote,
  std: BlockStdScope,
  abortController: AbortController
) => TemplateResult<1>;

export interface FootNoteNodeConfig {
  customNodeRenderer?: FootNoteNodeRenderer;
  customPopupRenderer?: FootNotePopupRenderer;
  interactive?: boolean;
  hidePopup?: boolean;
}
```

#### FootNoteNodeConfigProvider Class

```
export class FootNoteNodeConfigProvider {
  private _customNodeRenderer?: FootNoteNodeRenderer;
  private _customPopupRenderer?: FootNotePopupRenderer;
  private _hidePopup: boolean;
  private _interactive: boolean;

  get customNodeRenderer() {
    return this._customNodeRenderer;
  }

  get customPopupRenderer() {
    return this._customPopupRenderer;
  }

  get doc() {
    return this.std.store;
  }

  get hidePopup() {
    return this._hidePopup;
  }

  get interactive() {
    return this._interactive;
  }

  constructor(
    config: FootNoteNodeConfig,
    readonly std: BlockStdScope
  ) {
    this._customNodeRenderer = config.customNodeRenderer;
    this._customPopupRenderer = config.customPopupRenderer;
    this._hidePopup = config.hidePopup ?? false;
    this._interactive = config.interactive ?? true;
  }

  setCustomNodeRenderer(renderer: FootNoteNodeRenderer) {
    this._customNodeRenderer = renderer;
  }

  setCustomPopupRenderer(renderer: FootNotePopupRenderer) {
    this._customPopupRenderer = renderer;
  }

  setHidePopup(hidePopup: boolean) {
    this._hidePopup = hidePopup;
  }

  setInteractive(interactive: boolean) {
    this._interactive = interactive;
  }
}
```

#### FootNoteNodeConfigProvider Extension

```
export const FootNoteNodeConfigIdentifier =
  createIdentifier<FootNoteNodeConfigProvider>('AffineFootNoteNodeConfig');

export function FootNoteNodeConfigExtension(
  config: FootNoteNodeConfig
): ExtensionType {
  return {
    setup: di => {
      di.addImpl(
        FootNoteNodeConfigIdentifier,
        provider =>
          new FootNoteNodeConfigProvider(config, provider.get(StdIdentifier))
      );
    },
  };
}
```

The footnote node can be extended by this extension.

### FootnoteInlineSpec

```
export const FootNoteInlineSpecExtension = InlineSpecExtension(
  'footnote',
  provider => {
    const std = provider.get(StdIdentifier);
    const config =
      provider.getOptional(FootNoteNodeConfigIdentifier) ?? undefined;
    return {
      name: 'footnote',
      schema: FootNoteSchema.optional().nullable().catch(undefined),
      match: delta => {
        return !!delta.attributes?.footnote;
      },
      renderer: ({ delta }) => {
        return html`<affine-footnote-node
          .delta=${delta}
          .std=${std}
          .config=${config}
        ></affine-footnote-node>`;
      },
      embed: true,
    };
  }
);
```
2025-01-17 09:38:43 +00:00
CatsJuice
7d1d167858 chore: bump theme (#9732) 2025-01-17 09:22:15 +00:00
zzj3720
aa21ac6d64 refactor(editor): move database selection into the corresponding view (#9752) 2025-01-17 09:03:13 +00:00
doouding
b350dd1580 fix: legacy e2e test debug (#9746) 2025-01-17 04:26:59 +00:00
L-Sun
c2149f218b refactor(editor): enable toc dragging in page mode (#9736)
Related [BS-2322](https://linear.app/affine-design/issue/BS-2322/toc-排序坏掉部分的修复)
2025-01-16 17:53:28 +00:00
EYHN
a2ffdb4047 feat(core): new worker workspace engine (#9257) 2025-01-16 16:22:18 +00:00
pengx17
7dc470e7ea feat(core): add new bs dnd adapter (#9717) 2025-01-16 13:54:50 +00:00
doouding
99717196c5 refactor: rewrite blocksuite dnd (#9595)
### Changed

- Refactored BlockSuite drag-and-drop using @atlaskit/pragmatic-drag-and-drop/element/adapter.
- Updated block dragging to use the new drag-and-drop infrastructure.

### BlockSuite DND API

Access the BlockSuite drag-and-drop API via `std.dnd`. This is a lightweight wrapper around pragmatic-drag-and-drop, offering convenient generic types and more intuitive option names.

#### Drag payload structure
There's some constrain about drag payload. The whole drag payload looks like this:

```typescript
type DragPayload = {
  entity: {
    type: string
  },
  from: {
    at: 'blocksuite',
    docId: string
  }
}
```
- The `from` field is auto-generated—no need for manual handling.
- The `entity` field is customizable, but it must include a `type`.

All drag-and-drop methods accept a generic type for entity, ensuring more accurate payloads in event handlers.

```typescript
type BlockEntity = {
  type: 'blocks',
  blockIds: string[]
}

dnd.draggable<BlockEntity>({
  element: someElement,
  setDragData: () => {
    // the return type must satisfy the generic type
    // in this case, it's BlockEntity
    return {
      type: 'blocks',
      blockIds: []
    }
  }
});

dnd.monitor<BlockEntity>({
  // the arguments is same for other event handler
  onDrag({ source }) {
    // the type of this is BlockEntity
    source.data.entity
  }
})
```

#### Drop payload
When hover on droppable target. You can set drop payload as well. All drag-and-drop methods accept a second generic type for drop payload.

The drop payload is customizable. Additionally, the DND system will add an `edge` field to the final payload object, indicating the nearest edge of the drop target relative to the current drag position.

```typescript
type DropPayload = {
  blockId: string;
}

dnd.dropTarget<BlockEntity, DropPayload>({
  getData() {
    // the type should be DropPayload
    return {
      blockId: 'someId'
    }
  }
});

dnd.monitor<BlockEntity, DropPayload>({
  // drag over on drop target
  onDrag({ location }) {
    const target = location.current.dropTargets[0];

    // the type is DropPayload
    target.data;
    // retrieve the nearest edge of the drop target relative to the current drop position.
    target.data.edge;
  }
})
```
2025-01-16 12:36:58 +00:00
renovate
908afe19ee chore: bump up file-type version to v20 (#9731)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [file-type](https://redirect.github.com/sindresorhus/file-type) | [`^19.6.0` -> `^20.0.0`](https://renovatebot.com/diffs/npm/file-type/19.6.0/20.0.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/file-type/20.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/file-type/20.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/file-type/19.6.0/20.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/file-type/19.6.0/20.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) |
| [file-type](https://redirect.github.com/sindresorhus/file-type) | [`^19.5.0` -> `^20.0.0`](https://renovatebot.com/diffs/npm/file-type/19.6.0/20.0.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/file-type/20.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/file-type/20.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/file-type/19.6.0/20.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/file-type/19.6.0/20.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>sindresorhus/file-type (file-type)</summary>

### [`v20.0.0`](https://redirect.github.com/sindresorhus/file-type/releases/tag/v20.0.0)

[Compare Source](https://redirect.github.com/sindresorhus/file-type/compare/v19.6.0...v20.0.0)

##### Breaking

-   Drop MIME-type and extension enumeration in types ([#&#8203;693](https://redirect.github.com/sindresorhus/file-type/issues/693))  [`0ff11c6`](https://redirect.github.com/sindresorhus/file-type/commit/0ff11c6)
-   Remove `NodeFileTypeParser` in favor of using `FileTypeParser` on all platforms ([#&#8203;707](https://redirect.github.com/sindresorhus/file-type/issues/707))  [`ff8eed8`](https://redirect.github.com/sindresorhus/file-type/commit/ff8eed8)

##### Improvements

-   Give API access to `FileTypeParser#detectors` ([#&#8203;704](https://redirect.github.com/sindresorhus/file-type/issues/704))  [`7e72bbc`](https://redirect.github.com/sindresorhus/file-type/commit/7e72bbc)
-   Improve Nikon RAW NEF (Tiff) format detection ([#&#8203;670](https://redirect.github.com/sindresorhus/file-type/issues/670))  [`cf6fc1e`](https://redirect.github.com/sindresorhus/file-type/commit/cf6fc1e)
-   Add support for Java archive (`.jar`) ([#&#8203;719](https://redirect.github.com/sindresorhus/file-type/issues/719))  [`8651809`](https://redirect.github.com/sindresorhus/file-type/commit/8651809)
-   Add support for MSOffice macro-enabled docs and templates ([#&#8203;720](https://redirect.github.com/sindresorhus/file-type/issues/720))  [`7fe5667`](https://redirect.github.com/sindresorhus/file-type/commit/7fe5667)
-   Add support for OpenDocument graphics and templates ([#&#8203;718](https://redirect.github.com/sindresorhus/file-type/issues/718))  [`4db407d`](https://redirect.github.com/sindresorhus/file-type/commit/4db407d)
-   Add support for Microsoft Excel template with macros (.xltm) ([#&#8203;714](https://redirect.github.com/sindresorhus/file-type/issues/714))  [`1fe621a`](https://redirect.github.com/sindresorhus/file-type/commit/1fe621a)
-   Add support for Microsoft Word template (.dotx) ([#&#8203;713](https://redirect.github.com/sindresorhus/file-type/issues/713))  [`643ef78`](https://redirect.github.com/sindresorhus/file-type/commit/643ef78)
-   Add support for Microsoft Excel template (`.xltx`) ([#&#8203;712](https://redirect.github.com/sindresorhus/file-type/issues/712))  [`0dab3e0`](https://redirect.github.com/sindresorhus/file-type/commit/0dab3e0)
-   Add support for Microsoft PowerPoint template ( `.potx`) ([#&#8203;710](https://redirect.github.com/sindresorhus/file-type/issues/710))  [`f978619`](https://redirect.github.com/sindresorhus/file-type/commit/f978619)
-   Add support for ZIP decompression using `@tokenizer/inflate` ([#&#8203;695](https://redirect.github.com/sindresorhus/file-type/issues/695))  [`399b0f1`](https://redirect.github.com/sindresorhus/file-type/commit/399b0f1)
-   Add support for `.lz4` file format ([#&#8203;706](https://redirect.github.com/sindresorhus/file-type/issues/706))  [`74acf94`](https://redirect.github.com/sindresorhus/file-type/commit/74acf94)
-   Add support for format `.drc`, Google's Draco 3D Data Compression ([#&#8203;702](https://redirect.github.com/sindresorhus/file-type/issues/702))  [`e99257d`](https://redirect.github.com/sindresorhus/file-type/commit/e99257d)

##### Fixes

-   Fix code sequence "File Type Box" detection ([#&#8203;705](https://redirect.github.com/sindresorhus/file-type/issues/705))  [`7d4dd8d`](https://redirect.github.com/sindresorhus/file-type/commit/7d4dd8d)

***

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xMDcuMCIsInVwZGF0ZWRJblZlciI6IjM5LjEwNy4wIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
2025-01-16 10:08:14 +00:00
fundon
268e89911a perf(editor): fix autoUpdate being continuously added when updating selections (#9727)
Since `updated` is triggered every time click or update the selection, `autoUpdate` will be continuously added.

Case: select text and `Shift+ArrowLeft/ArrowRight`
2025-01-16 09:05:10 +00:00
L-Sun
969ac30874 fix(editor): reactive heading icon (#9729)
Close [BS-2407](https://linear.app/affine-design/issue/BS-2407/[bug]-edgeless-里选中-title-后更改,hint-没有改变)
2025-01-16 08:32:15 +00:00
doodlewind
509cdfd7bf fix(editor): playground font inconsistency (#9728) 2025-01-16 08:16:13 +00:00
fundon
676f855564 fix(editor): stop paste-copy event bubbling on bookmark modal (#9713)
Closes: [BS-2402](https://linear.app/affine-design/issue/BS-2402/bookmark-没法粘贴修改标题,会跑到下一行)
2025-01-16 06:34:09 +00:00
L-Sun
94c9717a35 feat(editor): edgeless page block toolbar (#9707)
Close [BS-2315](https://linear.app/affine-design/issue/BS-2315/page-block-header)

### What Changes
- Add header toolbar to page block (the first note in canvas)
- Add e2e tests
- Add some edgeless e2e test utils.  **The package `@blocksuite/affine` was added to `"@affine-test/kit"`**
2025-01-15 12:04:44 +00:00
fundon
0b2d11e6b1 fix(editor): text highlighting (#9708) 2025-01-15 10:57:27 +00:00
fundon
7002289c58 fix(editor): avoid drag and drag over updating drag indicator at the same time (#9656)
* add a `dragging` signal to the file drop manager
* `drag over` logic should  not be triggered  when inside app
* avoid drag and drag over updating `drag indicator` at the same time
2025-01-15 08:10:08 +00:00
donteatfriedrice
4f421efb22 fix(editor): init default theme observer value according to data-theme (#9698) 2025-01-15 04:04:06 +00:00
zzj3720
ff295f383f refactor(editor): enable the noUncheckedIndexedAccess rule for the block-database package (#9691)
close: BS-2269
2025-01-14 14:35:46 +00:00
donteatfriedrice
aa2a8fbf9b fix(editor): adapters panel type (#9690) 2025-01-14 11:02:00 +00:00
Yifeng Wang
777eea124d fix(editor): migrate basic playground examples (#9669) 2025-01-13 23:33:10 +08:00
zzj3720
80f8944188 fix(editor): should not update table selection after table is destroyed (#9665) 2025-01-13 10:43:02 +00:00
fundon
7e5e6031e8 chore(editor): update default colors of shape (#9633)
Closes: [PD-2176](https://linear.app/affine-design/issue/PD-2176/edgeless-shape默认颜色调整)

* updates shape's text color to the `#000000ff` and custom button should be selected by default in color picker
* updates shape background default color palette to `medium`

<img width="727" alt="Screenshot 2025-01-13 at 11 07 14" src="https://github.com/user-attachments/assets/81962741-0dbc-4990-8eec-db5e48624305" />
<img width="444" alt="Screenshot 2025-01-13 at 11 07 09" src="https://github.com/user-attachments/assets/2d119e33-635e-4bd4-826f-e3094c8a3fa2" />

<img width="764" alt="Screenshot 2025-01-13 at 11 08 14" src="https://github.com/user-attachments/assets/09f5c778-0e25-4972-8529-8d8323c27594" />
2025-01-13 10:19:58 +00:00
zzj3720
810e656174 fix(editor): add shift middleware for tag select panel (#9664)
fix: BS-1749
2025-01-13 09:05:05 +00:00
Brooooooklyn
e72371d15c style: use typescript resolver for eslint import plugin (#9662) 2025-01-13 05:56:29 +00:00
donteatfriedrice
5c4e87ddb5 feat(editor): support text highlight html adapter (#9632)
[BS-2061](https://linear.app/affine-design/issue/BS-2061/html-adapter-支持-text-highlight-样式)
2025-01-13 02:20:58 +00:00
Saul-Mirone
5b9256712e chore(editor): remove unused awareness slot (#9640) 2025-01-11 04:27:45 +00:00
Mirone
446b31b621 refactor(editor): rename job to transformer (#9639) 2025-01-11 12:04:07 +08:00
fundon
9fa35ed490 fix(editor): drag indicator flickering (#9636) 2025-01-11 03:15:07 +00:00
zzj3720
c016f8e37e feat(editor): support linked-doc in rich-text column (#9634)
close: BS-2345
2025-01-10 14:43:40 +00:00
zzj3720
cc08094b17 feat(editor): improve group title display for checkbox columns (#9622)
close: BS-1977
2025-01-10 14:01:12 +00:00
fundon
0b3dba614d perf(editor): optimize the search for the closest element (#9587)
Closes: [BS-2275](https://linear.app/affine-design/issue/BS-2275/拖拽-indicator-查找优化)
2025-01-10 08:21:10 +00:00
EYHN
18ff7500c8 fix(core): fix menu not close when click outside (#9535) 2025-01-10 08:04:49 +00:00
zzj3720
8e8058a44c feat(editor): support pasting Excel data into database block (#9618)
close: BS-2338
2025-01-09 14:35:19 +00:00
Saul-Mirone
6feb4def2f fix(editor): exisiting slice import should be move instead of add (#9616)
Closes: [BS-2339](https://linear.app/affine-design/issue/BS-2339/%E6%8B%96%E6%8B%BD%E9%87%8A%E6%94%BE%E5%90%8E%E7%9A%84%E4%BD%8D%E7%BD%AE%E4%B8%8D%E5%AF%B9)
2025-01-09 12:14:54 +00:00
Saul-Mirone
126ab18967 feat(editor): selection as store extension (#9605) 2025-01-09 11:49:23 +00:00
zzj3720
b23e980250 fix(editor): prototype-polluting assignment (#9606) 2025-01-09 08:20:26 +00:00
pengx17
f78857bb11 feat(editor): add more open doc options to editor toolbar (#9588)
fix AF-2036, AF-2092
2025-01-09 08:04:21 +00:00
doodlewind
890a962196 chore(editor): fix playground vscode tsc warning (#9603) 2025-01-09 07:49:16 +00:00
zzj3720
f46a7a073a fix(editor): component name for the mobile menu is incorrect (#9604) 2025-01-09 07:32:49 +00:00
Yifeng Wang
cac0b7fd66 refactor(editor): remove default entry (#9600) 2025-01-09 14:01:48 +08:00
Saul-Mirone
422bac6cbe refactor(editor): remove readonly in awareness (#9597) 2025-01-09 05:15:35 +00:00
Saul-Mirone
d21ef47ae8 chore(editor): rename std.doc to std.store (#9596) 2025-01-09 04:16:28 +00:00
akumatus
58ce86533e feat(core): support ai network search (#9357)
### What Changed?
- Add `PerplexityProvider` in backend.
- Update session prompt name if user toggle network search mode in chat panel.
- Add experimental flag for AI network search feature.
- Add unit tests and e2e tests.

Search results are streamed and appear word for word:

<div class='graphite__hidden'>
          <div>🎥 Video uploaded on Graphite:</div>
            <a href="https://app.graphite.dev/media/video/sJGviKxfE3Ap685cl5bj/56f6ec7b-4b21-405f-9612-43e083f6fb84.mov">
              <img src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/sJGviKxfE3Ap685cl5bj/56f6ec7b-4b21-405f-9612-43e083f6fb84.mov">
            </a>
          </div>
<video src="https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/sJGviKxfE3Ap685cl5bj/56f6ec7b-4b21-405f-9612-43e083f6fb84.mov">录屏2024-12-27 18.58.40.mov</video>

Click the little globe icon to manually turn on/off Internet search:
<div class='graphite__hidden'>
          <div>🎥 Video uploaded on Graphite:</div>
            <a href="https://app.graphite.dev/media/video/sJGviKxfE3Ap685cl5bj/778f1406-bf29-498e-a90d-7dad813392d1.mov">
              <img src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/sJGviKxfE3Ap685cl5bj/778f1406-bf29-498e-a90d-7dad813392d1.mov">
            </a>
          </div>
<video src="https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/sJGviKxfE3Ap685cl5bj/778f1406-bf29-498e-a90d-7dad813392d1.mov">录屏2024-12-27 19.01.16.mov</video>

When there is an image, it will automatically switch to the openai model:

<div class='graphite__hidden'>
          <div>🎥 Video uploaded on Graphite:</div>
            <a href="https://app.graphite.dev/media/video/sJGviKxfE3Ap685cl5bj/56431d8e-75e1-4d84-ab4a-b6636042cc6a.mov">
              <img src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/sJGviKxfE3Ap685cl5bj/56431d8e-75e1-4d84-ab4a-b6636042cc6a.mov">
            </a>
          </div>
<video src="https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/sJGviKxfE3Ap685cl5bj/56431d8e-75e1-4d84-ab4a-b6636042cc6a.mov">录屏2024-12-27 19.02.13.mov</video>
2025-01-09 04:00:59 +00:00
Yifeng Wang
4f10457815 refactor(editor): remove legacy console formatter (#9599) 2025-01-09 12:00:08 +08:00
doodlewind
e269cce141 refactor(editor): playground doc collection typing migration (#9593) 2025-01-09 03:07:43 +00:00
Saul-Mirone
3683297ccf feat(editor): add feature flag service (#9592) 2025-01-08 15:46:31 +00:00
Saul-Mirone
5842d45ab1 feat(editor): merge store and blocks (#9591) 2025-01-08 13:01:19 +00:00
L-Sun
a0cba55a5b feat(mobile): mobile toc menu (#9582)
Close [BS-1787](https://linear.app/affine-design/issue/BS-1787/toc-移动端适配)
2025-01-08 08:03:11 +00:00
Saul-Mirone
fe727412be feat(editor): add editor store (#9584) 2025-01-08 07:47:43 +00:00