# feature:
## In Browser:
- hidden back&forward button in sidebar.
- back and forward is equal with `window.history.back()` `window.history.forward()`
## In Desktop:
- Back and forward can be controlled through the sidebar, cmdk, and shortcut keys.
- back and forward act on the currently **active** view.
- buttons change disable&enable style based on current active view history
# Refactor:
Move app-sidebar and app-container from @affine/component to @affine/core
## **User description**
use react-transition-state to simplify exit animation
___
## **Type**
enhancement
___
## **Description**
- Integrated `react-transition-state` for managing animations in `ResizePanel` and `CMDKModal` components, simplifying the code and improving maintainability.
- Introduced a shared animation timeout variable to standardize animation durations across components.
- Added `react-transition-state` to dependencies to enable the new animation handling.
___
## **Changes walkthrough**
<table><thead><tr><th></th><th align="left">Relevant files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
<td>
<details>
<summary><strong>resize-panel.tsx</strong><dd><code>Integrate `react-transition-state` for Resize Panel Animations</code></dd></summary>
<hr>
packages/frontend/component/src/components/resize-panel/resize-panel.tsx
<li>Introduced <code>useTransition</code> hook from <code>react-transition-state</code> for managing <br>animations.<br> <li> Added a constant for animation timeout and applied it to the <br>transition.<br> <li> Utilized the transition state to toggle the open state of the resize <br>panel.<br>
</details>
</td>
<td><a href="https:/toeverything/AFFiNE/pull/5923/files#diff-a4d6e633862f63f97c167ff41ba62aff8aebf3e3b2f6e7ce13d5a0e22e8ff287">+12/-0</a> </td>
</tr>
<tr>
<td>
<details>
<summary><strong>modal.css.ts</strong><dd><code>Use Variable for Animation Timeout in Modal CSS</code> </dd></summary>
<hr>
packages/frontend/core/src/components/pure/cmdk/modal.css.ts
<li>Created a variable for animation timeout.<br> <li> Updated animation durations to use the new timeout variable.<br>
</details>
</td>
<td><a href="https:/toeverything/AFFiNE/pull/5923/files#diff-ba8935611b9c1695153d92d08ecb0f7dac73a6197f54ccda5a6e791902cd651d">+6/-3</a> </td>
</tr>
<tr>
<td>
<details>
<summary><strong>modal.tsx</strong><dd><code>Simplify CMDK Modal Animation with `react-transition-state`</code></dd></summary>
<hr>
packages/frontend/core/src/components/pure/cmdk/modal.tsx
<li>Replaced custom animation state management with <code>useTransition</code> hook.<br> <li> Removed old animation state logic and simplified the component.<br> <li> Added animation timeout variable and applied it to the transition.<br>
</details>
</td>
<td><a href="https:/toeverything/AFFiNE/pull/5923/files#diff-ab3fe66c9b1d3a691fafd1aebc9988e840fedfcd09b5b89570838a5a2a9469c9">+13/-33</a> </td>
</tr>
</table></td></tr><tr><td><strong>Dependencies</strong></td><td><table>
<tr>
<td>
<details>
<summary><strong>package.json</strong><dd><code>Add `react-transition-state` Dependency</code> </dd></summary>
<hr>
packages/frontend/core/package.json
- Added `react-transition-state` as a dependency.
</details>
</td>
<td><a href="https:/toeverything/AFFiNE/pull/5923/files#diff-23e0e5dc0ceb004a0a5d3d13e7d00545de7487535ca0e5eab4c5047f1e24eff0">+1/-0</a> </td>
</tr>
</table></td></tr></tr></tbody></table>
___
> ✨ **PR-Agent usage**:
>Comment `/help` on the PR to get a list of all available PR-Agent tools and their descriptions
using a [babel plugin](https://gist.github.com/pengx17/49e24ae8a5a609bdaff122ee8c679d1c) to transform all var(--affine-xxx) to cssVar
Some issues:
- tried ast-grep but it seems to be not easy to add imports conditionally
- current work does not work well with ts with types because babel will strip them out
close TOV-343 AFF-508 TOV-461 TOV-460 TOV-419
Add `isOverCapacity ` status to detect if blob usage exceeds limits.
Add `onCapacityChange` and `onBlobSet` to monitor if the storage or blob exceeds the capacity limit.
Global modals `LocalQuotaModal` and `CloudQuotaModal` have been added, with the upload size of the blob being limited within the modal components.
The notification component has been adjusted, now you can pass in `action` click events and `actionLabel` .
A React wrapper for blocksuite editor from title/meta/doc/edgless fragments.
This PR only **clones** the `AffineEditorContainer`'s existing behavior and make it easier for extension in affine later.
fix TOV-315
### Some core issues:
A customized version of `createComponent` from `@lit/react`. The [existing and solutions in the community](https://github.com/lit/lit/issues/4435) does not work well in our case.
Alternatively in this PR the approach we have is to create web component instances in React lifecycle and then append them to DOM. However this make it hard to wrap the exported Lit component's using React and therefore we will have an additional wrapper tag for the wrapped web component.
To mitigate the migration issue on using React instead of Lit listed on last day, we now use [a proxy to mimic the wrapped React component](https://github.com/toeverything/AFFiNE/pull/5606/files#diff-5b7f0ae7b52a08739d50e78e9ec803c26ff3d3e5437581c692add0de12d3ede5R142-R183) into an `AffineEditorContainer` instance.
fix TOV-280
experimental features ui
- enabled in the workspace settings for a cloud workspace; only show for workspace owner + early access
- a disclaimer prompt will be shown before going to the next feature setting page
- for now only show the ai poc switch, which controls the display of the ai tab in editor's sidepanel
before:
set global `blocksuiteEditorAtom` state in `<BlocksuiteEditorImpl />`
after:
Rename `blocksuiteEditorAtom` to `activeBlocksuiteEditorAtom`
And move the logic of setting this atom to `<PageDetailEditor />`.
benefit:
* make BlocksuiteEditor pure
* keep @toeverything/component clear
* Clarify the purpose of `activeBlocksuiteEditorAtom`
Rewrite sidebar panel using a customized react-resizable-panels version that supports sidebar pixel sizing (not using flex percentages).
Now the left & right sidebar using the same `ResizePanel` impl.
fix https://github.com/toeverything/AFFiNE/issues/5271
fix TOV-163
fix TOV-146
fix TOV-168
fix TOV-109
fix TOV-165
Added the ability to drag page items from the `all pages` view to the sidebar, including `favourites,` `collection` and `trash`. Page items in `favourites` and `collection` can also be dragged between each other. However, linked subpages cannot be dragged.
Additionally, an operation menu and ‘add’ button have been provided for the sidebar’s page items, enabling the addition of a subpage, renaming, deletion or removal from the sidebar.
On the code front, the `useSidebarDrag` hooks have been implemented for consolidating drag events. The functions `getDragItemId` and `getDropItemId` have been created, and they accept type and ID to obtain itemId.
https://github.com/toeverything/AFFiNE/assets/102217452/d06bac18-3c28-41c9-a7d4-72de955d7b11
Add color-scheme to html so that the web will use system scheme when scripts has not being loaded;
Use `(prefers-color-scheme: dark)` so that the css vars do not defer load based on `data-theme`, which is set by next-themes (which is deferred).
- moved `appSettingAtom` to infra since we now have different packages that depends on it. There is no better place to fit in for now
- use atomEffect to sync setting changes to updater related configs to Electron side
- refactored how Electron reacts to updater config changes.
Refactor AFFiNE layout to support new right sidebar.
The new layout:
![image](https://github.com/toeverything/AFFiNE/assets/584378/678a05f5-bd48-4dbe-ad78-7a0bcc979918)
**Highlights:**
- new sidebar UI/UX
- favoring top-down UI components that are composed by basic building blocks in each route, instead of creating universal component like `WorkspaceHeader` that renders every possible cases (which I think is really hard to maintain)
- remove plugin based solution
**Pros/cons for current plugin-based solution:**
The current solution is somewhat a Dependency Injection (DI) approach, where the layout is defined at the top and UI items can be injected using Jotai atom slots.
This approach works well if we want a fully configurable system with everything being handled by plugins. It provides flexibility for custom extensions.
However, this solution is more suitable for single-page applications where the UI is completely controlled by configuration. It becomes challenging to achieve an optimized and visually appealing UI that remains under our control. An example of such a scenario would be a customizable dashboard like Grafana.
Another drawback of the existing solution is that we need to use Jotai and hooks to access context values, resulting in an unclear data flow within the component hierarchy.
**Alternatively, our approach in this PR** provides layout building blocks such as headers and sidebars, which can then be composed in individual route components. The good is that we have cleaner biz component instead of vague all-in-one layout component (like `<WorkspaceHeader />`).
**Issues of the implementation in this PR:**
Some UI layouts that that seems to be defined at the root layout are now defined in individual route component instead.
New 3-col layout component like the right sidebar still needs some abstraction and they are right now just for the detail editor only.
work for #4523
add `appBuildType` to `runtimeConfig`
add `useAppUpdater` to manage client updates
<!--
copilot:summary
-->
### <samp>🤖[[deprecated]](https://githubnext.com/copilot-for-prs-sunset) Generated by Copilot at cdd012c</samp>
This pull request refactors and enhances the update functionality for the frontend. It introduces a new custom hook `useAppUpdater` that simplifies the update logic and state management, and uses it in various components and commands. It also adds more options and feedback for the user to control and monitor the update process, such as manual download, auto-check, and auto-download toggles, and update status and progress indicators. It also updates the `AboutAffine` component to show the app icon, version, and build type. It also adds new translations, dependencies, types, and schemas related to the update functionality.
<img width="1073" alt="image" src="https://github.com/toeverything/AFFiNE/assets/102217452/16ae7a6a-0035-4e57-902b-6b8f63169501">
If network offline or API error happens, the `session` returned by the `useSession` hook will be null, so we can't assume it is not null.
There should be following changes:
1. create a page in ErrorBoundary to let the user refetch the session.
2. The `SessionProvider` stop to pull the new session once the session is null, we need to figure out a way to pull the new session when the network is back or the user click the refetch button.
Close#3287
<!--
copilot:all
-->
### <samp>🤖 Generated by Copilot at d3fdf86</samp>
### Summary
📄🚀🔗
<!--
1. 📄 - This emoji represents the page and edgeless modes of sharing a page, as well as the GraphQL operations and types related to public pages.
2. 🚀 - This emoji represents the functionality of publishing and revoking public pages, as well as the confirmation modal and the notifications for the user.
3. 🔗 - This emoji represents the sharing URL and the query parameter for the share mode, as well as the hooks and functions that generate and use the URL.
-->
This pull request adds a feature to the frontend component of AFFiNE that allows the user to share a page in either `page` or `edgeless` mode, which affects the appearance and functionality of the page. It also adds the necessary GraphQL operations, types, and schema to support this feature in the backend, and updates the tests and the storybook stories accordingly.
* Modify the `useIsSharedPage` hook to accept an optional `shareMode` argument and use the `getWorkspacePublicPagesQuery`, `publishPageMutation`, and `revokePublicPageMutation` from `@affine/graphql`