I used [pdfmake](https://www.npmjs.com/package/pdfmake) to implement an
"export as PDF" feature, and I am happy to share with you!
This should fix#13577, fix#8846, and fix#13959.
A showcase:
[Getting
Started.pdf](https://github.com/user-attachments/files/24013057/Getting.Started.pdf)
Although it might miss rendering some properties currently, it can
evolve in the long run and provide a more native experience for the
users.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
- Experimental "Export to PDF" option added to the export menu (behind a
feature flag)
- PDF export supports headings, paragraphs, lists, code blocks, tables,
images, callouts, linked documents and embedded content
* **Chores**
- Added PDF rendering library and consolidated PDF utilities
- Feature flag introduced to control rollout
* **Tests**
- Comprehensive unit tests added for PDF content rendering logic
<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: DarkSky <darksky2048@gmail.com>
In electron v36, all workers do not work.
The webpack configuration is too complicated, so go back first.
If start a new project with [forge](https://www.electronforge.io/) and
latest electron, the worker works well.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Downgraded the Electron development/runtime used for building and
testing the desktop app from v36 to v35; this is a
development-environment change with no functional or API changes
affecting end users.
<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
https://github.com/user-attachments/assets/d5578060-2c8c-47a5-ba65-ef2e9430518b
This PR adds the ability to group-by date with configuration which an
example is shown in the image below:

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Date-based grouping modes (relative, day, week Sun/Mon, month, year),
a date group renderer, and quick lookup for group-by configs by name.
* **Improvements**
* Enhanced group settings: date sub‑modes, week‑start, per‑group
visibility, Hide All/Show All, date sort order, improved drag/drop and
reorder.
* Consistent popup placement/middleware, nested popup positioning,
per‑item close-on-select, and enforced minimum menu heights.
* UI: empty groups now display "No <property>"; views defensively handle
null/hidden groups.
* **Tests**
* Added unit tests for date-key sorting and comparison.
<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Norkz <richardlora557@gmail.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
It's my first time making a pull request to any repo. If there are any
issues, let me know.
## Summary
Adds Polish language support. Translation is 98% complete (10,447/10,646
words).
## Changes
- Added `pl` to Language type
- Added Polish to SUPPORTED_LANGUAGES with lazy loading
The `pl.json` file already exists in the repo with good translation
coverage. Some AI-related strings are not yet translated but will fall
back to English.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added Polish language support to the application, including localized
language name, native language name, and flag emoji.
<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Updated core dependencies, developer tooling and Rust toolchain to
newer stable versions across the repo
* Upgraded Storybook to v10 and improved ESM path resolution for
storybook tooling
* Broadened native binding platform/architecture support and
strengthened native module version validation, loading and WASI handling
* **New Features**
* Exposed an additional native text export for consumers (enhanced
JS/native surface)
<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
fix#12132, #14006, #13496, #12375, #12132
The previous idb indexer generated a large number of scattered writes
when flushing to disk, which caused CPU and disk write spikes. If the
document volume is extremely large, the accumulation of write
transactions will cause memory usage to continuously increase.
This PR introduces batch writes to mitigate write performance on the web
side, and adds a native indexer on the Electron side to greatly improve
performance.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Full-text search (FTS) added across storage layers and native plugins:
indexing, search, document retrieval, match ranges, and index flushing.
* New SQLite-backed indexer storage, streaming search/aggregate APIs,
and in-memory index with node-building and highlighting.
* **Performance**
* Indexing rewritten for batched, concurrent writes and parallel
metadata updates.
* Search scoring enhanced to consider multiple term positions and
aggregated term data.
* **Other**
* Configurable refresh interval and indexer version bump.
<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Updated dependency versions across the monorepo (notably zod →
^3.25.76 and vitest-related packages → ^3.2.4), plus minor package bumps
to align tooling and libraries. These are manifest/test-tooling updates
only; no public API, behavior, or end-user features were changed.
<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This PR is related to issue
https://github.com/toeverything/AFFiNE/issues/14018
When uploading a new profile photo avatar the Pica function, which is
responsible for reducing and resizing the profile photo, may crash if
the browser's Fingerprint Protection is enabled. This is because
Fingerprint Protection prevents Pica from modifying the canvas.
This fix introduces a try-catch inside the function that calls the
reduction and resizing of the photo. Also, the Error object is no longer
passed directly to the notification service, which also caused issues
previously. Now a message will appear that tells the user that the
upload failed and to check the browser's fingerprint protection (check
photo below).
Affected files: packages/frontend/core/src/utils/reduce-image.ts
<img width="408" height="136" alt="new_error"
src="https://github.com/user-attachments/assets/d140e17c-8c13-4f4b-bdf7-7dd5ddc5c917"
/>
I'm open to any suggestions in terms of wording of the error messages.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved error handling for image compression with clearer,
user-facing messages when compression is blocked or fails.
* Ensures the original or reduced image is reliably returned as a
fallback if compression is not performed.
* Preserves file metadata (original lastModified, name, type) when
returning processed files.
<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: DarkSky <darksky2048@gmail.com>
Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
Added a complete French translation for several user interface elements.
Updated existing translation strings to improve consistency and clarity.
Corrected inaccurate or unclear wording in the language files.
Harmonized terminology to maintain a uniform vocabulary across the
interface.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Localization**
* Corrected Spanish branding text for AFFiNE consistency.
* Expanded French locale with many new keys (AI features, calendar,
import/doc labels, shortcuts).
* Trimmed trailing spaces and fixed grammar, punctuation, diacritics
across French strings.
* Added French "Copied to clipboard" confirmation and other refined UI
labels.
<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
* Added 'Brazilian Portuguese' to the list of supported translation
languages in both backend and frontend.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added Brazilian Portuguese as a supported translation language across
the app.
* Brazilian Portuguese now appears in language selection for translation
actions.
* AI translation prompts now include Brazilian Portuguese as a valid
target option.
* No other translation behaviors or controls were modified.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
Bug: In Edgeless mode, pressing and dragging the middle mouse button
over any element incorrectly triggers DefaultTool in the same frame,
causing unintended selection/drag instead of panning. Dragging on empty
area works because no element intercepts left-click logic.
Reproduction:
- Open an Edgeless canvas
- Press and hold middle mouse button over a shape/text/any element and
drag
- Expected: pan the canvas
- Actual: the element gets selected or moved; no panning occurs
Root cause:
1. PanTool switched via requestAnimationFrame; the current frame’s
pointerDown/pointerMove were handled by DefaultTool first (handing
middle mouse to left-click logic).
2. Selection restore used a live reference to
`this.gfx.selection.surfaceSelections`, which could be mutated by other
selection logic during the temporary pan, leading to incorrect
restoration.
Fix:
- Switch to PanTool immediately on the same frame when middle mouse is
pressed; add a guard to avoid switching if PanTool is already active.
- Snapshot `surfaceSelections` using `slice()` before the temporary
switch; restore it on `pointerup` so external mutations won’t affect
restoration.
- Only register the temporary `pointerup` listener when actually
switching; on release, restore the previous tool (including
`frameNavigator` with `restoredAfterPan: true`) and selection.
Additionally, disable black background when exiting from frameNavigator.
Affected files:
- blocksuite/affine/gfx/pointer/src/tools/pan-tool.ts
Tests:
-
packages/frontend/core/src/blocksuite/__tests__/pan-tool-middle-mouse.spec.ts
- Verifies immediate PanTool switch, selection snapshot restoration,
frameNavigator recovery flag, and no-op when PanTool is already active.
Notes:
- Aligned with docs/contributing/tutorial.md. Local validation
performed. Thanks for reviewing!
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Prevented accidental re-activation of the middle-click pan tool.
* Preserved and restored the user's selection and previous tool options
after panning, including correct handling when returning to the frame
navigator.
* Ensured immediate tool switch to pan and reliable cleanup on
middle-button release.
* **Tests**
* Added tests covering middle-click pan behavior, restoration flows, and
no-op when pan is already active.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Updated rendering quality for images displayed in chat content,
applying a pixelated effect to both row and column layouts.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
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.
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 -->
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>
<!-- 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 -->
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>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added SMTP name configuration field to notification settings.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Hi 👋
Love what you're doing with AFFiNE, I found my Notion replacement in
this app. Coming from Notion and importing my workspaces, I saw the need
to improve the import functionality to replicate the folder hierarchy
from Notion into the AFFiNE folder structure in the `Organize` section.
There are a few issues(i.e. #12961 and #13629 ) of people that expected
the same behavior. This should make it a lot easier for people to move
over.
### Technical description
Improve Notion import functionality to preserve organizational structure
and page icons from exports:
- Add folder hierarchy preservation during Notion import
- Extract and set page icons (emoji and image) from Notion HTML
- Integrate with OrganizeService to recreate folder structure
- Use ExplorerIconService to apply page icons to imported documents
- Tested using production workspace exports from Notion, several
thousand pages and multiple hierarchy levels deep.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- New Features
- Imports from Notion/HTML now recreate folder hierarchies and link
imported pages into that structure.
- Page icons (emoji and supported images) are extracted and attached to
imported pages.
- Import results now include the created root folder for quick access.
- Improvements
- Import flows integrate folder creation and icon assignment with
non-blocking error handling.
- Bug Fixes
- Avoids including undefined page IDs in successful imports.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: DarkSky <darksky2048@gmail.com>
Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added a new Discord community link in the mobile settings Others
section with an animated "Hot" badge
* **Localization**
* Added multilingual support for the new Discord link across all
supported languages
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This pull request integrates RevenueCat into the iOS paywall system,
enabling user authentication and subscription management through the
RevenueCat SDK. It introduces new dependencies, updates the paywall
plugin initialization, and adds logic to fetch and use the current user
identifier from the web context for RevenueCat login. The most important
changes are grouped below:
**RevenueCat Integration and Configuration:**
* Added `purchases-ios-spm` (RevenueCat) as a Swift Package dependency
in `AffinePaywall` and updated `Package.resolved` to track the new
dependency.
(`packages/frontend/apps/ios/App/Packages/AffinePaywall/Package.swift`,
`packages/frontend/apps/ios/App/App.xcworkspace/xcshareddata/swiftpm/Package.resolved`)
[[1]](diffhunk://#diff-7716c691e65a220dad542e024fbf91547c45ea69ddff1d0b6a002a497cd7c8ecR20-R28)
[[2]](diffhunk://#diff-63609de9bdfc08b8a0691a4f0ddb7ddff07ae76b40ec2ee7c12adb7db226eb3cR48-R56)
* Implemented `Paywall.setup()` for initializing RevenueCat
configuration, including setting log level, proxy URL, and a static API
key.
(`packages/frontend/apps/ios/App/Packages/AffinePaywall/Sources/AffinePaywall/Paywall.swift`,
`packages/frontend/apps/ios/App/Plugins/PayWall/PayWallPlugin.swift`)
[[1]](diffhunk://#diff-bce0a21a4e7695b7bf2430cd6b8a85fbc84124cc3be83f3288119992b7abb6cdR8-R30)
[[2]](diffhunk://#diff-1854d318d8fd8736d078f5960373ed440836263649a8193c8ee33e72a99424edR14)
**User Authentication and Subscription State:**
* Enhanced the paywall ViewModel logic to fetch the current user
identifier from the web context (`window.getCurrentUserIdentifier`),
configure RevenueCat, and log in the user before fetching subscription
state. Improved error handling and ensured external entitlement fetching
is robust.
(`packages/frontend/apps/ios/App/Packages/AffinePaywall/Sources/AffinePaywall/Model/ViewModel+Action.swift`)
[[1]](diffhunk://#diff-df2cb61867b4ff10dee98d534cf3c94fe8d48ebaef3f219450a9fba26725fdcbR9)
[[2]](diffhunk://#diff-df2cb61867b4ff10dee98d534cf3c94fe8d48ebaef3f219450a9fba26725fdcbL120-R155)
[[3]](diffhunk://#diff-df2cb61867b4ff10dee98d534cf3c94fe8d48ebaef3f219450a9fba26725fdcbR165)
* Added a global JavaScript function `getCurrentUserIdentifier` to the
iOS web context to retrieve the current user's account ID for use in
RevenueCat login. (`packages/frontend/apps/ios/src/app.tsx`)
**Project Metadata:**
* Downgraded the `objectVersion` in the Xcode project file, possibly to
maintain compatibility with other tools or environments.
(`packages/frontend/apps/ios/App/App.xcodeproj/project.pbxproj`)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Paywall now initializes automatically for a smoother subscription
flow.
* New global API to retrieve the current user identifier from the app
context.
* **Improvements**
* Added integration to better coordinate subscription/login state before
showing paywall options.
* Ensures user identity is validated prior to entitlement checks,
improving accuracy.
* Improved error messages and logging during purchase/login flows.
* **Bug Fixes**
* Fixed intermittent issues where subscription status could fail to load
or appear outdated.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Close https://github.com/toeverything/AFFiNE/issues/13754
#### PR Dependency Tree
* **PR #13763** 👈
This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Updated page layout sizing to no longer force full-height on the docs
body, allowing height to adapt to content.
* Improves natural scrolling and reduces layout constraints in the
workspace “All” page.
* Enhances responsiveness across varying screen sizes by relying on
content and container sizing rules.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Refined vertical spacing in the document icon picker header, reducing
excess top padding and setting a consistent bottom padding for a
cleaner, tighter layout.
* Improves visual alignment and readability without altering
functionality—interactions and behavior remain unchanged.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Updated document title styling for improved readability (larger font,
increased line height, heavier weight).
* Refined spacing so titles align correctly when a document icon is
present (no extra top padding).
* Improved emoji rendering by using a consistent font and removing an
unnecessary visual artifact.
* Simplified title container behavior to ensure stable, predictable
alignment without placeholder-based shifts.
* **Chores**
* Minor UI cleanup and consistency adjustments for the icon/title area.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This pull request makes minor adjustments to the iOS frontend app,
focusing on UI fine-tuning and improving type safety for concurrency.
The most notable changes are a small font size adjustment in the paywall
badge, marking an enum as `Sendable` for safer concurrency, and removing
a StoreKit configuration reference from the Xcode scheme.
UI adjustments:
* Reduced the font size for the badge text in `PackageOptionView` from
12 to 10 for a more refined appearance.
Concurrency and type safety:
* Added the `Sendable` protocol conformance to the `SKUnitCategory` enum
to ensure it can be safely used across concurrency boundaries.
Project configuration:
* Removed the `StoreKitConfigurationFileReference` from the
`App.xcscheme`, which may help streamline scheme configuration or
prevent unnecessary StoreKit file usage during app launch.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- Style
- Tweaked paywall option badge text size for a cleaner, more polished
look.
- Refactor
- Improved concurrency safety in underlying models to enhance stability.
- Chores
- Removed a development-only StoreKit configuration from the iOS debug
launch setup.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->