git

www.appflowy.io/

Github.com/AppFlowy-IO…

Star 9.8K in 1 week, I thought he did it.

Objectives & Features

  • Object substitution Notion

  • Data is 100% self-managed

  • Open source way to provide, you can change

  • Multi-platform support

  • Native experience, presumably with flutter relations

Compile operation

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

cd appflowy/frontend

make install_rust

source $HOME/.cargo/env

make install_cargo_make

cargo make install_targets

Copy the code
    1. Switch flutter dev
flutter channel dev

or

fvm use dev
fvm global dev

Copy the code
    1. Flutter to enable the desktop
# for windows
flutter config --enable-windows-desktop

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

# for linux
flutter config --enable-linux-desktop
Copy the code
    1. Open it with vscode or other idea
open appflowy/frontend
Copy the code

The code architecture

  • Technology selection

    • Flutter: multiple adaptations

    • Rust: FFI platform interface and server

  • Flutter frontend/app_flowy

  • Front-end service Rust layerfrontend/rust-lib

  • The Shared library Shared – libshared-lib

  • The back-end rust APIbackend

Refer to technical notesdoc

  • System Design Descriptiondoc/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 │ │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │ │Copy the code

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 description doc/ build_on_linux.md

  • Windows compilation description doc/ build_on_windows.md

  • Contribution participation notes doc/CONTRIBUTING. Md

  • DDD design description doc/ domain_driven_design.md

┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ─ ─ ─ ─ ─ ─ ─ ─ ─ ▶ │ the Presentation Layer │ ─ ─ ┐ Dependency └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │ │ │ ▼ │ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │ │ Application Layer │ │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │ │ │ ▼ │ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │ │ Domain Layer │ ◀ ─ ┘ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ bring │ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │ Infrastructure Layer │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘Copy the code

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. The md

  • roadmap

Trello.com/b/NCyXCXXh/…

See where the local files are

  • To find the sqlite

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

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

Flutter plug-in

  • flutter-quill

Github.com/singerdmx/f…

Rich text editor

  • freezed

Pub. Flutter – IO. Cn/packages/fr…

Data model generator, support annotation mode

  • flutter_colorpicker

Pub. Flutter – IO. Cn/packages/fl…

Color picker

  • styled_widget

Pub. Flutter – IO. Cn/packages/st…

Simplify widget definitions

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));
Copy the code
  • get_it

Pub. Flutter – IO. Cn/packages/ge…

With global access to your business objects, you can split business and UI

/ / define

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());
}

/ / use

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

Copy the code

conclusion

  • Seeing the architecture of others, I feel that I am too weak, I still want to do a clean layered design
  • The flutter Bloc, rust ffi Web protobuf feels like a mature choice
  • I’d love to see how the architecture evolves if updates continue
  • At this stage, I am still testing the architecture design, so I don’t think there will be many features

The elder brother of the © cat

  • ducafecat.tech/

  • github.com/ducafecat

  • Ducafecat WeChat group