Compare commits

...

27 Commits

Author SHA1 Message Date
DarkSky
3a13bdcc3d fix: ci 2025-11-16 00:43:30 +08:00
Mau Nguyen
71d682c1c0 feat(editor): add font size adjustment in editor settings (#13549)
Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
Co-authored-by: DarkSky <darksky2048@gmail.com>
2025-11-15 23:57:17 +08:00
DarkSky
d90eeffe84 fix: ci 2025-11-15 23:52:14 +08:00
DarkSky
12fe7a5ced fix: flatpak build 2025-11-15 22:01:24 +08:00
Roger Clotet
a35bcdc3ef feat(i18n): add missing catalan strings (#13914)
I'm a native Catalan and Spanish speaker. 

There are lots of changes, if I notice something is off when using it,
I'll submit more patches to improve it.

One decision I'm not sure about is keeping "edgeless" as the
translation, since it's difficult to find a proper way of saying it
that's not too similar to "borderless" or "without borders" in Catalan.
I noticed Spanish has some of the strings as "Edgeless" and others "sin
bordes", so I'm guessing this is a bit subjective and in my opinion
leaving it unchanged is easier to understand than if poorly translated.
2025-11-15 21:27:05 +08:00
DarkSky
29cb937493 feat(native): add events feature for yocto 2025-11-15 21:17:02 +08:00
AKY
e52bcb7fd6 feat(i18n): korean translation (#13733)
Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
2025-11-15 19:31:19 +08:00
DarkSky
4e082e4170 chore: bump version 2025-11-15 17:29:54 +08:00
DarkSky
46958867ef fix(editor): mermaid style pollution (#13950)
fix #13546
2025-11-15 17:26:08 +08:00
DarkSky
beb09300b9 fix(editor): date picker in year (#13948)
fix #13582
2025-11-15 16:56:24 +08:00
github-actions[bot]
f644454c5c chore(i18n): sync translations (#13949)
New Crowdin translations by [Crowdin GH
Action](https://github.com/crowdin/github-action)

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-11-15 16:30:48 +08:00
DarkSky
1654d8efe4 feat: improve sub sync (#13932) 2025-11-15 15:52:35 +08:00
DarkSky
46e7d9fab7 chore: bump electron (#13935)
fix #13647

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

* **Chores**
* Updated development tooling and build dependencies to latest stable
versions
  * Increased minimum Node.js requirement to version 22
  * Updated macOS deployment target to version 11.6
  * Enhanced type safety and error handling in build processes
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-11-15 15:52:04 +08:00
Xun Sun
17ec76540b feat(editor): import docs from docx (#11774)
Support importing .docx files, as mentioned in
https://github.com/toeverything/AFFiNE/issues/10154#issuecomment-2655744757

It essentially uses mammoth to convert the docx to html, and then
imports the html with the standard steps.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Import Microsoft Word (.docx) files directly via the import dialog
(creates new documents).
* .docx added as a selectable file type in the file picker and import
options.

* **Localization**
* Added localized labels and tooltips for DOCX import in English,
Simplified Chinese, and Traditional Chinese.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
Co-authored-by: DarkSky <darksky2048@gmail.com>
2025-11-15 15:51:23 +08:00
DarkSky
e5db0e66c1 chore: update schema 2025-11-15 14:45:18 +08:00
Kevin
525b65c6ca fix(server): config typo (#13913)
Fix a typo on the SMTP configuration page
2025-11-15 14:41:03 +08:00
DarkSky
c302425a05 fix(server): doc squash timeout (#13939) 2025-11-15 03:19:51 +08:00
DarkSky
abe73e9996 fix: config escape error (#13936)
fix #13702
2025-11-14 23:24:44 +08:00
Richard Lora
e379da200e feat(editor): add collapse/expand toggle for groups with caching (#12671)
https://github.com/user-attachments/assets/4ef71704-57bb-45b8-9e73-8a51c67fb158

Adds a collapsible toggle for group-by groups.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Collapsible groups for desktop and mobile table views with persistent
per-view collapsed state and a keyboard-accessible toggle button.

- **Bug Fixes**
  - Group title icons now render consistently across variants.

- **Tests**
- Added unit tests verifying collapse/expand behavior for group
components.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: 3720 <zuozijian1994@gmail.com>
Co-authored-by: L-Sun <zover.v@gmail.com>
2025-11-14 04:21:13 +00:00
3720
6ec1948f62 feat(editor): release callout (#13896)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Refactor**
* Callout is no longer gated as an experimental option — it now
consistently appears in the editor’s slash menu and toolbar where
applicable.

* **Tests**
* End-to-end slash-menu tests updated to expect the Callout item in
search results and adjusted item ordering.

* **Chores**
  * Repository ignore rules updated to exclude .kiro files.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-11-12 06:46:18 +00:00
DarkSky
7e6ead4232 feat: native doc reader (#13881) 2025-11-08 23:07:16 +08:00
Hongxu Xu
02dcfdcc40 chore(native): remove unused deps (#13854)
Identified some unused dependencies and refactored them.
2025-11-07 11:31:19 +08:00
Vitaly Barakov
5a2f508dac feat(editor): hidden 'add icon' label on print if icon is not set (#13868)
This caption (see screenshot) is added when you try to print doc, even
if there is no icon.
<img width="1269" height="897" alt="изображение"
src="https://github.com/user-attachments/assets/d63383e6-48a2-44fb-8f32-ae91d1e9e8c6"
/>
2025-11-07 11:30:54 +08:00
Martin Pauli
2bd9f1a353 feat: implement tray and minimize behaviors (#13851)
This PR introduces new window behaviors, which can be enabled when the
menubar setting is active:

New Features:
- Quick open from tray icon
- Minimize to tray
- Exit to tray
- Start minimized

These changes have not yet been tested on macOS.

<img width="645" height="479" alt="image"
src="https://github.com/user-attachments/assets/7bdd13d0-5322-45a4-8e71-85c081aa0c86"
/>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Configurable menubar/tray behaviors: open on left-click, minimize to
tray, close to tray (exit to tray), and start minimized.

* **UI**
* Appearance settings add a Menubar → Window Behavior group with four
toggles; group shows only when menubar/tray is enabled (hidden on
macOS).

* **Settings**
* Tray settings persisted and exposed via the settings API with getters
and setters for each option.

* **Localization**
* Added translation keys and English strings for the new controls and
descriptions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Peng Xiao <pengxiao@outlook.com>
2025-11-06 20:10:15 +00:00
Vitaly Barakov
9f6ea83ac1 fix(editor): linked doc popover close when layout is switched (#13867)
Fixing the disappearing linked doc menu called by @ when switching
language using Alt+Shift.
2025-11-06 22:26:19 +08:00
DarkSky
d33df659f8 feat: check server type in chat (#13875) 2025-11-06 20:55:32 +08:00
Peng Xiao
c9a4129a3e fix: a security issue related to open external (#13864) 2025-11-06 20:54:25 +08:00
213 changed files with 7751 additions and 2090 deletions

View File

@@ -5,7 +5,14 @@ rustflags = ["-C", "target-feature=+crt-static"]
[target.'cfg(target_os = "linux")']
rustflags = ["-C", "link-args=-Wl,--warn-unresolved-symbols"]
[target.'cfg(target_os = "macos")']
rustflags = ["-C", "link-args=-Wl,-undefined,dynamic_lookup,-no_fixup_chains", "-C", "link-args=-all_load", "-C", "link-args=-weak_framework ScreenCaptureKit"]
rustflags = [
"-C",
"link-args=-Wl,-undefined,dynamic_lookup,-no_fixup_chains",
"-C",
"link-args=-all_load",
"-C",
"link-args=-weak_framework ScreenCaptureKit",
]
# https://sourceware.org/bugzilla/show_bug.cgi?id=21032
# https://sourceware.org/bugzilla/show_bug.cgi?id=21031
# https://github.com/rust-lang/rust/issues/134820

View File

@@ -222,12 +222,12 @@
},
"SMTP.sender": {
"type": "string",
"description": "Sender of all the emails (e.g. \"AFFiNE Team <noreply@affine.pro>\")\n@default \"\"\n@environment `MAILER_SENDER`",
"default": ""
"description": "Sender of all the emails (e.g. \"AFFiNE Self Hosted <noreply@example.com>\")\n@default \"AFFiNE Self Hosted <noreply@example.com>\"\n@environment `MAILER_SENDER`",
"default": "AFFiNE Self Hosted <noreply@example.com>"
},
"SMTP.ignoreTLS": {
"type": "boolean",
"description": "Whether ignore email server's TSL certification verification. Enable it for self-signed certificates.\n@default false\n@environment `MAILER_IGNORE_TLS`",
"description": "Whether ignore email server's TLS certificate verification. Enable it for self-signed certificates.\n@default false\n@environment `MAILER_IGNORE_TLS`",
"default": false
},
"fallbackDomains": {
@@ -262,12 +262,12 @@
},
"fallbackSMTP.sender": {
"type": "string",
"description": "Sender of all the emails (e.g. \"AFFiNE Team <noreply@affine.pro>\")\n@default \"\"",
"description": "Sender of all the emails (e.g. \"AFFiNE Self Hosted <noreply@example.com>\")\n@default \"\"",
"default": ""
},
"fallbackSMTP.ignoreTLS": {
"type": "boolean",
"description": "Whether ignore email server's TSL certification verification. Enable it for self-signed certificates.\n@default false",
"description": "Whether ignore email server's TLS certificate verification. Enable it for self-signed certificates.\n@default false",
"default": false
}
}

View File

@@ -3,4 +3,4 @@ name: affine
description: AFFiNE cloud chart
type: application
version: 0.0.0
appVersion: "0.25.2"
appVersion: "0.25.5"

View File

@@ -3,7 +3,7 @@ name: doc
description: AFFiNE doc server
type: application
version: 0.0.0
appVersion: "0.25.2"
appVersion: "0.25.5"
dependencies:
- name: gcloud-sql-proxy
version: 0.0.0

View File

@@ -3,7 +3,7 @@ name: graphql
description: AFFiNE GraphQL server
type: application
version: 0.0.0
appVersion: "0.25.2"
appVersion: "0.25.5"
dependencies:
- name: gcloud-sql-proxy
version: 0.0.0

View File

@@ -3,7 +3,7 @@ name: renderer
description: AFFiNE renderer server
type: application
version: 0.0.0
appVersion: "0.25.2"
appVersion: "0.25.5"
dependencies:
- name: gcloud-sql-proxy
version: 0.0.0

View File

@@ -3,7 +3,7 @@ name: sync
description: AFFiNE Sync Server
type: application
version: 0.0.0
appVersion: "0.25.2"
appVersion: "0.25.5"
dependencies:
- name: gcloud-sql-proxy
version: 0.0.0

View File

@@ -19,7 +19,7 @@ env:
APP_NAME: affine
AFFINE_ENV: dev
COVERAGE: true
MACOSX_DEPLOYMENT_TARGET: '10.13'
MACOSX_DEPLOYMENT_TARGET: '11.6'
DEPLOYMENT_TYPE: affine
AFFINE_INDEXER_ENABLED: true

View File

@@ -25,7 +25,7 @@ env:
RELEASE_VERSION: ${{ inputs.app-version }}
DEBUG: 'affine:*,napi:*'
APP_NAME: affine
MACOSX_DEPLOYMENT_TARGET: '10.13'
MACOSX_DEPLOYMENT_TARGET: '11.6'
jobs:
before-make:
@@ -165,7 +165,7 @@ jobs:
mv packages/frontend/apps/electron/out/*/make/zip/linux/${{ matrix.spec.arch }}/*.zip ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.zip
mv packages/frontend/apps/electron/out/*/make/*.AppImage ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.appimage
mv packages/frontend/apps/electron/out/*/make/deb/${{ matrix.spec.arch }}/*.deb ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.deb
mv packages/frontend/apps/electron/out/*/make/flatpak/*/*.flatpak ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.flatpak
# mv packages/frontend/apps/electron/out/*/make/flatpak/*/*.flatpak ./builds/affine-${{ env.RELEASE_VERSION }}-${{ env.BUILD_TYPE }}-linux-${{ matrix.spec.arch }}.flatpak
- uses: actions/attest-build-provenance@v2
if: ${{ matrix.spec.platform == 'darwin' }}
@@ -466,6 +466,4 @@ jobs:
draft: ${{ inputs.build-type == 'stable' }}
prerelease: ${{ inputs.build-type != 'stable' }}
tag_name: v${{ env.RELEASE_VERSION}}
files: |
./release/*
./release/.env.example
files: ./release/*

3
.gitignore vendored
View File

@@ -33,6 +33,9 @@ node_modules
!.vscode/launch.template.json
!.vscode/extensions.json
# Kiro
.kiro
# misc
/.sass-cache
/connect.lock

View File

@@ -1,7 +1,7 @@
include = ["./*.toml", "./packages/**/*.toml"]
exclude = ["node_modules/**/*.toml", "target/**/*.toml"]
# https://taplo.tamasfe.dev/configuration/formatter-options.html
[formatting]
align_entries = true
column_width = 180
reorder_arrays = true
reorder_keys = true
align_entries = true
indent_tables = true
reorder_keys = true

154
Cargo.lock generated
View File

@@ -40,6 +40,7 @@ dependencies = [
name = "affine_common"
version = "0.1.0"
dependencies = [
"assert-json-diff",
"cc",
"chrono",
"criterion2",
@@ -50,6 +51,7 @@ dependencies = [
"rand 0.9.1",
"rayon",
"readability",
"serde",
"serde_json",
"sha3",
"strum_macros",
@@ -69,6 +71,7 @@ dependencies = [
"tree-sitter-scala",
"tree-sitter-typescript",
"url",
"y-octo",
]
[[package]]
@@ -442,12 +445,6 @@ dependencies = [
"num-traits",
]
[[package]]
name = "atomic_refcell"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41e67cd8309bbd06cd603a9e693a784ac2e5d1e955f11286e355089fcab3047c"
[[package]]
name = "auto_enums"
version = "0.8.7"
@@ -584,18 +581,6 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "bitvec"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
dependencies = [
"funty",
"radium",
"tap",
"wyz",
]
[[package]]
name = "block-buffer"
version = "0.10.4"
@@ -1612,12 +1597,6 @@ dependencies = [
"autocfg",
]
[[package]]
name = "funty"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
[[package]]
name = "futf"
version = "0.1.5"
@@ -1724,19 +1703,6 @@ dependencies = [
"version_check",
]
[[package]]
name = "getrandom"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"wasi 0.9.0+wasi-snapshot-preview1",
"wasm-bindgen",
]
[[package]]
name = "getrandom"
version = "0.2.16"
@@ -1834,10 +1800,6 @@ name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
dependencies = [
"ahash",
"allocator-api2",
]
[[package]]
name = "hashbrown"
@@ -2255,16 +2217,6 @@ dependencies = [
"cpufeatures",
]
[[package]]
name = "lasso"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e14eda50a3494b3bf7b9ce51c52434a761e383d7238ce1dd5dcec2fbc13e9fb"
dependencies = [
"dashmap",
"hashbrown 0.14.5",
]
[[package]]
name = "lazy_static"
version = "1.5.0"
@@ -3280,25 +3232,6 @@ version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
[[package]]
name = "radium"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom 0.1.16",
"libc",
"rand_chacha 0.2.2",
"rand_core 0.5.1",
"rand_hc",
]
[[package]]
name = "rand"
version = "0.8.5"
@@ -3320,16 +3253,6 @@ dependencies = [
"rand_core 0.9.3",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core 0.5.1",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
@@ -3350,15 +3273,6 @@ dependencies = [
"rand_core 0.9.3",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom 0.1.16",
]
[[package]]
name = "rand_core"
version = "0.6.4"
@@ -3387,15 +3301,6 @@ dependencies = [
"rand 0.9.1",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core 0.5.1",
]
[[package]]
name = "rand_xorshift"
version = "0.3.0"
@@ -4477,12 +4382,6 @@ dependencies = [
"syn 2.0.101",
]
[[package]]
name = "tap"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "tempfile"
version = "3.20.0"
@@ -5198,12 +5097,6 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
@@ -5808,15 +5701,6 @@ version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
[[package]]
name = "wyz"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
dependencies = [
"tap",
]
[[package]]
name = "xml5ever"
version = "0.17.0"
@@ -5842,10 +5726,8 @@ dependencies = [
"arbitrary",
"assert-json-diff",
"async-lock",
"bitvec",
"byteorder",
"criterion",
"lasso",
"lib0",
"log",
"loom",
@@ -5862,7 +5744,7 @@ dependencies = [
"serde_json",
"smol_str",
"thiserror 2.0.12",
"yrs 0.23.4",
"yrs",
]
[[package]]
@@ -5892,18 +5774,7 @@ dependencies = [
"rand_chacha 0.9.0",
"regex",
"y-octo",
"y-sync",
"yrs 0.23.4",
]
[[package]]
name = "y-sync"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52e3675a497cde881a71e7e5c2ae1d087dfc7733ddece9b24a9a61408e969d3b"
dependencies = [
"thiserror 1.0.69",
"yrs 0.17.4",
"yrs",
]
[[package]]
@@ -5930,21 +5801,6 @@ dependencies = [
"synstructure",
]
[[package]]
name = "yrs"
version = "0.17.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4830316bfee4bec0044fe34a001cda783506d5c4c0852f8433c6041dfbfce51"
dependencies = [
"atomic_refcell",
"rand 0.7.3",
"serde",
"serde_json",
"smallstr",
"smallvec",
"thiserror 1.0.69",
]
[[package]]
name = "yrs"
version = "0.23.4"

View File

@@ -13,109 +13,122 @@ members = [
]
resolver = "3"
[workspace.package]
edition = "2024"
[workspace.package]
edition = "2024"
[workspace.dependencies]
affine_common = { path = "./packages/common/native" }
affine_nbstore = { path = "./packages/frontend/native/nbstore" }
ahash = "0.8"
anyhow = "1"
arbitrary = { version = "1.3", features = ["derive"] }
assert-json-diff = "2.0"
async-lock = { version = "3.4.0", features = ["loom"] }
base64-simd = "0.8"
bitvec = "1.0"
block2 = "0.6"
byteorder = "1.5"
cpal = "0.15"
chrono = "0.4"
clap = { version = "4.4", features = ["derive"] }
core-foundation = "0.10"
coreaudio-rs = "0.12"
criterion = { version = "0.5", features = ["html_reports"] }
criterion2 = { version = "3", default-features = false }
crossbeam-channel = "0.5"
dispatch2 = "0.3"
docx-parser = { git = "https://github.com/toeverything/docx-parser" }
dotenvy = "0.15"
file-format = { version = "0.28", features = ["reader"] }
homedir = "0.3"
infer = { version = "0.19.0" }
lasso = { version = "0.7", features = ["multi-threaded"] }
lib0 = { version = "0.16", features = ["lib0-serde"] }
libc = "0.2"
log = "0.4"
loom = { version = "0.7", features = ["checkpoint"] }
mimalloc = "0.1"
mp4parse = "0.17"
nanoid = "0.4"
napi = { version = "3.0.0-beta.3", features = ["async", "chrono_date", "error_anyhow", "napi9", "serde"] }
napi-build = { version = "2" }
napi-derive = { version = "3.0.0-beta.3" }
nom = "8"
notify = { version = "8", features = ["serde"] }
objc2 = "0.6"
objc2-foundation = "0.3"
once_cell = "1"
ordered-float = "5"
parking_lot = "0.12"
path-ext = "0.1.2"
pdf-extract = { git = "https://github.com/toeverything/pdf-extract", branch = "darksky/improve-font-decoding" }
phf = { version = "0.11", features = ["macros"] }
proptest = "1.3"
proptest-derive = "0.5"
rand = "0.9"
rand_chacha = "0.9"
rand_distr = "0.5"
rayon = "1.10"
readability = { version = "0.3.0", default-features = false }
regex = "1.10"
rubato = "0.16"
screencapturekit = "0.3"
serde = "1"
serde_json = "1"
sha3 = "0.10"
smol_str = "0.3"
sqlx = { version = "0.8", default-features = false, features = ["chrono", "macros", "migrate", "runtime-tokio", "sqlite", "tls-rustls"] }
strum_macros = "0.27.0"
symphonia = { version = "0.5", features = ["all", "opt-simd"] }
text-splitter = "0.27"
thiserror = "2"
tiktoken-rs = "0.7"
tokio = "1.45"
tree-sitter = { version = "0.25" }
tree-sitter-c = { version = "0.24" }
tree-sitter-c-sharp = { version = "0.23" }
tree-sitter-cpp = { version = "0.23" }
tree-sitter-go = { version = "0.23" }
tree-sitter-java = { version = "0.23" }
tree-sitter-javascript = { version = "0.23" }
tree-sitter-kotlin-ng = { version = "1.1" }
tree-sitter-python = { version = "0.23" }
tree-sitter-rust = { version = "0.24" }
tree-sitter-scala = { version = "0.24" }
tree-sitter-typescript = { version = "0.23" }
uniffi = "0.29"
url = { version = "2.5" }
uuid = "1.8"
v_htmlescape = "0.15"
windows = { version = "0.61", features = [
"Win32_Devices_FunctionDiscovery",
"Win32_UI_Shell_PropertiesSystem",
"Win32_Media_Audio",
"Win32_System_Variant",
"Win32_System_Com_StructuredStorage",
"Win32_System_Threading",
"Win32_System_ProcessStatus",
"Win32_Foundation",
"Win32_System_Com",
"Win32_System_Diagnostics_ToolHelp",
] }
windows-core = { version = "0.61" }
y-octo = { path = "./packages/common/y-octo/core" }
y-sync = { version = "0.4" }
yrs = "0.23.0"
[workspace.dependencies]
affine_common = { path = "./packages/common/native" }
affine_nbstore = { path = "./packages/frontend/native/nbstore" }
ahash = "0.8"
anyhow = "1"
arbitrary = { version = "1.3", features = ["derive"] }
assert-json-diff = "2.0"
async-lock = { version = "3.4.0", features = ["loom"] }
base64-simd = "0.8"
bitvec = "1.0"
block2 = "0.6"
byteorder = "1.5"
chrono = "0.4"
clap = { version = "4.4", features = ["derive"] }
core-foundation = "0.10"
coreaudio-rs = "0.12"
cpal = "0.15"
criterion = { version = "0.5", features = ["html_reports"] }
criterion2 = { version = "3", default-features = false }
crossbeam-channel = "0.5"
dispatch2 = "0.3"
docx-parser = { git = "https://github.com/toeverything/docx-parser" }
dotenvy = "0.15"
file-format = { version = "0.28", features = ["reader"] }
homedir = "0.3"
infer = { version = "0.19.0" }
lasso = { version = "0.7", features = ["multi-threaded"] }
lib0 = { version = "0.16", features = ["lib0-serde"] }
libc = "0.2"
log = "0.4"
loom = { version = "0.7", features = ["checkpoint"] }
mimalloc = "0.1"
mp4parse = "0.17"
nanoid = "0.4"
napi = { version = "3.0.0-beta.3", features = [
"async",
"chrono_date",
"error_anyhow",
"napi9",
"serde",
] }
napi-build = { version = "2" }
napi-derive = { version = "3.0.0-beta.3" }
nom = "8"
notify = { version = "8", features = ["serde"] }
objc2 = "0.6"
objc2-foundation = "0.3"
once_cell = "1"
ordered-float = "5"
parking_lot = "0.12"
path-ext = "0.1.2"
pdf-extract = { git = "https://github.com/toeverything/pdf-extract", branch = "darksky/improve-font-decoding" }
phf = { version = "0.11", features = ["macros"] }
proptest = "1.3"
proptest-derive = "0.5"
rand = "0.9"
rand_chacha = "0.9"
rand_distr = "0.5"
rayon = "1.10"
readability = { version = "0.3.0", default-features = false }
regex = "1.10"
rubato = "0.16"
screencapturekit = "0.3"
serde = "1"
serde_json = "1"
sha3 = "0.10"
smol_str = "0.3"
sqlx = { version = "0.8", default-features = false, features = [
"chrono",
"macros",
"migrate",
"runtime-tokio",
"sqlite",
"tls-rustls",
] }
strum_macros = "0.27.0"
symphonia = { version = "0.5", features = ["all", "opt-simd"] }
text-splitter = "0.27"
thiserror = "2"
tiktoken-rs = "0.7"
tokio = "1.45"
tree-sitter = { version = "0.25" }
tree-sitter-c = { version = "0.24" }
tree-sitter-c-sharp = { version = "0.23" }
tree-sitter-cpp = { version = "0.23" }
tree-sitter-go = { version = "0.23" }
tree-sitter-java = { version = "0.23" }
tree-sitter-javascript = { version = "0.23" }
tree-sitter-kotlin-ng = { version = "1.1" }
tree-sitter-python = { version = "0.23" }
tree-sitter-rust = { version = "0.24" }
tree-sitter-scala = { version = "0.24" }
tree-sitter-typescript = { version = "0.23" }
uniffi = "0.29"
url = { version = "2.5" }
uuid = "1.8"
v_htmlescape = "0.15"
windows = { version = "0.61", features = [
"Win32_Devices_FunctionDiscovery",
"Win32_Foundation",
"Win32_Media_Audio",
"Win32_System_Com",
"Win32_System_Com_StructuredStorage",
"Win32_System_Diagnostics_ToolHelp",
"Win32_System_ProcessStatus",
"Win32_System_Threading",
"Win32_System_Variant",
"Win32_UI_Shell_PropertiesSystem",
] }
windows-core = { version = "0.61" }
y-octo = { path = "./packages/common/y-octo/core" }
y-sync = { version = "0.4" }
yrs = "0.23.0"
[profile.dev.package.sqlx-macros]
opt-level = 3
@@ -126,6 +139,6 @@ lto = true
opt-level = 3
strip = "symbols"
# android uniffi bindgen requires symbols
[profile.release.package.affine_mobile_native]
strip = "none"
# android uniffi bindgen requires symbols
[profile.release.package.affine_mobile_native]
strip = "none"

View File

@@ -296,7 +296,7 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2",
"version": "0.25.5",
"devDependencies": {
"@vanilla-extract/vite-plugin": "^5.0.0",
"msw": "^2.8.4",

View File

@@ -41,5 +41,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -45,5 +45,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -45,5 +45,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -1,5 +1,4 @@
import { focusBlockEnd } from '@blocksuite/affine-shared/commands';
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
import { isInsideBlockByFlavour } from '@blocksuite/affine-shared/utils';
import { type SlashMenuConfig } from '@blocksuite/affine-widget-slash-menu';
import { FontIcon } from '@blocksuite/icons/lit';
@@ -18,10 +17,11 @@ export const calloutSlashMenuConfig: SlashMenuConfig = {
},
searchAlias: ['callout'],
group: '0_Basic@9',
when: ({ std, model }) => {
return (
std.get(FeatureFlagService).getFlag('enable_callout') &&
!isInsideBlockByFlavour(model.store, model, 'affine:edgeless-text')
when: ({ model }) => {
return !isInsideBlockByFlavour(
model.store,
model,
'affine:edgeless-text'
);
},
action: ({ model, std }) => {

View File

@@ -48,5 +48,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -42,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -48,5 +48,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -39,5 +39,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -43,5 +43,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -49,5 +49,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -49,5 +49,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -46,5 +46,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -46,5 +46,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -49,5 +49,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -42,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -46,7 +46,7 @@
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@types/lodash-es": "^4.17.12",
"dompurify": "^3.2.4",
"dompurify": "^3.3.0",
"html2canvas": "^1.4.1",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -67,5 +67,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -45,5 +45,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -46,5 +46,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -42,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -82,5 +82,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -229,9 +229,9 @@ export class DatePicker extends WithDisposable(LitElement) {
private _modeDecade(offset: number) {
this._yearCursor = clamp(
this._yearCursor + offset,
this._minYear,
this._maxYear,
this._yearCursor + offset
this._maxYear
);
this._getYearMatrix();
}

View File

@@ -46,5 +46,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -0,0 +1,36 @@
import { describe, expect, test } from 'vitest';
import { mobileEffects } from '../view-presets/table/mobile/effect.js';
import type { MobileTableGroup } from '../view-presets/table/mobile/group.js';
import { pcEffects } from '../view-presets/table/pc/effect.js';
import type { TableGroup } from '../view-presets/table/pc/group.js';
/** @vitest-environment happy-dom */
describe('TableGroup', () => {
test('toggle collapse on pc', () => {
pcEffects();
const group = document.createElement(
'affine-data-view-table-group'
) as TableGroup;
expect(group.collapsed$.value).toBe(false);
(group as any)._toggleCollapse();
expect(group.collapsed$.value).toBe(true);
(group as any)._toggleCollapse();
expect(group.collapsed$.value).toBe(false);
});
test('toggle collapse on mobile', () => {
mobileEffects();
const group = document.createElement(
'mobile-table-group'
) as MobileTableGroup;
expect(group.collapsed$.value).toBe(false);
(group as any)._toggleCollapse();
expect(group.collapsed$.value).toBe(true);
(group as any)._toggleCollapse();
expect(group.collapsed$.value).toBe(false);
});
});

View File

@@ -26,13 +26,10 @@ const GroupTitleMobile = (
const type = groupData.tType;
if (!type) return nothing;
const icon =
groupData.value == null
? ''
: html` <uni-lit
class="group-header-icon"
.uni="${groupData.property.icon}"
></uni-lit>`;
const icon = html` <uni-lit
class="group-header-icon"
.uni="${groupData.property.icon}"
></uni-lit>`;
const props: GroupRenderProps = {
group: groupData,
readonly: ops.readonly,
@@ -126,13 +123,10 @@ export const GroupTitle = (
const type = groupData.tType;
if (!type) return nothing;
const icon =
groupData.value == null
? ''
: html` <uni-lit
class="group-header-icon"
.uni="${groupData.property.icon}"
></uni-lit>`;
const icon = html` <uni-lit
class="group-header-icon"
.uni="${groupData.property.icon}"
></uni-lit>`;
const props: GroupRenderProps = {
group: groupData,
readonly: ops.readonly,

View File

@@ -0,0 +1,44 @@
/**
* Shared utility for managing table group collapsed state in sessionStorage.
* Used by both PC and mobile table group implementations.
*/
/**
* Gets the collapsed state for a specific table group from sessionStorage.
* @param viewId - The ID of the table view
* @param groupKey - The key of the group
* @returns The collapsed state as a boolean, or false if not found or invalid
*/
export function getCollapsedState(viewId: string, groupKey: string): boolean {
try {
const value = sessionStorage.getItem(
`affine:table-group:${viewId}:${groupKey}:collapsed`
);
if (!value) return false;
const parsed = JSON.parse(value);
return typeof parsed === 'boolean' ? parsed : false;
} catch {
return false;
}
}
/**
* Sets the collapsed state for a specific table group in sessionStorage.
* @param viewId - The ID of the table view
* @param groupKey - The key of the group
* @param collapsed - The collapsed state to store
*/
export function setCollapsedState(
viewId: string,
groupKey: string,
collapsed: boolean
): void {
try {
sessionStorage.setItem(
`affine:table-group:${viewId}:${groupKey}:collapsed`,
JSON.stringify(collapsed)
);
} catch {
// ignore
}
}

View File

@@ -4,16 +4,22 @@ import {
popupTargetFromElement,
} from '@blocksuite/affine-components/context-menu';
import { SignalWatcher, WithDisposable } from '@blocksuite/global/lit';
import { PlusIcon } from '@blocksuite/icons/lit';
import {
PlusIcon,
ToggleDownIcon,
ToggleRightIcon,
} from '@blocksuite/icons/lit';
import { ShadowlessElement } from '@blocksuite/std';
import { signal } from '@preact/signals-core';
import { cssVarV2 } from '@toeverything/theme/v2';
import { css, html, unsafeCSS } from 'lit';
import { css, html, nothing, unsafeCSS } from 'lit';
import { property } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
import { GroupTitle } from '../../../core/group-by/group-title.js';
import type { Group } from '../../../core/group-by/trait.js';
import type { Row } from '../../../core/index.js';
import { getCollapsedState, setCollapsedState } from '../collapsed-state.js';
import { LEFT_TOOL_BAR_WIDTH } from '../consts.js';
import type { MobileTableViewUILogic } from './table-view-ui-logic.js';
@@ -42,6 +48,28 @@ const styles = css`
line-height: 20px;
color: var(--affine-text-secondary-color);
}
.group-toggle-btn {
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 4px;
cursor: pointer;
transition: background-color 150ms cubic-bezier(0.42, 0, 1, 1);
}
.group-toggle-btn:hover {
background: var(--affine-hover-color);
}
.group-toggle-btn svg {
width: 16px;
height: 16px;
flex-shrink: 0;
user-select: none;
}
`;
export class MobileTableGroup extends SignalWatcher(
@@ -49,6 +77,29 @@ export class MobileTableGroup extends SignalWatcher(
) {
static override styles = styles;
collapsed$ = signal(false);
private storageLoaded = false;
private _loadCollapsedState() {
if (this.storageLoaded) return;
this.storageLoaded = true;
const view = this.tableViewLogic?.view;
if (!view) return;
const value = getCollapsedState(view.id, this.group?.key ?? 'all');
this.collapsed$.value = value;
}
private readonly _toggleCollapse = (e?: MouseEvent) => {
e?.stopPropagation();
const next = !this.collapsed$.value;
this.collapsed$.value = next;
const view = this.tableViewLogic?.view;
if (view) {
setCollapsedState(view.id, this.group?.key ?? 'all', next);
}
};
private readonly clickAddRow = () => {
this.view.rowAdd('end', this.group?.key);
this.requestUpdate();
@@ -93,6 +144,27 @@ export class MobileTableGroup extends SignalWatcher(
<div
style="position: sticky;left: 0;width: max-content;padding: 6px 0;margin-bottom: 4px;display:flex;align-items:center;gap: 12px;max-width: 400px"
>
<div
class=${`group-toggle-btn ${this.collapsed$.value ? '' : 'expanded'}`}
role="button"
aria-expanded=${this.collapsed$.value ? 'false' : 'true'}
aria-label=${this.collapsed$.value
? 'Expand group'
: 'Collapse group'}
tabindex="0"
@click=${this._toggleCollapse}
@keydown=${(e: KeyboardEvent) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
this._toggleCollapse();
}
}}
>
${this.collapsed$.value
? ToggleRightIcon({ width: '16px', height: '16px' })
: ToggleDownIcon({ width: '16px', height: '16px' })}
</div>
${GroupTitle(this.group, {
readonly: this.view.readonly$.value,
clickAdd: this.clickAddRowInStart,
@@ -109,7 +181,6 @@ export class MobileTableGroup extends SignalWatcher(
private renderRows(rows: Row[]) {
return html`
<mobile-table-header
.renderGroupHeader="${this.renderGroupHeader}"
.tableViewManager="${this.view}"
></mobile-table-header>
<div class="mobile-affine-table-body">
@@ -144,8 +215,26 @@ export class MobileTableGroup extends SignalWatcher(
`;
}
override willUpdate(changed: Map<PropertyKey, unknown>): void {
super.willUpdate(changed);
if (
!this.storageLoaded &&
(changed.has('group') || changed.has('tableViewLogic'))
) {
this._loadCollapsedState();
}
}
override connectedCallback(): void {
super.connectedCallback();
this._loadCollapsedState();
}
override render() {
return this.renderRows(this.rows);
return html`
${this.collapsed$.value ? this.renderGroupHeader() : nothing}
${this.collapsed$.value ? nothing : this.renderRows(this.rows)}
`;
}
@property({ attribute: false })

View File

@@ -57,12 +57,12 @@ const styles = css`
margin-inline: 5px;
}
.label {
.stats-cell .label {
text-transform: uppercase;
color: var(--affine-text-secondary-color);
}
.value {
.stats-cell .value {
color: var(--affine-text-primary-color);
}
`;

View File

@@ -4,11 +4,15 @@ import {
popupTargetFromElement,
} from '@blocksuite/affine-components/context-menu';
import { SignalWatcher, WithDisposable } from '@blocksuite/global/lit';
import { PlusIcon } from '@blocksuite/icons/lit';
import {
PlusIcon,
ToggleDownIcon,
ToggleRightIcon,
} from '@blocksuite/icons/lit';
import { ShadowlessElement } from '@blocksuite/std';
import { effect } from '@preact/signals-core';
import { effect, signal } from '@preact/signals-core';
import { cssVarV2 } from '@toeverything/theme/v2';
import { css, html, unsafeCSS } from 'lit';
import { css, html, nothing, unsafeCSS } from 'lit';
import { property, query } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
@@ -18,6 +22,7 @@ import type { Row } from '../../../core/index.js';
import { createDndContext } from '../../../core/utils/wc-dnd/dnd-context.js';
import { defaultActivators } from '../../../core/utils/wc-dnd/sensors/index.js';
import { linearMove } from '../../../core/utils/wc-dnd/utils/linear-move.js';
import { getCollapsedState, setCollapsedState } from '../collapsed-state.js';
import { LEFT_TOOL_BAR_WIDTH } from '../consts.js';
import { TableViewAreaSelection } from '../selection';
import { DataViewColumnPreview } from './header/column-renderer.js';
@@ -30,6 +35,12 @@ const styles = css`
opacity: 1;
}
affine-data-view-table-group {
margin-top: 4px;
padding-top: 4px;
border-top: 1px solid var(--affine-border-color);
}
.data-view-table-group-add-row {
display: flex;
width: 100%;
@@ -42,6 +53,10 @@ const styles = css`
border-bottom: 1px solid ${unsafeCSS(cssVarV2.layer.insideBorder.border)};
}
.affine-data-view-table-group:hover svg {
fill: var(--affine-icon-color);
}
@media print {
.data-view-table-group-add-row {
display: none;
@@ -60,6 +75,28 @@ const styles = css`
line-height: 20px;
color: var(--affine-text-secondary-color);
}
.group-toggle-btn {
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 4px;
cursor: pointer;
transition: background-color 150ms cubic-bezier(0.42, 0, 1, 1);
}
.group-toggle-btn:hover {
background: var(--affine-hover-color);
}
.group-toggle-btn svg {
width: 16px;
height: 16px;
flex-shrink: 0;
user-select: none;
}
`;
export class TableGroup extends SignalWatcher(
@@ -67,6 +104,29 @@ export class TableGroup extends SignalWatcher(
) {
static override styles = styles;
collapsed$ = signal(false);
private storageLoaded = false;
private _loadCollapsedState() {
if (this.storageLoaded) return;
this.storageLoaded = true;
const view = this.tableViewLogic?.view;
if (!view) return;
const value = getCollapsedState(view.id, this.group?.key ?? 'all');
this.collapsed$.value = value;
}
private readonly _toggleCollapse = (e?: MouseEvent) => {
e?.stopPropagation();
const next = !this.collapsed$.value;
this.collapsed$.value = next;
const view = this.tableViewLogic?.view;
if (view) {
setCollapsedState(view.id, this.group?.key ?? 'all', next);
}
};
private readonly clickAddRow = () => {
this.view.rowAdd('end', this.group?.key);
const selectionController = this.tableViewLogic.selectionController;
@@ -137,10 +197,32 @@ export class TableGroup extends SignalWatcher(
if (!this.group) {
return null;
}
return html`
<div
style="position: sticky;left: 0;width: max-content;padding: 6px 0;margin-bottom: 4px;display:flex;align-items:center;gap: 12px;max-width: 400px"
style="position: sticky;left: 0;width: max-content;padding: 6px 0;margin-bottom: 4px;display:flex;align-items:center;gap: 8px;max-width: 400px"
>
<div
class=${`group-toggle-btn ${this.collapsed$.value ? '' : 'expanded'}`}
role="button"
aria-expanded=${this.collapsed$.value ? 'false' : 'true'}
aria-label=${this.collapsed$.value
? 'Expand group'
: 'Collapse group'}
tabindex="0"
@click=${this._toggleCollapse}
@keydown=${(e: KeyboardEvent) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
this._toggleCollapse();
}
}}
>
${this.collapsed$.value
? ToggleRightIcon({ width: '16px', height: '16px' })
: ToggleDownIcon({ width: '16px', height: '16px' })}
</div>
${GroupTitle(this.group, {
readonly: this.view.readonly$.value,
clickAdd: this.clickAddRowInStart,
@@ -244,8 +326,8 @@ export class TableGroup extends SignalWatcher(
private renderRows(rows: Row[]) {
return html`
<affine-database-column-header
.renderGroupHeader="${this.renderGroupHeader}"
.tableViewLogic="${this.tableViewLogic}"
.renderGroupHeader=${this.renderGroupHeader}
.tableViewLogic=${this.tableViewLogic}
></affine-database-column-header>
<div class="affine-database-block-rows">
${repeat(
@@ -284,13 +366,27 @@ export class TableGroup extends SignalWatcher(
`;
}
override willUpdate(changed: Map<PropertyKey, unknown>): void {
super.willUpdate(changed);
if (
!this.storageLoaded &&
(changed.has('group') || changed.has('tableViewLogic'))
) {
this._loadCollapsedState();
}
}
override connectedCallback(): void {
super.connectedCallback();
this._loadCollapsedState();
this.showIndicator();
}
override render() {
return this.renderRows(this.rows);
return html`
${this.collapsed$.value ? this.renderGroupHeader() : nothing}
${this.collapsed$.value ? nothing : this.renderRows(this.rows)}
`;
}
@query('.affine-database-block-rows')

View File

@@ -57,12 +57,12 @@ const styles = css`
margin-inline: 5px;
}
.label {
.stats-cell .label {
text-transform: uppercase;
color: var(--affine-text-secondary-color);
}
.value {
.stats-cell .value {
color: var(--affine-text-primary-color);
}
`;

View File

@@ -26,5 +26,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -42,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -35,5 +35,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -40,5 +40,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -42,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -41,5 +41,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -43,5 +43,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -45,5 +45,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -51,5 +51,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -45,5 +45,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -42,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -43,5 +43,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -25,5 +25,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -42,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -47,5 +47,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -50,5 +50,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -42,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -56,5 +56,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -43,5 +43,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -30,5 +30,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -41,5 +41,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -24,7 +24,7 @@
"@types/lodash-es": "^4.17.12",
"@types/mdast": "^4.0.4",
"bytes": "^3.1.2",
"dompurify": "^3.2.4",
"dompurify": "^3.3.0",
"fractional-indexing": "^3.2.0",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -75,5 +75,5 @@
"devDependencies": {
"vitest": "3.1.3"
},
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -20,6 +20,7 @@ import {
type ToDocSnapshotPayload,
type Transformer,
} from '@blocksuite/store';
import DOMPurify from 'dompurify';
import type { Root } from 'hast';
import rehypeParse from 'rehype-parse';
import rehypeStringify from 'rehype-stringify';
@@ -297,7 +298,8 @@ export class HtmlAdapter extends BaseAdapter<Html> {
override async toDocSnapshot(
payload: ToDocSnapshotPayload<string>
): Promise<DocSnapshot> {
const htmlAst = this._htmlToAst(payload.file);
const sanitized = DOMPurify.sanitize(payload.file);
const htmlAst = this._htmlToAst(sanitized);
const titleAst = HastUtils.querySelector(htmlAst, 'title');
const blockSnapshotRoot = {
type: 'block',

View File

@@ -17,7 +17,6 @@ export interface BlockSuiteFlags {
enable_mobile_linked_doc_menu: boolean;
enable_mobile_database_editing: boolean;
enable_block_meta: boolean;
enable_callout: boolean;
enable_edgeless_scribbled_style: boolean;
enable_table_virtual_scroll: boolean;
enable_turbo_renderer: boolean;
@@ -43,7 +42,6 @@ export class FeatureFlagService extends StoreExtension {
enable_mobile_linked_doc_menu: false,
enable_block_meta: true,
enable_mobile_database_editing: false,
enable_callout: false,
enable_edgeless_scribbled_style: false,
enable_table_virtual_scroll: false,
enable_turbo_renderer: false,

View File

@@ -92,6 +92,13 @@ const FileTypes: NonNullable<OpenFilePickerOptions['types']> = [
'application/zip': ['.zip'],
},
},
{
description: 'Docx',
accept: {
'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
['.docx'],
},
},
{
description: 'MindMap',
accept: {
@@ -111,6 +118,7 @@ type AcceptTypes =
| 'Markdown'
| 'Html'
| 'Zip'
| 'Docx'
| 'MindMap';
export async function openFilesWith(

View File

@@ -45,5 +45,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -34,5 +34,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -36,5 +36,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -40,5 +40,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -38,5 +38,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -36,5 +36,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -34,5 +34,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -55,5 +55,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -47,10 +47,7 @@ import {
getTextSelectionCommand,
} from '@blocksuite/affine-shared/commands';
import { REFERENCE_NODE } from '@blocksuite/affine-shared/consts';
import {
FeatureFlagService,
TelemetryProvider,
} from '@blocksuite/affine-shared/services';
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
import type { AffineTextStyleAttributes } from '@blocksuite/affine-shared/types';
import {
createDefaultDoc,
@@ -290,10 +287,11 @@ const textToolActionItems: KeyboardToolbarActionItem[] = [
{
name: 'Callout',
icon: FontIcon(),
showWhen: ({ std, rootComponent: { model } }) => {
return (
std.get(FeatureFlagService).getFlag('enable_callout') &&
!isInsideBlockByFlavour(model.store, model, 'affine:edgeless-text')
showWhen: ({ rootComponent: { model } }) => {
return !isInsideBlockByFlavour(
model.store,
model,
'affine:edgeless-text'
);
},
action: ({ rootComponent: { model }, std }) => {

View File

@@ -28,6 +28,7 @@
"fflate": "^0.8.2",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
"mammoth": "^1.11.0",
"rxjs": "^7.8.1",
"zod": "^3.23.8"
},
@@ -41,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -181,6 +181,10 @@ export class LinkedDocPopover extends SignalWatcher(
target: eventSource,
signal: keydownObserverAbortController.signal,
interceptor: (event, next) => {
if (event.key === 'GroupNext' || event.key === 'GroupPrevious') {
event.stopPropagation();
return;
}
if (event.key === 'ArrowRight' || event.key === 'ArrowLeft') {
event.preventDefault();
event.stopPropagation();

View File

@@ -0,0 +1,47 @@
import type { ExtensionType, Schema, Workspace } from '@blocksuite/store';
// @ts-ignore
import { convertToHtml } from 'mammoth/mammoth.browser';
import { HtmlTransformer } from './html';
type ImportDocxOptions = {
collection: Workspace;
schema: Schema;
imported: Blob;
extensions: ExtensionType[];
};
/**
* Imports a .docx file into a doc.
*
* @param options - The import options.
* @param options.collection - The target doc collection.
* @param options.schema - The schema of the target doc collection.
* @param options.imported - The .docx file as a Blob.
* @returns A Promise that resolves to the ID of the newly created doc, or undefined if import fails.
*/
async function importDocx({
collection,
schema,
imported,
extensions,
}: ImportDocxOptions) {
try {
const { value } = await convertToHtml({
arrayBuffer: await imported.arrayBuffer(),
});
return await HtmlTransformer.importHTMLToDoc({
collection,
schema,
html: value,
extensions,
});
} catch (e) {
console.error('Failed to import .docx file:', e);
return undefined;
}
}
export const DocxTransformer = {
importDocx,
};

View File

@@ -1,3 +1,4 @@
export { DocxTransformer } from './docx.js';
export { HtmlTransformer } from './html.js';
export { MarkdownTransformer } from './markdown.js';
export { NotionHtmlTransformer } from './notion-html.js';

View File

@@ -37,5 +37,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -37,5 +37,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -35,5 +35,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -30,5 +30,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -36,5 +36,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -38,5 +38,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -35,5 +35,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -17,5 +17,5 @@
"dependencies": {
"@blocksuite/affine": "workspace:*"
},
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -64,5 +64,5 @@
"devDependencies": {
"vitest": "3.1.3"
},
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -19,7 +19,7 @@
"@preact/signals-core": "^1.8.0",
"@types/hast": "^3.0.4",
"@types/lodash-es": "^4.17.12",
"dompurify": "^3.2.4",
"dompurify": "^3.3.0",
"fractional-indexing": "^3.2.0",
"lib0": "^0.2.97",
"lit": "^3.2.0",
@@ -47,5 +47,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -42,5 +42,5 @@
"!dist/__tests__",
"shim.d.ts"
],
"version": "0.25.2"
"version": "0.25.5"
}

View File

@@ -33,5 +33,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.2"
"version": "0.25.5"
}

Some files were not shown because too many files have changed in this diff Show More