Compare commits

..

13 Commits

Author SHA1 Message Date
EYHN
4ebe8f5fb4 chore(core): improve export snapshot tool (#6863) 2024-05-13 04:00:47 +00:00
JimmFly
f94306703a feat(core): tag groups sorted alphabetically (#6865)
feat(core): tag groups sorted alphabetically
feat(core): add display group to collection page and tag page

<img width="755" alt="image" src="https://github.com/toeverything/AFFiNE/assets/102217452/17a5abbe-cd1a-4ce2-8adc-f9aa5b6d6e77">
2024-05-13 03:48:17 +00:00
pengx17
3e23878e0f feat: add more tracking events (#6866)
Added most tracking events

what is missing:
- still need a way to track events in blocksuite
- some events may not 100% accurate of the one defined in the PRD
2024-05-13 03:36:32 +00:00
pengx17
bd1733b2a9 chore: remove unused file (#6894) 2024-05-13 02:27:21 +00:00
renovate
31f7f6c9cf chore: bump up @napi-rs/cli version to v3.0.0-alpha.55 (#6900)
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@napi-rs/cli](https://togithub.com/napi-rs/napi-rs) | [`3.0.0-alpha.54` -> `3.0.0-alpha.55`](https://renovatebot.com/diffs/npm/@napi-rs%2fcli/3.0.0-alpha.54/3.0.0-alpha.55) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@napi-rs%2fcli/3.0.0-alpha.55?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@napi-rs%2fcli/3.0.0-alpha.55?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@napi-rs%2fcli/3.0.0-alpha.54/3.0.0-alpha.55?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@napi-rs%2fcli/3.0.0-alpha.54/3.0.0-alpha.55?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>napi-rs/napi-rs (@&#8203;napi-rs/cli)</summary>

### [`v3.0.0-alpha.55`](https://togithub.com/napi-rs/napi-rs/releases/tag/%40napi-rs/cli%403.0.0-alpha.55)

[Compare Source](https://togithub.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.0.0-alpha.54...@napi-rs/cli@3.0.0-alpha.55)

##### Bug Fixes

-   **cli:** prevent the wasm optimization crash the build ([#&#8203;2107](https://togithub.com/napi-rs/napi-rs/issues/2107)) ([c9c3c0e](c9c3c0ed05))
-   **deps:** update dependency [@&#8203;napi-rs/cross-toolchain](https://togithub.com/napi-rs/cross-toolchain) to ^0.0.16 ([#&#8203;2079](https://togithub.com/napi-rs/napi-rs/issues/2079)) ([d022f64](d022f64834))
-   **napi:** set explicit target flag for x86\_64 CI template ([#&#8203;2077](https://togithub.com/napi-rs/napi-rs/issues/2077)) ([ebc1e2c](ebc1e2ca18))

</details>

---

### Configuration

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

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

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

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

---

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

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4zNTEuMiIsInVwZGF0ZWRJblZlciI6IjM3LjM1MS4yIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
2024-05-13 02:16:05 +00:00
pengx17
8af064b663 fix: should not reset identity on app start (#6895) 2024-05-12 12:39:59 +00:00
JimmFly
b8a1fbd6c7 fix(core): add margin to scrollbar when clientBorder has no style (#6867)
close #6684

https://github.com/toeverything/AFFiNE/assets/102217452/9de18009-c718-4bdd-88fd-caafdb5b419c
2024-05-11 05:44:48 +00:00
renovate
e2b057cb93 chore: bump up apple-actions/import-codesign-certs action to v3 (#6869)
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [apple-actions/import-codesign-certs](https://togithub.com/apple-actions/import-codesign-certs) | action | major | `v2` -> `v3` |

---

### Release Notes

<details>
<summary>apple-actions/import-codesign-certs (apple-actions/import-codesign-certs)</summary>

### [`v3`](https://togithub.com/Apple-Actions/import-codesign-certs/releases/tag/v3)

[Compare Source](https://togithub.com/apple-actions/import-codesign-certs/compare/v2...v3)

Upgrade to node 20 plus some other changes

</details>

---

### Configuration

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

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

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

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

---

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

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4zNTEuMiIsInVwZGF0ZWRJblZlciI6IjM3LjM1MS4yIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
2024-05-11 05:32:41 +00:00
renovate
9ac8f3177e chore: bump up @aws-sdk/client-s3 version to v3.574.0 (#6882)
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@aws-sdk/client-s3](https://togithub.com/aws/aws-sdk-js-v3/tree/main/clients/client-s3) ([source](https://togithub.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3)) | [`3.572.0` -> `3.574.0`](https://renovatebot.com/diffs/npm/@aws-sdk%2fclient-s3/3.572.0/3.574.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@aws-sdk%2fclient-s3/3.574.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@aws-sdk%2fclient-s3/3.574.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@aws-sdk%2fclient-s3/3.572.0/3.574.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@aws-sdk%2fclient-s3/3.572.0/3.574.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>aws/aws-sdk-js-v3 (@&#8203;aws-sdk/client-s3)</summary>

### [`v3.574.0`](https://togithub.com/aws/aws-sdk-js-v3/blob/HEAD/clients/client-s3/CHANGELOG.md#35740-2024-05-10)

[Compare Source](https://togithub.com/aws/aws-sdk-js-v3/compare/v3.572.0...v3.574.0)

**Note:** Version bump only for package [@&#8203;aws-sdk/client-s3](https://togithub.com/aws-sdk/client-s3)

</details>

---

### Configuration

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

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

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

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

---

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

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4zNTEuMiIsInVwZGF0ZWRJblZlciI6IjM3LjM1MS4yIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
2024-05-11 05:20:50 +00:00
renovate
931e9968b8 chore: bump up all non-major dependencies (#6856)
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence | Type | Update |
|---|---|---|---|---|---|---|---|
| [@google-cloud/opentelemetry-cloud-monitoring-exporter](https://togithub.com/GoogleCloudPlatform/opentelemetry-operations-js) | [`^0.17.0` -> `^0.18.0`](https://renovatebot.com/diffs/npm/@google-cloud%2fopentelemetry-cloud-monitoring-exporter/0.17.0/0.18.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@google-cloud%2fopentelemetry-cloud-monitoring-exporter/0.18.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@google-cloud%2fopentelemetry-cloud-monitoring-exporter/0.18.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@google-cloud%2fopentelemetry-cloud-monitoring-exporter/0.17.0/0.18.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@google-cloud%2fopentelemetry-cloud-monitoring-exporter/0.17.0/0.18.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | minor |
| [@nx/vite](https://nx.dev) ([source](https://togithub.com/nrwl/nx/tree/HEAD/packages/vite)) | [`19.0.1` -> `19.0.2`](https://renovatebot.com/diffs/npm/@nx%2fvite/19.0.1/19.0.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@nx%2fvite/19.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@nx%2fvite/19.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@nx%2fvite/19.0.1/19.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@nx%2fvite/19.0.1/19.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [node](https://nodejs.org) ([source](https://togithub.com/nodejs/node)) | `20.13.0` -> `20.13.1` | [![age](https://developer.mend.io/api/mc/badges/age/node-version/node/v20.13.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/node-version/node/v20.13.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/node-version/node/v20.13.0/v20.13.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/node-version/node/v20.13.0/v20.13.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) |  | patch |

---

### Release Notes

<details>
<summary>GoogleCloudPlatform/opentelemetry-operations-js (@&#8203;google-cloud/opentelemetry-cloud-monitoring-exporter)</summary>

### [`v0.18.0`](6508117c22...@google-cloud/opentelemetry-cloud-monitoring-exporter@0.18.0)

[Compare Source](6508117c22...@google-cloud/opentelemetry-cloud-monitoring-exporter@0.18.0)

</details>

<details>
<summary>nrwl/nx (@&#8203;nx/vite)</summary>

### [`v19.0.2`](https://togithub.com/nrwl/nx/releases/tag/19.0.2)

[Compare Source](https://togithub.com/nrwl/nx/compare/19.0.1...19.0.2)

##### 19.0.2 (2024-05-09)

##### 🩹 Fixes

-   **bundling:** rollup does not log build errors ([#&#8203;23141](https://togithub.com/nrwl/nx/pull/23141))
-   **bundling:** resolve index files from ts paths when running esbuild without bundling ([#&#8203;23098](https://togithub.com/nrwl/nx/pull/23098))
-   **core:** set yarn berry nodeLinker correctly in migrate command ([#&#8203;23249](https://togithub.com/nrwl/nx/pull/23249))
-   **core:** show project --web shouldn't error ([#&#8203;23251](https://togithub.com/nrwl/nx/pull/23251))
-   **core:** update getLastValueFromAsyncIterableIterator to support AsyncIterables returned from executors ([#&#8203;23229](https://togithub.com/nrwl/nx/pull/23229))
-   **gradle:** run gradle init if no settings.gradle ([#&#8203;23226](https://togithub.com/nrwl/nx/pull/23226))
-   **linter:** ensure config.rules is spread into rules in flat config migration ([#&#8203;23263](https://togithub.com/nrwl/nx/pull/23263))
-   **misc:** create workspaces and default app with the name as provided ([#&#8203;23196](https://togithub.com/nrwl/nx/pull/23196))
-   ⚠️  **misc:** adjust deprecation messages to v20 ([#&#8203;23223](https://togithub.com/nrwl/nx/pull/23223))
-   **nx-dev:** fix home page mobile menu ([#&#8203;23250](https://togithub.com/nrwl/nx/pull/23250))
-   **release:** ensure changelog renderers are resolvable when processing config ([#&#8203;23214](https://togithub.com/nrwl/nx/pull/23214))
-   **vite:** don't generate tasks for remix projects ([#&#8203;22551](https://togithub.com/nrwl/nx/pull/22551))
-   **vite:** get tsconfig from new path including target ([#&#8203;22775](https://togithub.com/nrwl/nx/pull/22775))
-   **webpack:** fix default compiler option ([#&#8203;22762](https://togithub.com/nrwl/nx/pull/22762))
-   **webpack:** don't overwrite output config ([#&#8203;22116](https://togithub.com/nrwl/nx/pull/22116))
-   **webpack:** publicPath and rebaseRootRelative ([#&#8203;20992](https://togithub.com/nrwl/nx/pull/20992))

##### ⚠️  Breaking Changes

-   **misc:** `nx print-affected` was deprecated in 16.4.0 and has been removed
-   **misc:** `nx affected:graph` was deprecated in 16.4.0 and has been removed
-   **misc:** `criticalPath` and `affectedProjects` properties created for `nx graph --file graph.json` was deprecated in 16.2.0 and has been removed

##### ❤️  Thank You

-   andriizavoiko [@&#8203;andriizavoiko](https://togithub.com/andriizavoiko)
-   Craigory Coppola [@&#8203;AgentEnder](https://togithub.com/AgentEnder)
-   Edward Wang [@&#8203;wzc0415](https://togithub.com/wzc0415)
-   Emily Xiong [@&#8203;xiongemi](https://togithub.com/xiongemi)
-   Isaac Mann [@&#8203;isaacplmann](https://togithub.com/isaacplmann)
-   Jack Hsu [@&#8203;jaysoo](https://togithub.com/jaysoo)
-   James Henry [@&#8203;JamesHenry](https://togithub.com/JamesHenry)
-   Jason Jean [@&#8203;FrozenPandaz](https://togithub.com/FrozenPandaz)
-   Krystian Sowiński [@&#8203;plumcoding](https://togithub.com/plumcoding)
-   Leosvel Pérez Espinosa [@&#8203;leosvelperez](https://togithub.com/leosvelperez)
-   Mateo Tibaquirá
-   Matthias Stemmler [@&#8203;ms-tng](https://togithub.com/ms-tng)
-   Mike Peters
-   Sean Sanker

</details>

<details>
<summary>nodejs/node (node)</summary>

### [`v20.13.1`](https://togithub.com/nodejs/node/releases/tag/v20.13.1): 2024-05-09, Version 20.13.1 &#x27;Iron&#x27; (LTS), @&#8203;marco-ippolito

[Compare Source](https://togithub.com/nodejs/node/compare/v20.13.0...v20.13.1)

#### 2024-05-09, Version 20.13.1 'Iron' (LTS), [@&#8203;marco-ippolito](https://togithub.com/marco-ippolito)

##### Revert "tools: install npm PowerShell scripts on Windows"

Due to a regression in the npm installation on Windows, this commit reverts the change that installed npm PowerShell scripts on Windows.

##### Commits

-   \[[`b7d80802cc`](https://togithub.com/nodejs/node/commit/b7d80802cc)] - ***Revert*** "**tools**: install npm PowerShell scripts on Windows" (marco-ippolito) [#&#8203;52897](https://togithub.com/nodejs/node/pull/52897)

</details>

---

### Configuration

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

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

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

👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://togithub.com/renovatebot/renovate/discussions) if that's undesired.

---

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

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4zNTEuMiIsInVwZGF0ZWRJblZlciI6IjM3LjM1MS4yIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
2024-05-10 04:21:32 +00:00
pengx17
c07c7c0969 Revert "chore: bump @pengx17/electron-forge-maker-appimage (#6726)" (#6859)
This reverts commit 964e475c5f.

fix #6829
2024-05-10 04:11:06 +00:00
EYHN
f5dceda0cc fix(core): mixpanel error when opt-out (#6861) 2024-05-10 03:58:45 +00:00
donteatfriedrice
203459679c feat: bump blocksuite (#6852)
## Features
- https://github.com/toeverything/BlockSuite/pull/6995 @fundon

## Bugfix
- https://github.com/toeverything/BlockSuite/pull/7002 @donteatfriedrice
- https://github.com/toeverything/BlockSuite/pull/7000 @regischen
- https://github.com/toeverything/BlockSuite/pull/7001 @fundon
- https://github.com/toeverything/BlockSuite/pull/6999 @Flrande
- https://github.com/toeverything/BlockSuite/pull/6997 @donteatfriedrice
- https://github.com/toeverything/BlockSuite/pull/6996 @regischen
- https://github.com/toeverything/BlockSuite/pull/6994 @L-Sun

## Refactor

## Misc
2024-05-10 03:46:10 +00:00
60 changed files with 1041 additions and 629 deletions

View File

@@ -123,7 +123,7 @@ jobs:
- name: Signing By Apple Developer ID
if: ${{ matrix.spec.platform == 'darwin' }}
uses: apple-actions/import-codesign-certs@v2
uses: apple-actions/import-codesign-certs@v3
with:
p12-file-base64: ${{ secrets.CERTIFICATES_P12 }}
p12-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }}

2
.nvmrc
View File

@@ -1 +1 @@
20.13.0
20.13.1

View File

@@ -59,7 +59,7 @@
"@faker-js/faker": "^8.4.1",
"@istanbuljs/schema": "^0.1.3",
"@magic-works/i18n-codegen": "^0.6.0",
"@nx/vite": "19.0.1",
"@nx/vite": "19.0.2",
"@playwright/test": "^1.44.0",
"@taplo/cli": "^0.7.0",
"@testing-library/react": "^15.0.0",

View File

@@ -32,7 +32,7 @@
"build:debug": "napi build"
},
"devDependencies": {
"@napi-rs/cli": "3.0.0-alpha.54",
"@napi-rs/cli": "3.0.0-alpha.55",
"lib0": "^0.2.93",
"nx": "^19.0.0",
"nx-cloud": "^18.0.0",

View File

@@ -20,7 +20,7 @@
"dependencies": {
"@apollo/server": "^4.10.2",
"@aws-sdk/client-s3": "^3.552.0",
"@google-cloud/opentelemetry-cloud-monitoring-exporter": "^0.17.0",
"@google-cloud/opentelemetry-cloud-monitoring-exporter": "^0.18.0",
"@google-cloud/opentelemetry-cloud-trace-exporter": "^2.1.0",
"@google-cloud/opentelemetry-resource-util": "^2.1.0",
"@keyv/redis": "^2.8.4",

View File

@@ -3,8 +3,8 @@
"private": true,
"type": "module",
"devDependencies": {
"@blocksuite/global": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/store": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/global": "0.14.0-canary-202405100201-e591bb8",
"@blocksuite/store": "0.14.0-canary-202405100201-e591bb8",
"react": "18.3.1",
"react-dom": "18.3.1",
"vitest": "1.6.0"

View File

@@ -11,9 +11,9 @@
"@affine/debug": "workspace:*",
"@affine/env": "workspace:*",
"@affine/templates": "workspace:*",
"@blocksuite/blocks": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/global": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/store": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/blocks": "0.14.0-canary-202405100201-e591bb8",
"@blocksuite/global": "0.14.0-canary-202405100201-e591bb8",
"@blocksuite/store": "0.14.0-canary-202405100201-e591bb8",
"@datastructures-js/binary-search-tree": "^5.3.2",
"foxact": "^0.2.33",
"jotai": "^2.8.0",
@@ -28,8 +28,8 @@
"devDependencies": {
"@affine-test/fixtures": "workspace:*",
"@affine/templates": "workspace:*",
"@blocksuite/block-std": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/presets": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/block-std": "0.14.0-canary-202405100201-e591bb8",
"@blocksuite/presets": "0.14.0-canary-202405100201-e591bb8",
"@testing-library/react": "^15.0.0",
"async-call-rpc": "^6.4.0",
"react": "^18.2.0",

View File

@@ -37,6 +37,10 @@ export class EventBus {
}
}
get root(): EventBus {
return this.parent?.root ?? this;
}
on<T>(id: string, listener: (event: FrameworkEvent<T>) => void) {
if (!this.listeners[id]) {
this.listeners[id] = [];

View File

@@ -75,12 +75,12 @@
"zod": "^3.22.4"
},
"devDependencies": {
"@blocksuite/block-std": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/blocks": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/global": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/block-std": "0.14.0-canary-202405100201-e591bb8",
"@blocksuite/blocks": "0.14.0-canary-202405100201-e591bb8",
"@blocksuite/global": "0.14.0-canary-202405100201-e591bb8",
"@blocksuite/icons": "2.1.50",
"@blocksuite/presets": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/store": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/presets": "0.14.0-canary-202405100201-e591bb8",
"@blocksuite/store": "0.14.0-canary-202405100201-e591bb8",
"@storybook/addon-actions": "^7.6.17",
"@storybook/addon-essentials": "^7.6.17",
"@storybook/addon-interactions": "^7.6.17",

View File

@@ -18,13 +18,13 @@
"@affine/graphql": "workspace:*",
"@affine/i18n": "workspace:*",
"@affine/templates": "workspace:*",
"@blocksuite/block-std": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/blocks": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/global": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/block-std": "0.14.0-canary-202405100201-e591bb8",
"@blocksuite/blocks": "0.14.0-canary-202405100201-e591bb8",
"@blocksuite/global": "0.14.0-canary-202405100201-e591bb8",
"@blocksuite/icons": "2.1.50",
"@blocksuite/inline": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/presets": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/store": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/inline": "0.14.0-canary-202405100201-e591bb8",
"@blocksuite/presets": "0.14.0-canary-202405100201-e591bb8",
"@blocksuite/store": "0.14.0-canary-202405100201-e591bb8",
"@dnd-kit/core": "^6.1.0",
"@dnd-kit/modifiers": "^7.0.0",
"@dnd-kit/sortable": "^8.0.0",

View File

@@ -7,6 +7,7 @@ import type { createStore } from 'jotai';
import { openSettingModalAtom, openWorkspaceListModalAtom } from '../atoms';
import type { useNavigateHelper } from '../hooks/use-navigate-helper';
import { mixpanel } from '../utils/mixpanel';
export function registerAffineNavigationCommands({
t,
@@ -76,6 +77,10 @@ export function registerAffineNavigationCommands({
label: t['com.affine.cmdk.affine.navigation.open-settings'](),
keyBinding: '$mod+,',
run() {
mixpanel.track('SettingsViewed', {
// page:
segment: 'cmdk',
});
store.set(openSettingModalAtom, s => ({
activeTab: 'appearance',
open: !s.open,
@@ -84,6 +89,25 @@ export function registerAffineNavigationCommands({
})
);
unsubs.push(
registerAffineCommand({
id: 'affine:open-account',
category: 'affine:navigation',
icon: <ArrowRightBigIcon />,
label: t['com.affine.cmdk.affine.navigation.open-account-settings'](),
run() {
mixpanel.track('AccountSettingsViewed', {
// page:
segment: 'cmdk',
});
store.set(openSettingModalAtom, s => ({
activeTab: 'account',
open: !s.open,
}));
},
})
);
unsubs.push(
registerAffineCommand({
id: 'affine:goto-trash',

View File

@@ -11,6 +11,7 @@ import type { useTheme } from 'next-themes';
import { openQuickSearchModalAtom } from '../atoms';
import type { useLanguageHelper } from '../hooks/affine/use-language-helper';
import { mixpanel } from '../utils';
export function registerAffineSettingsCommands({
t,
@@ -38,6 +39,9 @@ export function registerAffineSettingsCommands({
label: '',
icon: <SettingsIcon />,
run() {
mixpanel.track('QuickSearchOpened', {
control: 'shortcut',
});
const quickSearchModalState = store.get(openQuickSearchModalAtom);
if (!editor) {

View File

@@ -1,6 +1,7 @@
import { Button, FlexWrapper, notify } from '@affine/component';
import { openSettingModalAtom } from '@affine/core/atoms';
import { SubscriptionService } from '@affine/core/modules/cloud';
import { mixpanel } from '@affine/core/utils';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { AiIcon } from '@blocksuite/icons';
@@ -69,6 +70,11 @@ export const AIOnboardingEdgeless = ({
const mode = useLiveData(doc.mode$);
const goToPricingPlans = useCallback(() => {
mixpanel.track('PlansViewed', {
page: 'whiteboard editor',
segment: 'ai onboarding',
module: 'whiteboard dialog',
});
setSettingModal({
open: true,
activeTab: 'plans',

View File

@@ -2,6 +2,7 @@ import { Button, IconButton, Modal } from '@affine/component';
import { openSettingModalAtom } from '@affine/core/atoms';
import { useBlurRoot } from '@affine/core/hooks/use-blur-root';
import { SubscriptionService } from '@affine/core/modules/cloud';
import { mixpanel } from '@affine/core/utils';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
@@ -122,6 +123,11 @@ export const AIOnboardingGeneral = ({
activeTab: 'plans',
scrollAnchor: 'aiPricingPlan',
});
mixpanel.track('PlansViewed', {
page: 'whiteboard-editor',
segment: 'ai onboarding',
module: 'general',
});
closeAndDismiss();
}, [closeAndDismiss, setSettingModal]);
const onPrev = useCallback(() => {

View File

@@ -1,4 +1,5 @@
import { Tooltip } from '@affine/component/ui/tooltip';
import { mixpanel } from '@affine/core/utils';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useLiveData, useServices } from '@toeverything/infra';
import { useSetAtom } from 'jotai';
@@ -40,6 +41,10 @@ export const UserPlanButton = () => {
open: true,
activeTab: 'plans',
});
mixpanel.track('PlansViewed', {
segment: 'settings panel',
module: 'profile and badge',
});
},
[setSettingModalAtom]
);

View File

@@ -225,6 +225,9 @@ const PlanPrompt = () => {
open: true,
activeTab: 'plans',
});
mixpanel.track('PlansViewed', {
segment: 'doc history',
});
}, [setSettingModalAtom]);
const t = useAFFiNEI18N();
@@ -233,7 +236,7 @@ const PlanPrompt = () => {
return (
<div className={styles.planPromptTitle}>
{
isProWorkspace === null
isProWorkspace !== null
? !isProWorkspace
? t[
'com.affine.history.confirm-restore-modal.plan-prompt.limited-title'

View File

@@ -3,6 +3,7 @@ import { openQuotaModalAtom, openSettingModalAtom } from '@affine/core/atoms';
import { UserQuotaService } from '@affine/core/modules/cloud';
import { WorkspacePermissionService } from '@affine/core/modules/permissions';
import { WorkspaceQuotaService } from '@affine/core/modules/quota';
import { mixpanel } from '@affine/core/utils';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useLiveData, useService, WorkspaceService } from '@toeverything/infra';
import bytes from 'bytes';
@@ -48,6 +49,11 @@ export const CloudQuotaModal = () => {
activeTab: 'plans',
});
mixpanel.track('PlansViewed', {
segment: 'payment wall',
category: 'payment wall storage',
});
setOpen(false);
}, [setOpen, setSettingModalAtom]);

View File

@@ -6,6 +6,7 @@ import {
SubscriptionService,
UserCopilotQuotaService,
} from '@affine/core/modules/cloud';
import { mixpanel } from '@affine/core/utils';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useLiveData, useService } from '@toeverything/infra';
import { cssVar } from '@toeverything/theme';
@@ -46,6 +47,12 @@ export const AIUsagePanel = () => {
open: true,
activeTab: 'billing',
});
mixpanel.track('BillingViewed', {
segment: 'settings panel',
module: 'account usage list',
control: 'change plan button',
type: 'ai subscription',
});
}, [setOpenSettingModal]);
if (loading) {

View File

@@ -162,8 +162,11 @@ const StoragePanel = () => {
const setSettingModalAtom = useSetAtom(openSettingModalAtom);
const onUpgrade = useCallback(() => {
mixpanel.track('Button', {
resolve: 'UpgradeStorage',
mixpanel.track('PlansViewed', {
segment: 'settings panel',
module: 'account usage list',
control: 'cloud storage upgrade button',
type: 'cloud subscription',
});
setSettingModalAtom({
open: true,

View File

@@ -108,17 +108,22 @@ const SubscriptionSettings = () => {
const openPlans = useCallback(
(scrollAnchor?: string) => {
mixpanel.track('Button', {
resolve: 'ChangePlan',
currentPlan: proSubscription?.plan,
mixpanel.track('PlansViewed', {
type: proSubscription?.plan,
category: proSubscription?.recurring,
// page:
segment: 'settings panel',
module: 'billing subscription list',
control: 'change plan button',
});
setOpenSettingModalAtom({
open: true,
activeTab: 'plans',
scrollAnchor: scrollAnchor,
});
},
[proSubscription?.plan, setOpenSettingModalAtom]
[proSubscription?.plan, proSubscription?.recurring, setOpenSettingModalAtom]
);
const gotoCloudPlansSetting = useCallback(() => openPlans(), [openPlans]);
const gotoAiPlanSetting = useCallback(

View File

@@ -1,7 +1,7 @@
import { Button, type ButtonProps } from '@affine/component';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { SubscriptionService } from '@affine/core/modules/cloud';
import { popupWindow } from '@affine/core/utils';
import { mixpanel, popupWindow } from '@affine/core/utils';
import { SubscriptionPlan, SubscriptionRecurring } from '@affine/graphql';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useLiveData, useService } from '@toeverything/infra';
@@ -42,6 +42,10 @@ export const AISubscribe = ({ ...btnProps }: AISubscribeProps) => {
const subscribe = useAsyncCallback(async () => {
setMutating(true);
mixpanel.track('plan upgrade started', {
category: SubscriptionRecurring.Yearly,
type: SubscriptionPlan.AI,
});
try {
const session = await subscriptionService.createCheckoutSession({
recurring: SubscriptionRecurring.Yearly,

View File

@@ -115,15 +115,22 @@ export const SettingSidebar = ({
const loginStatus = useLiveData(useService(AuthService).session.status$);
const generalList = useGeneralSettingList();
const onAccountSettingClick = useCallback(() => {
mixpanel.track('Button', {
resolve: 'AccountSetting',
mixpanel.track('AccountSettingsViewed', {
// page:
segment: 'settings panel',
module: 'settings menu',
control: 'menu item',
});
onTabChange('account', null);
}, [onTabChange]);
const onWorkspaceSettingClick = useCallback(
(subTab: WorkspaceSubTab, workspaceMetadata: WorkspaceMetadata) => {
mixpanel.track('Button', {
resolve: 'WorkspaceSetting',
mixpanel.track(`view workspace setting`, {
// page:
segment: 'settings panel',
module: 'settings menu',
control: 'menu item',
type: subTab,
workspaceId: workspaceMetadata.id,
});
onTabChange(`workspace:${subTab}`, workspaceMetadata);
@@ -148,9 +155,21 @@ export const SettingSidebar = ({
key={key}
title={title}
onClick={() => {
mixpanel.track('Button', {
resolve: key,
});
if (key === 'billing') {
mixpanel.track('BillingViewed', {
// page:
segment: 'settings panel',
module: 'settings menu',
control: 'menu item',
});
} else if (key === 'plans') {
mixpanel.track('PlansViewed', {
// page:
segment: 'settings panel',
module: 'settings menu',
control: 'menu item',
});
}
onTabChange(key, null);
}}
data-testid={testId}

View File

@@ -23,6 +23,7 @@ import { useMembers } from '@affine/core/hooks/affine/use-members';
import { useRevokeMemberPermission } from '@affine/core/hooks/affine/use-revoke-member-permission';
import { WorkspacePermissionService } from '@affine/core/modules/permissions';
import { WorkspaceQuotaService } from '@affine/core/modules/quota';
import { mixpanel } from '@affine/core/utils';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { Permission } from '@affine/graphql';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
@@ -144,6 +145,12 @@ export const CloudWorkspaceMembersPanel = () => {
open: true,
activeTab: 'plans',
});
mixpanel.track('PlansViewed', {
// page:
segment: 'settings panel',
module: 'workspace setting',
control: 'invite member',
});
}, [setSettingModalAtom]);
const listContainerRef = useRef<HTMLDivElement | null>(null);

View File

@@ -11,6 +11,7 @@ import { Button } from '@affine/component/ui/button';
import { Menu, MenuItem, MenuTrigger } from '@affine/component/ui/menu';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { ShareService } from '@affine/core/modules/share-doc';
import { mixpanel } from '@affine/core/utils';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { PublicPageMode } from '@affine/graphql';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
@@ -101,6 +102,12 @@ export const AffineSharePage = (props: ShareMenuProps) => {
await shareService.share.enableShare(
mode === 'edgeless' ? PublicPageMode.Edgeless : PublicPageMode.Page
);
mixpanel.track('ShareCreated', {
segment: 'sharing panel',
module: 'public share',
control: 'share panel',
type: mode,
});
notify.success({
title:
t[

View File

@@ -1,5 +1,6 @@
import { toast } from '@affine/component';
import { getAffineCloudBaseUrl } from '@affine/core/modules/cloud/services/fetch';
import { mixpanel } from '@affine/core/utils';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useCallback, useMemo } from 'react';
@@ -52,10 +53,14 @@ export const useSharingUrl = ({
.catch(err => {
console.error(err);
});
mixpanel.track('ShareLinkCopied', {
module: urlType === 'share' ? 'public share' : 'private share',
type: 'link',
});
} else {
toast('Network not available');
}
}, [sharingUrl, t]);
}, [sharingUrl, t, urlType]);
return {
sharingUrl,

View File

@@ -1,5 +1,6 @@
import { notify } from '@affine/component';
import { authAtom, openSettingModalAtom } from '@affine/core/atoms';
import { mixpanel } from '@affine/core/utils';
import { getBaseUrl } from '@affine/graphql';
import { Trans } from '@affine/i18n';
import { UnauthorizedError } from '@blocksuite/blocks';
@@ -345,6 +346,11 @@ Could you make a new website based on these notes and send back just the html fi
getCurrentStore().set(openSettingModalAtom, {
activeTab: 'billing',
open: true,
scrollAnchor: 'aiPricingPlan',
});
mixpanel.track('PlansViewed', {
segment: 'payment wall',
category: 'payment wall ai action count',
});
});

View File

@@ -11,6 +11,8 @@ import { Export, MoveToTrash } from '@affine/core/components/page-list';
import { useBlockSuiteMetaHelper } from '@affine/core/hooks/affine/use-block-suite-meta-helper';
import { useExportPage } from '@affine/core/hooks/affine/use-export-page';
import { useTrashModalHelper } from '@affine/core/hooks/affine/use-trash-modal-helper';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { mixpanel } from '@affine/core/utils';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import {
@@ -97,8 +99,34 @@ export const PageHeaderMenuButton = ({
const handleDuplicate = useCallback(() => {
duplicate(pageId);
mixpanel.track('DocCreated', {
segment: 'editor header',
module: 'header menu',
control: 'copy doc',
type: 'doc duplicate',
category: 'doc',
});
}, [duplicate, pageId]);
const onImportFile = useAsyncCallback(async () => {
const options = await importFile();
if (options.isWorkspaceFile) {
mixpanel.track('WorkspaceCreated', {
segment: 'editor header',
module: 'header menu',
control: 'import button',
type: 'imported workspace',
});
} else {
mixpanel.track('DocCreated', {
segment: 'editor header',
module: 'header menu',
control: 'import button',
type: 'imported doc',
});
}
}, [importFile]);
const EditMenu = (
<>
{!isJournal && (
@@ -179,7 +207,7 @@ export const PageHeaderMenuButton = ({
</MenuIcon>
}
data-testid="editor-option-menu-import"
onSelect={importFile}
onSelect={onImportFile}
style={menuItemStyle}
>
{t['Import']()}

View File

@@ -36,30 +36,47 @@ export const usePageHelper = (docCollection: DocCollection) => {
return createPageAndOpen('edgeless');
}, [createPageAndOpen]);
const importFileAndOpen = useAsyncCallback(async () => {
const { showImportModal } = await import('@blocksuite/blocks');
const onSuccess = (
pageIds: string[],
options: { isWorkspaceFile: boolean; importedCount: number }
) => {
toast(
`Successfully imported ${options.importedCount} Page${
options.importedCount > 1 ? 's' : ''
}.`
);
if (options.isWorkspaceFile) {
jumpToSubPath(docCollection.id, WorkspaceSubPath.ALL);
return;
}
const importFileAndOpen = useMemo(
() => async () => {
const { showImportModal } = await import('@blocksuite/blocks');
const { promise, resolve, reject } =
Promise.withResolvers<
Parameters<
NonNullable<Parameters<typeof showImportModal>[0]['onSuccess']>
>[1]
>();
const onSuccess = (
pageIds: string[],
options: { isWorkspaceFile: boolean; importedCount: number }
) => {
resolve(options);
toast(
`Successfully imported ${options.importedCount} Page${
options.importedCount > 1 ? 's' : ''
}.`
);
if (options.isWorkspaceFile) {
jumpToSubPath(docCollection.id, WorkspaceSubPath.ALL);
return;
}
if (pageIds.length === 0) {
return;
}
const pageId = pageIds[0];
openPage(docCollection.id, pageId);
};
showImportModal({ collection: docCollection, onSuccess });
}, [docCollection, openPage, jumpToSubPath]);
if (pageIds.length === 0) {
return;
}
const pageId = pageIds[0];
openPage(docCollection.id, pageId);
};
showImportModal({
collection: docCollection,
onSuccess,
onFail: message => {
reject(new Error(message));
},
});
return await promise;
},
[docCollection, openPage, jumpToSubPath]
);
const createLinkedPageAndOpen = useAsyncCallback(
async (pageId: string) => {

View File

@@ -1,5 +1,6 @@
import { DropdownButton, Menu } from '@affine/component';
import { BlockCard } from '@affine/component/card/block-card';
import { mixpanel } from '@affine/core/utils';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { EdgelessIcon, ImportIcon, PageIcon } from '@blocksuite/icons';
import type { PropsWithChildren } from 'react';
@@ -69,11 +70,27 @@ export const NewPageButton = ({
const handleCreateNewPage = useCallback(() => {
createNewPage();
setOpen(false);
mixpanel.track('DocCreated', {
page: 'doc library',
segment: 'all doc',
module: 'doc list header',
control: 'new doc button',
type: 'doc',
category: 'page',
});
}, [createNewPage]);
const handleCreateNewEdgeless = useCallback(() => {
createNewEdgeless();
setOpen(false);
mixpanel.track('DocCreated', {
page: 'doc library',
segment: 'all doc',
module: 'doc list header',
control: 'new whiteboard button',
type: 'doc',
category: 'whiteboard',
});
}, [createNewEdgeless]);
const handleImportFile = useCallback(() => {
@@ -104,10 +121,7 @@ export const NewPageButton = ({
>
<DropdownButton
size={size}
onClick={useCallback(() => {
createNewPage();
setOpen(false);
}, [createNewPage])}
onClick={handleCreateNewPage}
onClickDropDown={useCallback(() => setOpen(open => !open), [])}
>
{children}

View File

@@ -9,6 +9,7 @@ import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { useNavigateHelper } from '@affine/core/hooks/use-navigate-helper';
import type { Tag } from '@affine/core/modules/tag';
import { TagService } from '@affine/core/modules/tag';
import { mixpanel } from '@affine/core/utils';
import type { Collection } from '@affine/env/filter';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import {
@@ -46,6 +47,28 @@ export const PageListHeader = () => {
return t['com.affine.all-pages.header']();
}, [t]);
const onImportFile = useAsyncCallback(async () => {
const options = await importFile();
if (options.isWorkspaceFile) {
mixpanel.track('WorkspaceCreated', {
page: 'doc library',
segment: 'all doc',
module: 'doc list header',
control: 'import button',
type: 'imported workspace',
});
} else {
mixpanel.track('DocCreated', {
page: 'doc library',
segment: 'all doc',
module: 'doc list header',
control: 'import button',
type: 'imported doc',
// category
});
}
}, [importFile]);
return (
<div className={styles.docListHeader}>
<div className={styles.docListHeaderTitle}>{title}</div>
@@ -54,7 +77,7 @@ export const PageListHeader = () => {
testId="new-page-button-trigger"
onCreateEdgeless={createEdgeless}
onCreatePage={createPage}
onImportFile={importFile}
onImportFile={onImportFile}
>
<div className={styles.buttonText}>{t['New Page']()}</div>
</PageListNewPageButton>

View File

@@ -4,7 +4,7 @@ import { TagService } from '@affine/core/modules/tag';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { FavoritedIcon, FavoriteIcon } from '@blocksuite/icons';
import type { DocMeta } from '@blocksuite/store';
import { useLiveData, useService } from '@toeverything/infra';
import { LiveData, useLiveData, useService } from '@toeverything/infra';
import { type ReactNode, useMemo } from 'react';
import * as styles from './group-definitions.css';
@@ -128,7 +128,17 @@ const GroupTagLabel = ({ tag, count }: { tag: Tag; count: number }) => {
};
export const useTagGroupDefinitions = (): ItemGroupDefinition<ListItem>[] => {
const tagList = useService(TagService).tagList;
const tags = useLiveData(tagList.tags$);
const sortedTagsLiveData$ = useMemo(
() =>
LiveData.computed(get =>
get(tagList.tags$).sort((a, b) =>
get(a.value$).localeCompare(get(b.value$))
)
),
[tagList.tags$]
);
const tags = useLiveData(sortedTagsLiveData$);
const t = useAFFiNEI18N();
const untagged = useMemo(

View File

@@ -12,6 +12,7 @@ import { useBlockSuiteMetaHelper } from '@affine/core/hooks/affine/use-block-sui
import { useTrashModalHelper } from '@affine/core/hooks/affine/use-trash-modal-helper';
import { FavoriteItemsAdapter } from '@affine/core/modules/properties';
import { WorkbenchService } from '@affine/core/modules/workbench';
import { mixpanel } from '@affine/core/utils';
import type { Collection, DeleteCollectionInfo } from '@affine/env/filter';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import {
@@ -96,6 +97,13 @@ export const PageOperationCell = ({
const onDuplicate = useCallback(() => {
duplicate(page.id, false);
mixpanel.track('DocCreated', {
segment: 'all doc',
module: 'doc item menu',
control: 'copy doc',
type: 'doc duplicate',
category: 'doc',
});
}, [duplicate, page.id]);
const OperationMenu = (

View File

@@ -3,6 +3,7 @@ import { useGetDocCollectionPageTitle } from '@affine/core/hooks/use-block-suite
import { useJournalHelper } from '@affine/core/hooks/use-journal';
import { CollectionService } from '@affine/core/modules/collection';
import { WorkspaceSubPath } from '@affine/core/shared';
import { mixpanel } from '@affine/core/utils';
import type { Collection } from '@affine/env/filter';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import {
@@ -235,6 +236,9 @@ export const usePageCommands = () => {
page.id,
blockId
);
mixpanel.track('AppendToJournal', {
control: 'cmdk',
});
},
icon: <TodayIcon />,
});
@@ -250,6 +254,10 @@ export const usePageCommands = () => {
const page = pageHelper.createPage();
page.load();
pageMetaHelper.setDocTitle(page.id, query);
mixpanel.track('DocCreated', {
control: 'cmdk',
type: 'doc',
});
},
icon: <PageIcon />,
});
@@ -265,6 +273,10 @@ export const usePageCommands = () => {
const page = pageHelper.createEdgeless();
page.load();
pageMetaHelper.setDocTitle(page.id, query);
mixpanel.track('DocCreated', {
control: 'cmdk',
type: 'whiteboard',
});
},
icon: <EdgelessIcon />,
});

View File

@@ -1,6 +1,7 @@
import { IconButton } from '@affine/component/ui/button';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { FavoriteItemsAdapter } from '@affine/core/modules/properties';
import { mixpanel } from '@affine/core/utils';
import { PlusIcon } from '@blocksuite/icons';
import type { DocCollection } from '@blocksuite/store';
import { useService } from '@toeverything/infra';
@@ -24,10 +25,26 @@ export const AddFavouriteButton = ({
e.stopPropagation();
e.preventDefault();
createLinkedPage(pageId);
mixpanel.track('DocCreated', {
// page:
segment: 'all doc',
module: 'favorite',
control: 'new fav sub doc',
type: 'doc',
category: 'page',
});
} else {
const page = createPage();
page.load();
favAdapter.set(page.id, 'doc', true);
mixpanel.track('DocCreated', {
// page:
segment: 'all doc',
module: 'favorite',
control: 'new fav doc',
type: 'doc',
category: 'page',
});
}
},
[pageId, createLinkedPage, createPage, favAdapter]

View File

@@ -1,3 +1,5 @@
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { mixpanel } from '@affine/core/utils';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { ImportIcon } from '@blocksuite/icons';
@@ -8,8 +10,31 @@ import { usePageHelper } from '../blocksuite/block-suite-page-list/utils';
const ImportPage = ({ docCollection }: { docCollection: DocCollection }) => {
const t = useAFFiNEI18N();
const { importFile } = usePageHelper(docCollection);
const onImportFile = useAsyncCallback(async () => {
const options = await importFile();
if (options.isWorkspaceFile) {
mixpanel.track('WorkspaceCreated', {
page: 'doc library',
segment: 'navigation panel',
module: 'doc list header',
control: 'import button',
type: 'imported workspace',
});
} else {
mixpanel.track('DocCreated', {
page: 'doc library',
segment: 'navigation panel',
module: 'doc list header',
control: 'import button',
type: 'imported doc',
// category
});
}
}, [importFile]);
return (
<MenuItem icon={<ImportIcon />} onClick={importFile}>
<MenuItem icon={<ImportIcon />} onClick={onImportFile}>
{t['Import']()}
</MenuItem>
);

View File

@@ -2,6 +2,7 @@ import { AnimatedDeleteIcon } from '@affine/component';
import { getDNDId } from '@affine/core/hooks/affine/use-global-dnd-helper';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { CollectionService } from '@affine/core/modules/collection';
import { mixpanel } from '@affine/core/utils';
import { apis, events } from '@affine/electron-api';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { FolderIcon, SettingsIcon } from '@blocksuite/icons';
@@ -106,11 +107,23 @@ export const RootAppSidebar = ({
)
);
const allPageActive = currentPath === '/all';
const trashActive = currentPath === '/trash';
const onClickNewPage = useAsyncCallback(async () => {
const page = createPage();
page.load();
openPage(page.id);
}, [createPage, openPage]);
mixpanel.track('DocCreated', {
page: allPageActive ? 'all' : trashActive ? 'trash' : 'other',
segment: 'navigation panel',
module: 'bottom button',
control: 'new doc button',
category: 'page',
type: 'doc',
});
}, [allPageActive, createPage, openPage, trashActive]);
const { trashModal, setTrashModal, handleOnConfirm } =
useTrashModalHelper(docCollection);
@@ -166,10 +179,6 @@ export const RootAppSidebar = ({
});
}, [docCollection.id, collection, navigateHelper, open]);
const allPageActive = currentPath === '/all';
const trashActive = currentPath === '/trash';
return (
<AppSidebar
clientBorder={appSettings.clientBorder}

View File

@@ -14,6 +14,7 @@ import {
openSettingModalAtom,
openSignOutModalAtom,
} from '@affine/core/atoms';
import { mixpanel } from '@affine/core/utils';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { AccountIcon, SignOutIcon } from '@blocksuite/icons';
import { useLiveData, useService } from '@toeverything/infra';
@@ -79,6 +80,12 @@ const AccountMenu = () => {
const setOpenSignOutModalAtom = useSetAtom(openSignOutModalAtom);
const onOpenAccountSetting = useCallback(() => {
mixpanel.track('AccountSettingsViewed', {
// page:
segment: 'navigation panel',
module: 'profile and badge',
control: 'profile and email',
});
setSettingModalAtom(prev => ({
...prev,
open: true,

View File

@@ -23,10 +23,12 @@ export const AppContainer = ({
useNoisyBackground,
useBlurBackground,
children,
...rest
}: WorkspaceRootProps) => {
const noisyBackground = useNoisyBackground && environment.isDesktop;
return (
<div
{...rest}
className={clsx(appStyle, {
'noisy-background': noisyBackground,
'blur-background': environment.isDesktop && useBlurBackground,

View File

@@ -3,6 +3,7 @@ import {
pushGlobalLoadingEventAtom,
resolveGlobalLoadingEventAtom,
} from '@affine/component/global-loading';
import { mixpanel } from '@affine/core/utils';
import { apis } from '@affine/electron-api';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import type { PageRootService, RootBlockModel } from '@blocksuite/blocks';
@@ -25,6 +26,11 @@ async function exportHandler({ page, type }: ExportHandlerOptions) {
if (editorRoot) {
pageService = editorRoot.spec.getService<PageRootService>('affine:page');
}
mixpanel.track('ShareCreated', {
type,
segment: 'sharing panel',
module: 'export share',
});
switch (type) {
case 'html':
await HtmlTransformer.exportDoc(page);

View File

@@ -1,6 +1,7 @@
import { toast } from '@affine/component';
import { useDocMetaHelper } from '@affine/core/hooks/use-block-suite-page-meta';
import { FavoriteItemsAdapter } from '@affine/core/modules/properties';
import { mixpanel } from '@affine/core/utils';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { assertExists } from '@blocksuite/global/utils';
@@ -141,6 +142,11 @@ export function useRegisterBlocksuiteEditorCommands() {
label: t['com.affine.header.option.duplicate'](),
run() {
duplicate(docId);
mixpanel.track('DocCreated', {
control: 'cmdk',
type: 'doc duplicate',
category: 'doc',
});
},
})
);

View File

@@ -40,6 +40,7 @@ import {
} from '../hooks/affine/use-global-dnd-helper';
import { useNavigateHelper } from '../hooks/use-navigate-helper';
import { useRegisterWorkspaceCommands } from '../hooks/use-register-workspace-commands';
import { WorkbenchService } from '../modules/workbench';
import {
AllWorkspaceModals,
CurrentWorkspaceModals,
@@ -62,7 +63,6 @@ export const QuickSearch = () => {
const onToggleQuickSearch = useCallback(
(open: boolean) => {
mixpanel.track('QuickSearch', { open });
setOpenQuickSearchModalAtom(open);
},
[setOpenQuickSearchModalAtom]
@@ -113,6 +113,14 @@ export const WorkspaceLayoutInner = ({ children }: PropsWithChildren) => {
const upgrading = useLiveData(currentWorkspace.upgrade.upgrading$);
const needUpgrade = useLiveData(currentWorkspace.upgrade.needUpgrade$);
const workbench = useService(WorkbenchService).workbench;
const basename = useLiveData(workbench.basename$);
const currentPath = useLiveData(
workbench.location$.map(location => basename + location.pathname)
);
useRegisterWorkspaceCommands();
useEffect(() => {
@@ -143,6 +151,10 @@ export const WorkspaceLayoutInner = ({ children }: PropsWithChildren) => {
const [, setOpenQuickSearchModalAtom] = useAtom(openQuickSearchModalAtom);
const handleOpenQuickSearchModal = useCallback(() => {
setOpenQuickSearchModalAtom(true);
mixpanel.track('QuickSearchOpened', {
segment: 'navigation panel',
control: 'search button',
});
}, [setOpenQuickSearchModalAtom]);
const setOpenSettingModalAtom = useSetAtom(openSettingModalAtom);
@@ -152,6 +164,12 @@ export const WorkspaceLayoutInner = ({ children }: PropsWithChildren) => {
activeTab: 'appearance',
open: true,
});
mixpanel.track('SettingsViewed', {
// page:
segment: 'navigation panel',
module: 'general list',
control: 'settings button',
});
}, [setOpenSettingModalAtom]);
const resizing = useAtomValue(appSidebarResizingAtom);
@@ -171,7 +189,7 @@ export const WorkspaceLayoutInner = ({ children }: PropsWithChildren) => {
<>
{/* This DndContext is used for drag page from all-pages list into a folder in sidebar */}
<DndContext sensors={sensors} onDragEnd={handleDragEnd}>
<AppContainer resizing={resizing}>
<AppContainer data-current-path={currentPath} resizing={resizing}>
<Suspense fallback={<AppSidebarFallback />}>
<RootAppSidebar
isPublicWorkspace={false}

View File

@@ -19,9 +19,14 @@ const EditorChatPanel = ({ editor }: SidebarTabProps) => {
useEffect(() => {
if (!editor) return;
editor.host.spec.getService('affine:page').slots.docLinkClicked.on(() => {
const pageService = editor.host.spec.getService('affine:page');
pageService.slots.docLinkClicked.on(() => {
(chatPanelRef.current as ChatPanel).doc = editor.doc;
});
pageService.slots.editorModeSwitch.on(() => {
(chatPanelRef.current as ChatPanel).host = editor.host;
});
}, [editor]);
if (!editor) {
@@ -32,11 +37,9 @@ const EditorChatPanel = ({ editor }: SidebarTabProps) => {
chatPanelRef.current = new ChatPanel();
}
if (editor !== chatPanelRef.current?.editor) {
(chatPanelRef.current as ChatPanel).editor = editor;
(chatPanelRef.current as ChatPanel).doc = editor.doc;
// (copilotPanelRef.current as CopilotPanel).fitPadding = [20, 20, 20, 20];
}
(chatPanelRef.current as ChatPanel).host = editor.host;
(chatPanelRef.current as ChatPanel).doc = editor.doc;
// (copilotPanelRef.current as CopilotPanel).fitPadding = [20, 20, 20, 20];
return <div className={styles.root} ref={onRefChange} />;
};

View File

@@ -7,10 +7,12 @@ import {
type AuthAccountInfo,
type AuthService,
} from '../../cloud';
import { AccountLoggedOut } from '../../cloud/services/auth';
import { UserQuotaChanged } from '../../cloud/services/user-quota';
@OnEvent(ApplicationStarted, e => e.onApplicationStart)
@OnEvent(AccountChanged, e => e.onAccountChanged)
@OnEvent(AccountChanged, e => e.updateIdentity)
@OnEvent(AccountLoggedOut, e => e.onAccountLoggedOut)
@OnEvent(UserQuotaChanged, e => e.onUserQuotaChanged)
export class TelemetryService extends Service {
private prevQuota: NonNullable<QuotaQuery['currentUser']>['quota'] | null =
@@ -26,23 +28,32 @@ export class TelemetryService extends Service {
track_pageview: true,
persistence: 'localStorage',
});
}
const account = this.auth.session.account$.value;
this.onAccountChanged(account);
}
onAccountChanged(account: AuthAccountInfo | null) {
if (account === null) {
mixpanel.reset();
} else {
mixpanel.reset();
mixpanel.identify(account.id);
mixpanel.people.set({
$email: account.email,
$name: account.label,
$avatar: account.avatar,
mixpanel.register({
appVersion: runtimeConfig.appVersion,
environment: runtimeConfig.appBuildType,
editorVersion: runtimeConfig.editorVersion,
isSelfHosted: Boolean(runtimeConfig.isSelfHosted),
isDesktop: environment.isDesktop,
});
}
const account = this.auth.session.account$.value;
this.updateIdentity(account);
}
updateIdentity(account: AuthAccountInfo | null) {
if (!account) {
return;
}
mixpanel.identify(account.id);
mixpanel.people.set({
$email: account.email,
$name: account.label,
$avatar: account.avatar,
});
}
onAccountLoggedOut() {
mixpanel.reset();
}
onUserQuotaChanged(quota: NonNullable<QuotaQuery['currentUser']>['quota']) {

View File

@@ -1,7 +1,29 @@
import { Service } from '@toeverything/infra';
import { mixpanel } from '@affine/core/utils';
import { createEvent, Service } from '@toeverything/infra';
import { combineLatest, distinctUntilChanged, map, skip } from 'rxjs';
import { Workbench } from '../entities/workbench';
export const WorkbenchLocationChanged = createEvent<string>(
'WorkbenchLocationChanged'
);
export class WorkbenchService extends Service {
constructor() {
super();
combineLatest([this.workbench.location$, this.workbench.basename$])
.pipe(
map(([location, basename]) => basename + location.pathname),
distinctUntilChanged(),
skip(1)
)
.subscribe(newLocation => {
this.eventBus.root.emit(WorkbenchLocationChanged, newLocation);
mixpanel.track_pageview({
location: newLocation,
});
});
}
workbench = this.framework.createEntity(Workbench);
}

View File

@@ -8,6 +8,7 @@ import { EMPTY, mergeMap, switchMap } from 'rxjs';
import { RouteLogic, useNavigateHelper } from '../hooks/use-navigate-helper';
import { AuthService, SubscriptionService } from '../modules/cloud';
import { mixpanel } from '../utils';
import { container } from './subscribe.css';
export const Component = () => {
@@ -68,6 +69,16 @@ export const Component = () => {
});
setMessage('Redirecting...');
location.href = checkout;
mixpanel.track('PlanChangeSucceeded', {
type: plan,
category: recurring,
});
if (plan) {
mixpanel.people.set({
[SubscriptionPlan.AI === plan ? 'ai plan' : plan]: plan,
recurring: recurring,
});
}
} catch (err) {
console.error(err);
setError('Something went wrong. Please try again.');

View File

@@ -6,6 +6,8 @@ import {
} from '@affine/core/components/page-list';
import { Header } from '@affine/core/components/pure/header';
import { WorkspaceModeFilterTab } from '@affine/core/components/pure/workspace-mode-filter-tab';
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { mixpanel } from '@affine/core/utils';
import type { Filter } from '@affine/env/filter';
import { PlusIcon } from '@blocksuite/icons';
import { useService, WorkspaceService } from '@toeverything/infra';
@@ -27,6 +29,28 @@ export const AllPageHeader = ({
workspace.docCollection
);
const onImportFile = useAsyncCallback(async () => {
const options = await importFile();
if (options.isWorkspaceFile) {
mixpanel.track('WorkspaceCreated', {
page: 'doc library',
segment: 'all page',
module: 'doc list header',
control: 'import button',
type: 'imported workspace',
});
} else {
mixpanel.track('DocCreated', {
page: 'doc library',
segment: 'all page',
module: 'doc list header',
control: 'import button',
type: 'imported doc',
// category
});
}
}, [importFile]);
return (
<Header
left={
@@ -46,7 +70,7 @@ export const AllPageHeader = ({
)}
onCreateEdgeless={createEdgeless}
onCreatePage={createPage}
onImportFile={importFile}
onImportFile={onImportFile}
>
<PlusIcon />
</PageListNewPageButton>

View File

@@ -1,4 +1,5 @@
import { IconButton } from '@affine/component';
import { PageDisplayMenu } from '@affine/core/components/page-list';
import { Header } from '@affine/core/components/pure/header';
import { WorkspaceModeFilterTab } from '@affine/core/components/pure/workspace-mode-filter-tab';
import { PlusIcon } from '@blocksuite/icons';
@@ -16,16 +17,19 @@ export const CollectionDetailHeader = ({
return (
<Header
right={
<IconButton
type="default"
icon={<PlusIcon fontSize={16} />}
onClick={onCreate}
className={clsx(
styles.headerCreateNewButton,
styles.headerCreateNewCollectionIconButton,
!showCreateNew && styles.headerCreateNewButtonHidden
)}
/>
<>
<IconButton
type="default"
icon={<PlusIcon fontSize={16} />}
onClick={onCreate}
className={clsx(
styles.headerCreateNewButton,
styles.headerCreateNewCollectionIconButton,
!showCreateNew && styles.headerCreateNewButtonHidden
)}
/>
<PageDisplayMenu />
</>
}
center={<WorkspaceModeFilterTab activeFilter={'collections'} />}
/>

View File

@@ -32,3 +32,7 @@ export const affineDocViewport = style({
},
},
});
export const scrollbar = style({
marginRight: '4px',
});

View File

@@ -1,6 +1,7 @@
import { Scrollable } from '@affine/component';
import { PageDetailSkeleton } from '@affine/component/page-detail-skeleton';
import { PageAIOnboarding } from '@affine/core/components/affine/ai-onboarding';
import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper';
import type { PageRootService } from '@blocksuite/blocks';
import {
BookmarkService,
@@ -90,6 +91,7 @@ const DetailPageImpl = memo(function DetailPageImpl() {
const rightSidebar = useService(RightSidebarService).rightSidebar;
const docCollection = workspace.docCollection;
const mode = useLiveData(doc.mode$);
const { appSettings } = useAppSettingHelper();
const isActiveView = useIsActiveView();
// TODO: remove jotai here
@@ -252,7 +254,11 @@ const DetailPageImpl = memo(function DetailPageImpl() {
docCollection={docCollection}
/>
</Scrollable.Viewport>
<Scrollable.Scrollbar />
<Scrollable.Scrollbar
className={clsx({
[styles.scrollbar]: !appSettings.clientBorder,
})}
/>
</Scrollable.Root>
</AffineErrorBoundary>
{isInTrash ? <TrashPageFooter /> : null}

View File

@@ -66,12 +66,12 @@ export const Component = (): ReactElement => {
},
})
);
window.exportWorkspaceSnapshot = async () => {
window.exportWorkspaceSnapshot = async (docs?: string[]) => {
const zip = await ZipTransformer.exportDocs(
workspace.docCollection,
Array.from(workspace.docCollection.docs.values()).map(collection =>
collection.getDoc()
)
Array.from(workspace.docCollection.docs.values())
.filter(doc => (docs ? docs.includes(doc.id) : true))
.map(doc => doc.getDoc())
);
const url = URL.createObjectURL(zip);
// download url

View File

@@ -1,6 +1,12 @@
import { PageDisplayMenu } from '@affine/core/components/page-list';
import { Header } from '@affine/core/components/pure/header';
import { WorkspaceModeFilterTab } from '@affine/core/components/pure/workspace-mode-filter-tab';
export const TagDetailHeader = () => {
return <Header center={<WorkspaceModeFilterTab activeFilter={'tags'} />} />;
return (
<Header
center={<WorkspaceModeFilterTab activeFilter={'tags'} />}
right={<PageDisplayMenu />}
/>
);
};

View File

@@ -5,17 +5,13 @@ import {
createBrowserRouter as reactRouterCreateBrowserRouter,
Outlet,
redirect,
useLocation,
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
useNavigate,
} from 'react-router-dom';
import { mixpanel } from './utils';
export const NavigateContext = createContext<NavigateFunction | null>(null);
function RootRouter() {
const location = useLocation();
const navigate = useNavigate();
const [ready, setReady] = useState(false);
useEffect(() => {
@@ -23,16 +19,6 @@ function RootRouter() {
setReady(true);
}, []);
useEffect(() => {
mixpanel.track_pageview({
page: location.pathname,
appVersion: runtimeConfig.appVersion,
environment: runtimeConfig.appBuildType,
editorVersion: runtimeConfig.editorVersion,
isSelfHosted: Boolean(runtimeConfig.isSelfHosted),
isDesktop: environment.isDesktop,
});
}, [location]);
return (
ready && (
<NavigateContext.Provider value={navigate}>

View File

@@ -1,8 +1,9 @@
import { appSettingAtom } from '@toeverything/infra';
import { useAtomValue } from 'jotai/react';
import mixpanel from 'mixpanel-browser';
import { useLayoutEffect } from 'react';
import { mixpanel } from './utils';
export function Telemetry() {
const settings = useAtomValue(appSettingAtom);
useLayoutEffect(() => {

View File

@@ -29,10 +29,10 @@
"@affine/env": "workspace:*",
"@affine/i18n": "workspace:*",
"@affine/native": "workspace:*",
"@blocksuite/block-std": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/blocks": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/presets": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/store": "0.14.0-canary-202405082235-4e0896c",
"@blocksuite/block-std": "0.14.0-canary-202405100201-e591bb8",
"@blocksuite/blocks": "0.14.0-canary-202405100201-e591bb8",
"@blocksuite/presets": "0.14.0-canary-202405100201-e591bb8",
"@blocksuite/store": "0.14.0-canary-202405100201-e591bb8",
"@electron-forge/cli": "^7.3.0",
"@electron-forge/core": "^7.3.0",
"@electron-forge/core-utils": "^7.3.0",
@@ -43,7 +43,7 @@
"@electron-forge/plugin-auto-unpack-natives": "^7.3.0",
"@electron-forge/shared-types": "^7.3.0",
"@emotion/react": "^11.11.4",
"@pengx17/electron-forge-maker-appimage": "^1.2.1",
"@pengx17/electron-forge-maker-appimage": "^1.2.0",
"@sentry/electron": "^4.22.0",
"@sentry/esbuild-plugin": "^2.16.1",
"@sentry/react": "^7.109.0",

View File

@@ -1,61 +0,0 @@
import { parse } from 'node:url';
import { app, BrowserWindow, shell } from 'electron';
import { logger } from '../logger';
const redirectUri = 'https://affine.pro/client/auth-callback';
export const oauthEndpoint = `https://accounts.google.com/o/oauth2/v2/auth?client_id=${process.env.AFFINE_GOOGLE_CLIENT_ID}&redirect_uri=${redirectUri}&response_type=code&scope=openid https://www.googleapis.com/auth/userinfo.email profile&access_type=offline&customParameters={"prompt":"select_account"}`;
const tokenEndpoint = 'https://oauth2.googleapis.com/token';
export const getExchangeTokenParams = (code: string) => {
const postData = {
code,
client_id: process.env.AFFINE_GOOGLE_CLIENT_ID || '',
client_secret: process.env.AFFINE_GOOGLE_CLIENT_SECRET || '',
redirect_uri: redirectUri,
grant_type: 'authorization_code',
};
const requestInit: RequestInit = {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams(postData).toString(),
};
return { requestInit, url: tokenEndpoint };
};
export function getGoogleOauthCode() {
return new Promise<ReturnType<typeof getExchangeTokenParams>>(
(resolve, reject) => {
shell.openExternal(oauthEndpoint).catch(e => {
logger.error('Failed to open external url', e);
reject(e);
});
const handleOpenUrl = (_: any, url: string) => {
const mainWindow = BrowserWindow.getAllWindows().find(
w => !w.isDestroyed()
);
const urlObj = parse(url.replace('??', '?'), true);
if (!mainWindow || !url.startsWith('affine://auth-callback')) return;
const code = urlObj.query['code'] as string;
if (!code) return;
logger.info('google sign in code received from callback', code);
app.removeListener('open-url', handleOpenUrl);
resolve(getExchangeTokenParams(code));
};
app.on('open-url', handleOpenUrl);
setTimeout(() => {
reject(new Error('Timed out'));
app.removeListener('open-url', handleOpenUrl);
}, 30000);
}
);
}

View File

@@ -13,7 +13,6 @@ import { getOnboardingWindow } from '../onboarding';
import type { NamespaceHandlers } from '../type';
import { launchStage } from '../windows-manager/stage';
import { getChallengeResponse } from './challenge';
import { getGoogleOauthCode } from './google-auth';
export let isOnline = true;
@@ -63,9 +62,6 @@ export const uiHandlers = {
handleNetworkChange: async (_, _isOnline: boolean) => {
isOnline = _isOnline;
},
getGoogleOauthCode: async () => {
return getGoogleOauthCode();
},
getChallengeResponse: async (_, challenge: string) => {
return getChallengeResponse(challenge);
},

View File

@@ -574,6 +574,7 @@
"com.affine.cmdk.affine.navigation.goto-trash": "Go to Trash",
"com.affine.cmdk.affine.navigation.goto-workspace": "Go to Workspace",
"com.affine.cmdk.affine.navigation.open-settings": "Go to Settings",
"com.affine.cmdk.affine.navigation.open-account-settings": "Go to Account Settings",
"com.affine.cmdk.affine.new-edgeless-page": "New Edgeless",
"com.affine.cmdk.affine.new-page": "New Doc",
"com.affine.cmdk.affine.new-workspace": "New Workspace",

View File

@@ -34,7 +34,7 @@
}
},
"devDependencies": {
"@napi-rs/cli": "3.0.0-alpha.54",
"@napi-rs/cli": "3.0.0-alpha.55",
"@types/node": "^20.12.7",
"@types/uuid": "^9.0.8",
"ava": "^6.1.2",

View File

@@ -5,8 +5,8 @@
"devDependencies": {
"@affine/env": "workspace:*",
"@affine/templates": "workspace:*",
"@aws-sdk/client-s3": "3.572.0",
"@blocksuite/presets": "0.14.0-canary-202405082235-4e0896c",
"@aws-sdk/client-s3": "3.574.0",
"@blocksuite/presets": "0.14.0-canary-202405100201-e591bb8",
"@clack/core": "^0.3.4",
"@clack/prompts": "^0.7.0",
"@magic-works/i18n-codegen": "^0.6.0",

921
yarn.lock

File diff suppressed because it is too large Load Diff