AFFiNE
AFFiNE copied to clipboard
Support subpage and bi-directional links
Updated TODOs:
- Rich text
- [x] New rich text node (blot-like cursor behavior)
- [x]
[[
markdown shortcuts
- Model layer
- [x] API (events) for receiving linked page title change
- [x] API for querying filtered page list inside workspace
- [ ] Import from markdown
- [x] Export to markdown and HTML
- UI components
- [x] Filtered page list popup UI
- Misc
- [ ] Clipboard support
- [x] Multiple page testing in BlockSuite playground
To be clarified:
- Behavior (fallback) state when linked page is deleted
Note:
- Cross-workspace bi-directional link support is a non-goal.
@lawvs
Some design ideas related to subpage:
Basic Principles
- Use the field
pageMeta
as the data source
For example:
<page title="page1" pageMeta={["page-id-foo", "bar"]}>
<paragraph text={<>
<page-ref type="subpage" link-id="page-id-foo">subpage text</page-ref>
<page-ref type="bi-directional" link-id="foo">bi-directional link text</page-ref>
</>}
/>
</page>
Scenario 1 - Add/Delete subpage by sidebar
- Update
pageMeta
- If page1 is opened and
page-ref
node rendered- The
page-ref
can receive notification, then remove itself
- The
- Else do nothing
- If someone opens the readonly page, the
page-ref
will checkpage.subpages
and render nothing. - When the page1 opens and before
page-ref
rendered-
page-ref
can checkpageMeta
and then remove itself
-
Scenario 2 - Add/Delete subpage by operate text node
- Update
pageMeta
- Add/Remove
page-ref
node
Scenario 3 - data out of sync 1
-
pageMeta
is empty, but has a subpage node- It's expected scenario, the
page-ref
will remove itself before render
- It's expected scenario, the
Options (happens when removing an unopened subpage from sidebar):
- Not removing subpage link from page content immediately, lazy-remove it at next render -> may lead to side effect.
- Try removing subpage link after page tree updated -> requires loading subdoc and may fail, also more time-costly.

<page title="page1" pageMeta={[]}>
<paragraph text={<>
<page-ref type="subpage" link-id="foo">subpage text</page-ref>
<page-ref type="bi-directional" link-id="page-id-foo">bi-directional link text</page-ref>
</>}
/>
</page>
Scenario 4 - data out of sync 2
-
pageMeta
has some pages, but no correspondingpage-ref
text node- left side would have a ghost page, once remove it manually, it will return to normal
Happens when adding new subpage from sidebar, need similar options as Scenario 3.
<page title="page1" subpages={["page-id-foo"]}>
<paragraph text="" />
</page>
Note: All of the above names are temporary.
We need to maintain the page tree hierarchy in pageMeta
, which is a common sub-doc across the workspace. In this case, we may not need another page-level field (page.subpage
in CRDT model) marking the subpage relationship, only having the sys:refs: id[]
property on the paragraph/list block that contains subpage could be adequate.
TODOs:
- API for adding/querying/removing/
updatingsubpage link in one page - API for querying all bi-directional links in one page