2

video

https://www.bilibili.com/video/BV1Cr4y1Q734/

git

https://www.appflowy.io/

https://github.com/AppFlowy-IO/appflowy

It's star 9.8k in 1 week, and I thought he did it.

Goals & Features

  • Target replacement Notion
  • 100% data management
  • Provided in open source mode, you can change it yourself
  • Multi-platform support
  • The original experience, it is estimated that the flutter relationship is used

Compile and run

    1. git clone
git clone https://github.com/AppFlowy-IO/appflowy.git
    1. Install rust

cd appflowy/frontend

make install_rust

source $HOME/.cargo/env

make install_cargo_make

cargo make install_targets
    1. Switch flutter dev
flutter channel dev

or

fvm use dev
fvm global dev
    1. flutter enable desktop
# for windows
flutter config --enable-windows-desktop

# for macos
flutter config --enable-macos-desktop

# for linux
flutter config --enable-linux-desktop
    1. Open with vscode or other ideas
open appflowy/frontend

Code architecture

  • Technical selection

    • flutter: Multi-terminal adaptation
    • rust: ffi platform interface, server
  • flutter end frontend/app_flowy

  • Front-end business rust layer frontend/rust-lib

  • Shared library shared-lib shared-lib

  • Backend rust api backend

See technical note doc

  • System design description doc/APPFLOWY_SYSTEM_DESIGN.md
                        Frontend                                                     FLowySDK
                                                             │                                              ┌─────────┐
                                                             │                                          ┌7─▶│Handler A│
                                                             │                                          │   └─────────┘
                                                             │                             ┌─────────┐  │   ┌─────────┐
┌──────┐    ┌────┐    ┌──────────────┐                       │                        ┌───▶│Module A │──┼──▶│Handler B│
│Widget│─1─▶│Bloc│─2─▶│ Repository A │─3─┐                   │                        │    └─────────┘  │   └─────────┘
└──────┘    └────┘    └──────────────┘   │                   │                        │                 │   ┌─────────┐
                      ┌──────────────┐   │    ┌───────┐    ┌─┴──┐     ┌───────────┐   │    ┌─────────┐  └──▶│Handler C│
                      │ Repository B │───┼───▶│ Event │─4─▶│FFI │─5──▶│Dispatcher │─6─┼───▶│Module B │      └─────────┘
                      └──────────────┘   │    └───────┘    └─┬──┘     └───────────┘   │    └─────────┘
                      ┌──────────────┐   │                   │                        │
                      │ Repository C │───┘                   │                        │    ┌─────────┐
                      └──────────────┘                       │                        └───▶│Module C │
                                                             │                             └─────────┘
                                                             │
                                                             │

Here are the event flow:

  1. User click on the Widget(The user interface) that invokes the Bloc actions
  2. Bloc calls the repositories to perform additional operations to handle the actions.
  3. Repository offers the functionalities by combining the event, defined in the FlowySDK.
  4. Events will be passed in the FlowySDK through the FFI interface.
  5. Dispatcher parses the event and generates the specific action scheduled in the FlowySDK runtime.
  6. Dispatcher find the event handler declared by the modules.
  7. Handler consumes the event and generates the response. The response will be returned to the widget through the FFI.

The event flow will be discussed in two parts: the frontend implemented in flutter and the FlowySDK implemented in Rust.

  • Linux compilation instructions doc/BUILD_ON_LINUX.md
  • Windows compilation instructions doc/BUILD_ON_WINDOWS.md
  • Contribution and participation instructions doc/CONTRIBUTING.md
  • DDD design description doc/DOMAIN_DRIVEN_DESIGN.md
    ┌──────────────────────────────────────────────────┐         ─────────▶
    │                Presentation Layer                │──┐      Dependency
    └──────────────────────────────────────────────────┘  │
                              │                           │
                              ▼                           │
    ┌──────────────────────────────────────────────────┐  │
    │                Application Layer                 │  │
    └──────────────────────────────────────────────────┘  │
                              │                           │
                              ▼                           │
    ┌──────────────────────────────────────────────────┐  │
    │                   Domain Layer                   │◀─┘
    └──────────────────────────────────────────────────┘
                              ▲
                              │
    ┌──────────────────────────────────────────────────┐
    │               Infrastructure Layer               │
    └──────────────────────────────────────────────────┘

Presentation Layer:

  • Responsible for presenting information to the user and interpreting user commands.
  • Consists of Widgets and also the state of the Widgets.

Application Layer:

  • Defines the jobs the software is supposed to do. (Shouldn't find any UI code or network code)
  • Coordinates the application activity and delegates work to the next layer down.
  • It doesn't contain any complex business logic but the basic validation on the user input before
    passing to the other layer.

Domain Layer:

  • Responsible for representing concepts of the business.
  • Manages the business state or delegated to the infrastructure layer.
  • Self contained and it doesn't depend on any other layers. Domain should be well isolated from the
    other layers.

Infrastructure Layer:

  • Provides generic technical capabilities that support the higher layers. It deals with APIs, persistence and network, etc.
  • Implements the repository interface and hiding the complexity of the Domain layer.
  • Editor doc/EDITOR.md
  • roadmap

https://trello.com/b/NCyXCXXh/appflowy-roadmap

See where the local files are

  • Find sqlite

  • Search local
find ~ -iname 'flowy-database.db'

~/Library/Containers/com.appflowy.macos/Data/Documents/flowy/fd3ada7d-7653-4196-90e1-7de0019627bc/flowy-database.db

flutter plugin

  • flutter-quill

https://github.com/singerdmx/flutter-quill

Rich text editor

  • freezed

https://pub.flutter-io.cn/packages/freezed

Data model generator, support annotation method

  • flutter_colorpicker

https://pub.flutter-io.cn/packages/flutter_colorpicker

Color picker

  • styled_widget

https://pub.flutter-io.cn/packages/styled_widget

Simplify widget definition

Icon(OMIcons.home, color: Colors.white)
  .padding(all: 10)
  .decorated(color: Color(0xff7AC1E7), shape: BoxShape.circle)
  .padding(all: 15)
  .decorated(color: Color(0xffE8F2F7), shape: BoxShape.circle)
  .padding(all: 20)
  .card(
    elevation: 10,
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.circular(20),
    ),
  )
  .alignment(Alignment.center)
  .backgroundColor(Color(0xffEBECF1));
  • get_it

https://pub.flutter-io.cn/packages/get_it

Global access to your business objects, you can split the business and UI

// 定义

final getIt = GetIt.instance;

void setup() {
  getIt.registerSingleton<AppModel>(AppModel());

// Alternatively you could write it if you don't like global variables
  GetIt.I.registerSingleton<AppModel>(AppModel());
}

// 使用

MaterialButton(
  child: Text("Update"),
  onPressed: getIt<AppModel>().update   // given that your AppModel has a method update
),

Summarize

  • Seeing other people’s architecture, I feel that I am weak. I still do a clean field layered design first.
  • flutter bloc, rust ffi web protobuf feel that it is still a mature choice
  • If it continues to be updated, I would also like to see the evolution of the architecture
  • At this stage, it is estimated that the architecture design is still being tested, and there should not be many functions

© Cat brother


独立开发者_猫哥
669 声望129 粉丝