AFFiNE/packages/frontend/apps/electron
akumatus 2f79104bdb
feat(core): support ai insert image, mindmap, slides and make it real in page mode (#9164)
Support issue [BS-2085](https://linear.app/affine-design/issue/BS-2085).

### What changed?
- Refactor the `actionToAnswerRenderer` function to support reuse in both page mode and edgeless mode.
- Add a new `page-response.ts` module to handle AI-generated answers in page mode.
    - Remove the redundant `edgelessHandler` function from `_common/config.ts`.
- Introduce the `AIContext` class along with the `ctx` TypeScript type to standardize context management.
- Implement the `createTemplateJob` function to enable AI slide insertion in both page mode and edgeless mode.

Insert mindmap on page mode:
<div class='graphite__hidden'>
          <div>🎥 Video uploaded on Graphite:</div>
            <a href="https://app.graphite.dev/media/video/sJGviKxfE3Ap685cl5bj/30630d3e-ebd9-416b-9bb9-5f27086e48a3.mov">
              <img src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/sJGviKxfE3Ap685cl5bj/30630d3e-ebd9-416b-9bb9-5f27086e48a3.mov">
            </a>
          </div>
<video src="https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/sJGviKxfE3Ap685cl5bj/30630d3e-ebd9-416b-9bb9-5f27086e48a3.mov">mindmap.mov</video>

Insert image on edgeless note
<div class='graphite__hidden'>
          <div>🎥 Video uploaded on Graphite:</div>
            <a href="https://app.graphite.dev/media/video/sJGviKxfE3Ap685cl5bj/b850ee5a-a06b-4ae7-8b68-ed5929a6e81a.mov">
              <img src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/sJGviKxfE3Ap685cl5bj/b850ee5a-a06b-4ae7-8b68-ed5929a6e81a.mov">
            </a>
          </div>
<video src="https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/sJGviKxfE3Ap685cl5bj/b850ee5a-a06b-4ae7-8b68-ed5929a6e81a.mov">image3.mov</video>

Insert image on page mode:
<div class='graphite__hidden'>
          <div>🎥 Video uploaded on Graphite:</div>
            <a href="https://app.graphite.dev/media/video/sJGviKxfE3Ap685cl5bj/c4f98e2d-0b15-4310-b3e0-0725e330302b.mov">
              <img src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/sJGviKxfE3Ap685cl5bj/c4f98e2d-0b15-4310-b3e0-0725e330302b.mov">
            </a>
          </div>
<video src="https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/sJGviKxfE3Ap685cl5bj/c4f98e2d-0b15-4310-b3e0-0725e330302b.mov">image.mov</video>

Generate image from image:
<div class='graphite__hidden'>
          <div>🎥 Video uploaded on Graphite:</div>
            <a href="https://app.graphite.dev/media/video/sJGviKxfE3Ap685cl5bj/2776a55f-cbb7-47ce-8e7d-7cae243fa3e9.mov">
              <img src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/sJGviKxfE3Ap685cl5bj/2776a55f-cbb7-47ce-8e7d-7cae243fa3e9.mov">
            </a>
          </div>
<video src="https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/sJGviKxfE3Ap685cl5bj/2776a55f-cbb7-47ce-8e7d-7cae243fa3e9.mov">image2.mov</video>

Insert presentation on page mode:
<div class='graphite__hidden'>
          <div>🎥 Video uploaded on Graphite:</div>
            <a href="https://app.graphite.dev/media/video/sJGviKxfE3Ap685cl5bj/4e228fa5-88f4-478c-8b79-647612d5515c.mov">
              <img src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/sJGviKxfE3Ap685cl5bj/4e228fa5-88f4-478c-8b79-647612d5515c.mov">
            </a>
          </div>
<video src="https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/sJGviKxfE3Ap685cl5bj/4e228fa5-88f4-478c-8b79-647612d5515c.mov">ppt.mov</video>

Insert make it real on page mode:

<div class='graphite__hidden'>
          <div>🎥 Video uploaded on Graphite:</div>
            <a href="https://app.graphite.dev/media/video/sJGviKxfE3Ap685cl5bj/c71139b2-fb55-4d89-84e2-d52eeb905b57.mov">
              <img src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/sJGviKxfE3Ap685cl5bj/c71139b2-fb55-4d89-84e2-d52eeb905b57.mov">
            </a>
          </div>
<video src="https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/sJGviKxfE3Ap685cl5bj/c71139b2-fb55-4d89-84e2-d52eeb905b57.mov">make it real.mov</video>
2024-12-16 10:04:16 +00:00
..
renderer feat(electron): spellcheck setting (#8730) 2024-11-11 13:03:33 +00:00
resources refactor: new project struct (#8199) 2024-09-12 07:42:57 +00:00
scripts chore: disable rules in oxlint (#9154) 2024-12-13 10:49:35 +00:00
src chore: disable rules in oxlint (#9154) 2024-12-13 10:49:35 +00:00
test feat(nbstore): add sqlite implementation (#8811) 2024-12-13 06:13:05 +00:00
.gitignore refactor: new project struct (#8199) 2024-09-12 07:42:57 +00:00
dev-app-update.yml refactor: new project struct (#8199) 2024-09-12 07:42:57 +00:00
forge.config.mjs chore: add electronZipDir env which helps to offline build (#8983) 2024-12-02 21:55:45 +08:00
package.json feat(core): support ai insert image, mindmap, slides and make it real in page mode (#9164) 2024-12-16 10:04:16 +00:00
project.json refactor: new project struct (#8199) 2024-09-12 07:42:57 +00:00
README.md refactor: new project struct (#8199) 2024-09-12 07:42:57 +00:00
tsconfig.json refactor: new project struct (#8199) 2024-09-12 07:42:57 +00:00
tsconfig.node.json refactor: new project struct (#8199) 2024-09-12 07:42:57 +00:00
tsconfig.test.json refactor: new project struct (#8199) 2024-09-12 07:42:57 +00:00
vitest.config.ts refactor: new project struct (#8199) 2024-09-12 07:42:57 +00:00

AFFiNE Electron App

Development

To run AFFiNE Desktop Client Application locally, run the following commands:

# in repo root
yarn install
yarn workspace @affine/native build
yarn dev

# in packages/frontend/apps/electron
yarn generate-assets
yarn dev # or yarn prod for production build

Troubleshooting

If you have trouble building electron during yarn install, try setting mirror environment variable:

export ELECTRON_MIRROR="https://registry.npmmirror.com/-/binary/electron/"

Credits

Most of the boilerplate code is generously borrowed from the following