mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-04-24 14:47:13 -04:00
chore: Merge branch 'main' into release/0.0.9.1
This commit is contained in:
commit
1b295c0ab6
654 changed files with 8077 additions and 4021 deletions
3
.github/workflows/appflowy_editor_test.yml
vendored
3
.github/workflows/appflowy_editor_test.yml
vendored
|
@ -15,6 +15,7 @@ on:
|
|||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
FLUTTER_VERSION: "3.3.9"
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
|
@ -30,7 +31,7 @@ jobs:
|
|||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
flutter-version: "3.0.5"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
- name: Run FlowyEditor tests
|
||||
|
|
86
.github/workflows/dart_lint.yml
vendored
86
.github/workflows/dart_lint.yml
vendored
|
@ -1,86 +0,0 @@
|
|||
# This workflow uses actions that are not certified by GitHub.
|
||||
# They are provided by a third-party and are governed by
|
||||
# separate terms of service, privacy policy, and support
|
||||
# documentation.
|
||||
|
||||
name: Flutter lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
- "release/*"
|
||||
paths:
|
||||
- "frontend/app_flowy/**"
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- "main"
|
||||
- "release/*"
|
||||
paths:
|
||||
- "frontend/app_flowy/**"
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
flutter-analyze:
|
||||
name: flutter analyze
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- uses: subosito/flutter-action@v1
|
||||
with:
|
||||
flutter-version: "3.0.5"
|
||||
channel: "stable"
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: "stable-2022-04-07"
|
||||
|
||||
- name: Cache Cargo
|
||||
id: cache-cargo
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.cargo
|
||||
key: ${{ runner.os }}-cargo-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}
|
||||
|
||||
- name: Cache Rust
|
||||
id: cache-rust-target
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
frontend/rust-lib/target
|
||||
shared-lib/target
|
||||
key: ${{ runner.os }}-rust-rust-lib-share-lib-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}
|
||||
|
||||
- if: steps.cache-cargo.outputs.cache-hit != 'true'
|
||||
name: Rust Deps
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo install cargo-make
|
||||
|
||||
- name: Cargo make flowy dev
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo make appflowy-deps-tools
|
||||
|
||||
- name: Flutter Deps
|
||||
run: flutter packages pub get
|
||||
working-directory: frontend/app_flowy
|
||||
|
||||
- name: Build FlowySDK
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo make --profile development-linux-x86_64 appflowy-sdk-dev
|
||||
|
||||
- name: Flutter Code Generation
|
||||
working-directory: frontend/app_flowy
|
||||
run: |
|
||||
flutter packages pub run easy_localization:generate -f keys -o locale_keys.g.dart -S assets/translations -s en.json
|
||||
flutter packages pub run build_runner build --delete-conflicting-outputs
|
||||
|
||||
- name: Run Flutter Analyzer
|
||||
working-directory: frontend/app_flowy
|
||||
run: flutter analyze
|
80
.github/workflows/dart_test.yml
vendored
80
.github/workflows/dart_test.yml
vendored
|
@ -1,80 +0,0 @@
|
|||
name: Frontend test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
- "release/*"
|
||||
paths:
|
||||
- "frontend/app_flowy/**"
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- "main"
|
||||
- "release/*"
|
||||
paths:
|
||||
- "frontend/app_flowy/**"
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: "stable-2022-04-07"
|
||||
|
||||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
flutter-version: "3.0.5"
|
||||
cache: true
|
||||
|
||||
- name: Cache Cargo
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.cargo
|
||||
key: ${{ runner.os }}-cargo-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}
|
||||
|
||||
- name: Cache Rust
|
||||
id: cache-rust-target
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
frontend/rust-lib/target
|
||||
shared-lib/target
|
||||
key: ${{ runner.os }}-rust-rust-lib-share-lib-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}
|
||||
|
||||
- if: steps.cache-cargo.outputs.cache-hit != 'true'
|
||||
name: Rust Deps
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo install cargo-make
|
||||
cargo make appflowy-deps-tools
|
||||
|
||||
- name: Flutter Deps
|
||||
working-directory: frontend/app_flowy
|
||||
run: |
|
||||
flutter config --enable-linux-desktop
|
||||
|
||||
- name: Build Test lib
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo make --profile test-linux build-test-lib
|
||||
|
||||
- name: Flutter Code Generation
|
||||
working-directory: frontend/app_flowy
|
||||
run: |
|
||||
flutter packages pub get
|
||||
flutter packages pub run easy_localization:generate -f keys -o locale_keys.g.dart -S assets/translations -s en.json
|
||||
flutter packages pub run build_runner build --delete-conflicting-outputs
|
||||
|
||||
- name: Run bloc tests
|
||||
working-directory: frontend/app_flowy
|
||||
run: |
|
||||
flutter pub get
|
||||
flutter test
|
|
@ -1,89 +1,87 @@
|
|||
name: CI
|
||||
name: Flutter-CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
- "release/*"
|
||||
paths:
|
||||
- "frontend/**"
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- "main"
|
||||
- "release/*"
|
||||
paths:
|
||||
- "frontend/**"
|
||||
|
||||
env:
|
||||
FLUTTER_VERSION: "3.3.9"
|
||||
RUST_TOOLCHAIN: "1.65"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
flutter_profile: development-linux-x86_64
|
||||
target: x86_64-unknown-linux-gnu
|
||||
- os: macos-latest
|
||||
flutter_profile: development-mac-x86_64
|
||||
target: x86_64-apple-darwin
|
||||
- os: windows-latest
|
||||
flutter_profile: development-windows-x86
|
||||
target: x86_64-pc-windows-msvc
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- id: rust_toolchain
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: "stable-2022-04-07"
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
target: ${{ matrix.target }}
|
||||
override: true
|
||||
profile: minimal
|
||||
|
||||
- id: flutter
|
||||
- name: Install flutter
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
flutter-version: "3.0.5"
|
||||
|
||||
- name: Cache Cargo
|
||||
id: cache-cargo
|
||||
uses: actions/cache@v2
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.cargo
|
||||
key: ${{ runner.os }}-cargo-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}
|
||||
prefix-key: ${{ matrix.job.os }}
|
||||
|
||||
- name: Cache Rust
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
frontend/rust-lib/target
|
||||
shared-lib/target
|
||||
key: ${{ runner.os }}-rust-rust-lib-share-lib-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}
|
||||
|
||||
- name: Setup Environment
|
||||
- name: Install prerequisites
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo install --force cargo-make
|
||||
cargo install --force duckscript_cli
|
||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||
sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub
|
||||
sudo wget -qO /etc/apt/sources.list.d/dart_stable.list https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y dart curl build-essential libsqlite3-dev libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev
|
||||
sudo apt-get install -y dart curl build-essential libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev
|
||||
sudo apt-get install keybinder-3.0
|
||||
elif [ "$RUNNER_OS" == "Windows" ]; then
|
||||
vcpkg integrate install
|
||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||
echo 'do nothing'
|
||||
fi
|
||||
cargo make appflowy-deps-tools
|
||||
shell: bash
|
||||
|
||||
- if: steps.cache-cargo.outputs.cache-hit != 'true'
|
||||
name: Deps
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo install cargo-make
|
||||
cargo install duckscript_cli
|
||||
|
||||
- name: Cargo make appflowy-deps-tools
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo make appflowy-deps-tools
|
||||
|
||||
- name: Config Flutter
|
||||
- name: Enable Flutter Desktop
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||
flutter config --enable-linux-desktop
|
||||
|
@ -94,7 +92,16 @@ jobs:
|
|||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Build
|
||||
- name: Build AppFlowy
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo make --profile ${{ matrix.flutter_profile }} appflowy-dev
|
||||
|
||||
- name: Flutter Analyzer
|
||||
working-directory: frontend/app_flowy
|
||||
run: flutter analyze
|
||||
|
||||
- name: Run Flutter unit tests
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo make dart_unit_test
|
2
.github/workflows/integration_test.yml
vendored
2
.github/workflows/integration_test.yml
vendored
|
@ -35,7 +35,7 @@ jobs:
|
|||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
flutter-version: "3.0.5"
|
||||
flutter-version: "3.3.9"
|
||||
cache: true
|
||||
|
||||
- name: Cache Cargo
|
||||
|
|
507
.github/workflows/release.yml
vendored
507
.github/workflows/release.yml
vendored
|
@ -5,6 +5,10 @@ on:
|
|||
tags:
|
||||
- '*'
|
||||
|
||||
env:
|
||||
FLUTTER_VERSION: "3.3.9"
|
||||
RUST_TOOLCHAIN: "1.65"
|
||||
|
||||
jobs:
|
||||
create-release:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -31,268 +35,48 @@ jobs:
|
|||
release_name: v${{ github.ref }}
|
||||
body_path: ${{ env.RELEASE_NOTES_PATH }}
|
||||
|
||||
build-linux-x86:
|
||||
runs-on: ubuntu-latest
|
||||
needs: create-release
|
||||
env:
|
||||
LINUX_APP_RELEASE_PATH: frontend/app_flowy/product/${{ github.ref_name }}/linux/Release
|
||||
LINUX_ZIP_NAME: AppFlowy-linux-x86.tar.gz
|
||||
LINUX_PACKAGE_NAME: AppFlowy_${{ github.ref_name }}_linux-amd64.deb
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup environment - Rust and Cargo
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: 'stable-2022-04-07'
|
||||
|
||||
- name: Setup environment - Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version: '3.0.5'
|
||||
|
||||
- name: Pre build
|
||||
working-directory: frontend
|
||||
run: |
|
||||
sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y build-essential libsqlite3-dev libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev
|
||||
sudo apt-get install keybinder-3.0
|
||||
source $HOME/.cargo/env
|
||||
cargo install --force cargo-make
|
||||
cargo install --force duckscript_cli
|
||||
cargo make appflowy-deps-tools
|
||||
|
||||
- name: Build Linux app
|
||||
working-directory: frontend
|
||||
run: |
|
||||
flutter config --enable-linux-desktop
|
||||
cargo make --env APP_VERSION=${{ github.ref_name }} --profile production-linux-x86_64 appflowy
|
||||
|
||||
- name: Configuring Linux Package
|
||||
working-directory: frontend
|
||||
run: |
|
||||
mkdir -p ../${{ env.LINUX_APP_RELEASE_PATH }}/package/opt
|
||||
mkdir -p ../${{ env.LINUX_APP_RELEASE_PATH }}/package/usr/share/applications
|
||||
cp -r ./scripts/linux_installer ../${{ env.LINUX_APP_RELEASE_PATH }}/package/DEBIAN
|
||||
cd ../${{ env.LINUX_APP_RELEASE_PATH }}/package/DEBIAN
|
||||
grep -rl "\[CHANGE_THIS\]" ./control | xargs sed -i "s/\[CHANGE_THIS\]/${{ github.ref_name }}/"
|
||||
chmod 0755 {postinst,postrm}
|
||||
|
||||
- name: Build Linux package
|
||||
working-directory: ${{ env.LINUX_APP_RELEASE_PATH }}
|
||||
run: |
|
||||
mv AppFlowy package/opt/
|
||||
cd package
|
||||
|
||||
# Update Exec & icon path in desktop entry
|
||||
grep -rl "\[CHANGE_THIS\]" ./opt/AppFlowy/appflowy.desktop.temp | xargs sed -i "s/\[CHANGE_THIS\]/\/opt/"
|
||||
# Add desktop entry in package
|
||||
mv ./opt/AppFlowy/appflowy.desktop.temp ./usr/share/applications/appflowy.desktop
|
||||
|
||||
# Build
|
||||
cd ../ && dpkg-deb --build --root-owner-group -Z xz package ${{ env.LINUX_PACKAGE_NAME }}
|
||||
|
||||
- name: Upload Release Asset
|
||||
id: upload-release-asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||
asset_path: ${{ env.LINUX_APP_RELEASE_PATH }}/${{ env.LINUX_ZIP_NAME }}
|
||||
asset_name: ${{ env.LINUX_ZIP_NAME }}
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
- name: Upload Release Asset Install Package
|
||||
id: upload-release-asset-install-package
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||
asset_path: ${{ env.LINUX_APP_RELEASE_PATH }}/${{ env.LINUX_PACKAGE_NAME }}
|
||||
asset_name: ${{ env.LINUX_PACKAGE_NAME }}
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
build-linux-x86-alt:
|
||||
runs-on: ubuntu-18.04
|
||||
needs: create-release
|
||||
env:
|
||||
LINUX_APP_RELEASE_PATH: frontend/app_flowy/product/${{ github.ref_name }}/linux/Release
|
||||
LINUX_PACKAGE_NAME: AppFlowy_${{ github.ref_name }}_linux-amd64-alt.deb
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup environment - Rust and Cargo
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: 'stable-2022-04-07'
|
||||
|
||||
- name: Setup environment - Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version: '3.0.5'
|
||||
|
||||
- name: Pre build
|
||||
working-directory: frontend
|
||||
run: |
|
||||
sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y build-essential libsqlite3-dev libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev
|
||||
sudo apt-get install keybinder-3.0
|
||||
source $HOME/.cargo/env
|
||||
cargo install --force cargo-make
|
||||
cargo install --force duckscript_cli
|
||||
cargo make appflowy-deps-tools
|
||||
|
||||
- name: Build Linux app
|
||||
working-directory: frontend
|
||||
run: |
|
||||
flutter config --enable-linux-desktop
|
||||
cargo make --env APP_VERSION=${{ github.ref_name }} --profile production-linux-x86_64 appflowy
|
||||
|
||||
- name: Configuring Linux Package
|
||||
working-directory: frontend
|
||||
run: |
|
||||
mkdir -p ../${{ env.LINUX_APP_RELEASE_PATH }}/package/opt
|
||||
mkdir -p ../${{ env.LINUX_APP_RELEASE_PATH }}/package/usr/share/applications
|
||||
cp -r ./scripts/linux_installer ../${{ env.LINUX_APP_RELEASE_PATH }}/package/DEBIAN
|
||||
cd ../${{ env.LINUX_APP_RELEASE_PATH }}/package/DEBIAN
|
||||
grep -rl "\[CHANGE_THIS\]" ./control | xargs sed -i "s/\[CHANGE_THIS\]/${{ github.ref_name }}/"
|
||||
chmod 0755 {postinst,postrm}
|
||||
|
||||
- name: Build Linux package
|
||||
working-directory: ${{ env.LINUX_APP_RELEASE_PATH }}
|
||||
run: |
|
||||
mv AppFlowy package/opt/
|
||||
cd package
|
||||
|
||||
# Update Exec & icon path in desktop entry
|
||||
grep -rl "\[CHANGE_THIS\]" ./opt/AppFlowy/appflowy.desktop.temp | xargs sed -i "s/\[CHANGE_THIS\]/\/opt/"
|
||||
# Add desktop entry in package
|
||||
mv ./opt/AppFlowy/appflowy.desktop.temp ./usr/share/applications/appflowy.desktop
|
||||
|
||||
# Build
|
||||
cd ../ && dpkg-deb --build --root-owner-group -Z xz package ${{ env.LINUX_PACKAGE_NAME }}
|
||||
|
||||
- name: Upload Alternative Release Asset Install Package
|
||||
id: upload-release-asset-install-package
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||
asset_path: ${{ env.LINUX_APP_RELEASE_PATH }}/${{ env.LINUX_PACKAGE_NAME }}
|
||||
asset_name: ${{ env.LINUX_PACKAGE_NAME }}
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
build-macos-x86_64:
|
||||
runs-on: macos-latest
|
||||
needs: create-release
|
||||
env:
|
||||
MACOS_APP_RELEASE_PATH: frontend/app_flowy/product/${{ github.ref_name }}/macos/Release
|
||||
MACOS_X86_ZIP_NAME: Appflowy-macos-x86_64.zip
|
||||
MACOS_DMG_NAME: Appflowy-macos-x86_64-installer
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup environment - Rust and Cargo
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: 'stable-2022-04-07'
|
||||
|
||||
- name: Setup environment - Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version: '3.0.5'
|
||||
|
||||
- name: Pre build
|
||||
working-directory: frontend
|
||||
run: |
|
||||
source $HOME/.cargo/env
|
||||
cargo install --force cargo-make
|
||||
cargo install --force duckscript_cli
|
||||
cargo make appflowy-deps-tools
|
||||
|
||||
- name: Build macOS app for x86_64
|
||||
working-directory: frontend
|
||||
run: |
|
||||
flutter config --enable-macos-desktop
|
||||
cargo make --env APP_VERSION=${{ github.ref_name }} --profile production-mac-x86_64 appflowy
|
||||
|
||||
- name: Create MacOS dmg
|
||||
run: |
|
||||
brew install create-dmg
|
||||
create-dmg \
|
||||
--volname ${{ env.MACOS_DMG_NAME }} \
|
||||
--hide-extension "AppFlowy.app" \
|
||||
--background frontend/scripts/dmg_assets/AppFlowyInstallerBackground.jpg \
|
||||
--window-size 600 450 \
|
||||
--icon-size 94 \
|
||||
--icon "AppFlowy.app" 141 249 \
|
||||
--app-drop-link 458 249 \
|
||||
"${{ env.MACOS_APP_RELEASE_PATH }}/${{ env.MACOS_DMG_NAME }}.dmg" \
|
||||
"${{ env.MACOS_APP_RELEASE_PATH }}/AppFlowy.app"
|
||||
|
||||
- name: Archive macOS app
|
||||
working-directory: ${{ env.MACOS_APP_RELEASE_PATH }}
|
||||
run: zip --symlinks -qr ${{ env.MACOS_X86_ZIP_NAME }} AppFlowy.app
|
||||
|
||||
- name: Upload Release Asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||
asset_path: ${{ env.MACOS_APP_RELEASE_PATH }}/${{ env.MACOS_X86_ZIP_NAME }}
|
||||
asset_name: ${{ env.MACOS_X86_ZIP_NAME }}
|
||||
asset_content_type: application/octet-stream
|
||||
- name: Upload DMG Release Asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||
asset_path: ${{ env.MACOS_APP_RELEASE_PATH }}/${{ env.MACOS_DMG_NAME }}.dmg
|
||||
asset_name: ${{ env.MACOS_DMG_NAME }}.dmg
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
build-windows-x86_64:
|
||||
runs-on: windows-latest
|
||||
build-for-windows:
|
||||
name: ${{ matrix.job.target }} (${{ matrix.job.os }})
|
||||
needs: create-release
|
||||
env:
|
||||
WINDOWS_APP_RELEASE_PATH: frontend\app_flowy\product\${{ github.ref_name }}\windows
|
||||
WINDOWS_ZIP_NAME: AppFlowy-windows-x86_64.zip
|
||||
WINDOWS_INSTALLER_NAME: AppFlowy-${{ github.ref_name }}-windows-x86_64
|
||||
WINDOWS_ZIP_NAME: AppFlowy_${{ github.ref_name }}_windows-x86_64.zip
|
||||
WINDOWS_INSTALLER_NAME: AppFlowy_${{ github.ref_name }}_windows-x86_64
|
||||
runs-on: ${{ matrix.job.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
job:
|
||||
- { target: x86_64-pc-windows-msvc, os: windows-2019 }
|
||||
steps:
|
||||
- name: Checkout
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup environment - Rust and Cargo
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: 'stable-2022-04-07'
|
||||
|
||||
- name: Setup environment - Flutter
|
||||
- name: Install flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version: '3.0.5'
|
||||
channel: "stable"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
- name: Pre build
|
||||
- name: Install Rust toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
target: ${{ matrix.job.target }}
|
||||
override: true
|
||||
components: rustfmt
|
||||
profile: minimal
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: ${{ matrix.job.os }}
|
||||
|
||||
- name: Install prerequisites
|
||||
working-directory: frontend
|
||||
run: |
|
||||
vcpkg integrate install
|
||||
cargo install --force cargo-make
|
||||
cargo install --force duckscript_cli
|
||||
cargo make appflowy-deps-tools
|
||||
|
||||
- name: Build Windows app
|
||||
working-directory: frontend
|
||||
|
@ -300,11 +84,12 @@ jobs:
|
|||
flutter config --enable-windows-desktop
|
||||
cargo make --env APP_VERSION=${{ github.ref_name }} --profile production-windows-x86 appflowy
|
||||
|
||||
- uses: vimtor/action-zip@v1
|
||||
- name: Archive Asset
|
||||
uses: vimtor/action-zip@v1
|
||||
with:
|
||||
files: ${{ env.WINDOWS_APP_RELEASE_PATH }}\
|
||||
dest: ${{ env.WINDOWS_APP_RELEASE_PATH }}\${{ env.WINDOWS_ZIP_NAME }}
|
||||
|
||||
|
||||
- name: Copy installer config & icon file
|
||||
working-directory: frontend
|
||||
run: |
|
||||
|
@ -315,7 +100,7 @@ jobs:
|
|||
run: |
|
||||
iscc /F${{ env.WINDOWS_INSTALLER_NAME }} inno_setup_config.iss /DAppVersion=${{ github.ref_name }}
|
||||
|
||||
- name: Upload Release Asset
|
||||
- name: Upload Asset
|
||||
id: upload-release-asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
|
@ -336,3 +121,221 @@ jobs:
|
|||
asset_path: ${{ env.WINDOWS_APP_RELEASE_PATH }}\Output\${{ env.WINDOWS_INSTALLER_NAME }}.exe
|
||||
asset_name: ${{ env.WINDOWS_INSTALLER_NAME }}.exe
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
build-for-macOS:
|
||||
name: ${{ matrix.job.target }} (${{ matrix.job.os }}) [${{ matrix.job.extra-build-args }}]
|
||||
runs-on: ${{ matrix.job.os }}
|
||||
needs: create-release
|
||||
env:
|
||||
MACOS_APP_RELEASE_PATH: frontend/app_flowy/product/${{ github.ref_name }}/macos/Release
|
||||
MACOS_X86_ZIP_NAME: AppFlowy_${{ github.ref_name }}_macos-x86_64.zip
|
||||
MACOS_DMG_NAME: AppFlowy_${{ github.ref_name }}_macos-x86_64
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
job:
|
||||
- { target: x86_64-apple-darwin, os: macos-10.15, extra-build-args: "" }
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
target: ${{ matrix.job.target }}
|
||||
override: true
|
||||
components: rustfmt
|
||||
profile: minimal
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: ${{ matrix.job.os }}
|
||||
|
||||
- name: Install prerequisites
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo install --force cargo-make
|
||||
cargo install --force duckscript_cli
|
||||
|
||||
- name: Build AppFlowy
|
||||
working-directory: frontend
|
||||
run: |
|
||||
flutter config --enable-macos-desktop
|
||||
cargo make --env APP_VERSION=${{ github.ref_name }} --profile production-mac-x86_64 appflowy
|
||||
|
||||
- name: Create macOS dmg
|
||||
run: |
|
||||
brew install create-dmg
|
||||
create-dmg \
|
||||
--volname ${{ env.MACOS_DMG_NAME }} \
|
||||
--hide-extension "AppFlowy.app" \
|
||||
--background frontend/scripts/dmg_assets/AppFlowyInstallerBackground.jpg \
|
||||
--window-size 600 450 \
|
||||
--icon-size 94 \
|
||||
--icon "AppFlowy.app" 141 249 \
|
||||
--app-drop-link 458 249 \
|
||||
"${{ env.MACOS_APP_RELEASE_PATH }}/${{ env.MACOS_DMG_NAME }}.dmg" \
|
||||
"${{ env.MACOS_APP_RELEASE_PATH }}/AppFlowy.app"
|
||||
|
||||
- name: Archive Asset
|
||||
working-directory: ${{ env.MACOS_APP_RELEASE_PATH }}
|
||||
run: zip --symlinks -qr ${{ env.MACOS_X86_ZIP_NAME }} AppFlowy.app
|
||||
|
||||
- name: Upload Asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||
asset_path: ${{ env.MACOS_APP_RELEASE_PATH }}/${{ env.MACOS_X86_ZIP_NAME }}
|
||||
asset_name: ${{ env.MACOS_X86_ZIP_NAME }}
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
- name: Upload DMG Asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||
asset_path: ${{ env.MACOS_APP_RELEASE_PATH }}/${{ env.MACOS_DMG_NAME }}.dmg
|
||||
asset_name: ${{ env.MACOS_DMG_NAME }}.dmg
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
build-for-linux:
|
||||
name: ${{ matrix.job.target }} (${{ matrix.job.os }}) [${{ matrix.job.extra-build-args }}]
|
||||
runs-on: ${{ matrix.job.os }}
|
||||
needs: create-release
|
||||
env:
|
||||
LINUX_APP_RELEASE_PATH: frontend/app_flowy/product/${{ github.ref_name }}/linux/Release
|
||||
LINUX_ZIP_NAME: AppFlowy_${{ matrix.job.target }}_${{ matrix.job.os }}.tar.gz
|
||||
LINUX_PACKAGE_NAME: AppFlowy_${{ github.ref_name }}_${{ matrix.job.os }}.deb
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
job:
|
||||
- { arch: x86_64, target: x86_64-unknown-linux-gnu, os: ubuntu-20.04, extra-build-args: "", }
|
||||
- { arch: x86_64, target: x86_64-unknown-linux-gnu, os: ubuntu-18.04, extra-build-args: "", }
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
target: ${{ matrix.job.target }}
|
||||
override: true
|
||||
components: rustfmt
|
||||
profile: minimal
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: ${{ matrix.job.os }}
|
||||
|
||||
- name: Install prerequisites
|
||||
working-directory: frontend
|
||||
run: |
|
||||
sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y build-essential libsqlite3-dev libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev
|
||||
sudo apt-get install keybinder-3.0
|
||||
source $HOME/.cargo/env
|
||||
cargo install --force cargo-make
|
||||
cargo install --force duckscript_cli
|
||||
|
||||
- name: Build AppFlowy
|
||||
working-directory: frontend
|
||||
run: |
|
||||
flutter config --enable-linux-desktop
|
||||
cargo make --env APP_VERSION=${{ github.ref_name }} --profile production-linux-x86_64 appflowy
|
||||
|
||||
- name: Archive Assert
|
||||
working-directory: ${{ env.LINUX_APP_RELEASE_PATH }}
|
||||
run: tar -czf ${{ env.LINUX_ZIP_NAME }} *
|
||||
|
||||
- name: Configuring Linux Package
|
||||
working-directory: frontend
|
||||
run: |
|
||||
mkdir -p ../${{ env.LINUX_APP_RELEASE_PATH }}/package/opt
|
||||
mkdir -p ../${{ env.LINUX_APP_RELEASE_PATH }}/package/usr/share/applications
|
||||
cp -r ./scripts/linux_installer ../${{ env.LINUX_APP_RELEASE_PATH }}/package/DEBIAN
|
||||
cd ../${{ env.LINUX_APP_RELEASE_PATH }}/package/DEBIAN
|
||||
grep -rl "\[CHANGE_THIS\]" ./control | xargs sed -i "s/\[CHANGE_THIS\]/${{ github.ref_name }}/"
|
||||
chmod 0755 {postinst,postrm}
|
||||
|
||||
- name: Build Linux package
|
||||
working-directory: ${{ env.LINUX_APP_RELEASE_PATH }}
|
||||
run: |
|
||||
mv AppFlowy package/opt/
|
||||
cd package
|
||||
|
||||
# Update Exec & icon path in desktop entry
|
||||
grep -rl "\[CHANGE_THIS\]" ./opt/AppFlowy/appflowy.desktop.temp | xargs sed -i "s/\[CHANGE_THIS\]/\/opt/"
|
||||
# Add desktop entry in package
|
||||
mv ./opt/AppFlowy/appflowy.desktop.temp ./usr/share/applications/appflowy.desktop
|
||||
|
||||
# Build
|
||||
cd ../ && dpkg-deb --build --root-owner-group -Z xz package ${{ env.LINUX_PACKAGE_NAME }}
|
||||
|
||||
- name: Upload Asset
|
||||
id: upload-release-asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||
asset_path: ${{ env.LINUX_APP_RELEASE_PATH }}/${{ env.LINUX_ZIP_NAME }}
|
||||
asset_name: ${{ env.LINUX_ZIP_NAME }}
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
- name: Upload Asset Install Package
|
||||
id: upload-release-asset-install-package
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||
asset_path: ${{ env.LINUX_APP_RELEASE_PATH }}/${{ env.LINUX_PACKAGE_NAME }}
|
||||
asset_name: ${{ env.LINUX_PACKAGE_NAME }}
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
build-for-docker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./frontend/scripts/docker-buildfiles/Dockerfile
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
push: true
|
||||
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/appflowy_client:${{ github.ref_name }}
|
||||
cache-from: type=registry,ref=${{ secrets.DOCKER_HUB_USERNAME }}/af_build_cache:buildcache
|
||||
cache-to: type=registry,ref=${{ secrets.DOCKER_HUB_USERNAME }}/af_build_cache:buildcache,mode=max
|
||||
|
|
35
.github/workflows/release_docker.yml
vendored
35
.github/workflows/release_docker.yml
vendored
|
@ -1,35 +0,0 @@
|
|||
name: release_docker
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
build-docker-image:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./frontend/scripts/docker-buildfiles/Dockerfile
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
push: true
|
||||
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/appflowy_client:${{ github.ref_name }}
|
||||
cache-from: type=registry,ref=${{ secrets.DOCKER_HUB_USERNAME }}/af_build_cache:buildcache
|
||||
cache-to: type=registry,ref=${{ secrets.DOCKER_HUB_USERNAME }}/af_build_cache:buildcache,mode=max
|
86
.github/workflows/rust_ci.yaml
vendored
Normal file
86
.github/workflows/rust_ci.yaml
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
name: Rust-CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
- "release/*"
|
||||
paths:
|
||||
- "frontend/rust-lib/**"
|
||||
- "shared-lib/**"
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- "main"
|
||||
- "release/*"
|
||||
paths:
|
||||
- "frontend/rust-lib/**"
|
||||
- "shared-lib/**"
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
RUST_TOOLCHAIN: "1.65"
|
||||
FLUTTER_VERSION: "3.3.9"
|
||||
|
||||
jobs:
|
||||
test-on-ubuntu:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
profile: minimal
|
||||
|
||||
- name: Install flutter
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
- name: Install prerequisites
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo install --force cargo-make
|
||||
cargo install --force duckscript_cli
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: ${{ matrix.job.os }}
|
||||
|
||||
- name: Build FlowySDK
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo make --profile development-linux-x86_64 appflowy-sdk-dev
|
||||
|
||||
- name: rustfmt rust-lib
|
||||
run: cargo fmt --all -- --check
|
||||
working-directory: frontend/rust-lib/
|
||||
|
||||
- name: clippy rust-lib
|
||||
run: cargo clippy --features="rev-sqlite"
|
||||
working-directory: frontend/rust-lib
|
||||
|
||||
- name: Run rust-lib tests
|
||||
working-directory: frontend/rust-lib
|
||||
run: RUST_LOG=info cargo test --no-default-features --features="sync,rev-sqlite"
|
||||
|
||||
- name: rustfmt shared-lib
|
||||
run: cargo fmt --all -- --check
|
||||
working-directory: shared-lib
|
||||
|
||||
- name: clippy shared-lib
|
||||
run: cargo clippy -- -D warnings
|
||||
working-directory: shared-lib
|
||||
|
||||
- name: Run shared-lib tests
|
||||
working-directory: shared-lib
|
||||
run: RUST_LOG=info cargo test --no-default-features
|
52
.github/workflows/rust_coverage.yml
vendored
52
.github/workflows/rust_coverage.yml
vendored
|
@ -11,52 +11,48 @@ on:
|
|||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
FLUTTER_VERSION: "3.3.9"
|
||||
RUST_TOOLCHAIN: "1.65"
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- id: rust_toolchain
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: 'stable-2022-04-07'
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
target: ${{ matrix.job.target }}
|
||||
override: true
|
||||
profile: minimal
|
||||
|
||||
- name: Cache Cargo
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.cargo
|
||||
key: ${{ runner.os }}-cargo-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}
|
||||
|
||||
- name: Cache Rust
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
frontend/rust-lib/target
|
||||
shared-lib/target
|
||||
key: ${{ runner.os }}-rust-rust-lib-share-lib-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}
|
||||
|
||||
|
||||
- name: Install cargo-make
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo install cargo-make
|
||||
|
||||
- name: Setup environment - Flutter
|
||||
- name: Install flutter
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version: '3.0.5'
|
||||
channel: "stable"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
- name: Install prerequisites
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo install --force cargo-make
|
||||
cargo install --force duckscript_cli
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: ${{ matrix.job.os }}
|
||||
|
||||
- name: Install code-coverage tools
|
||||
working-directory: frontend
|
||||
run: |
|
||||
sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y build-essential libsqlite3-dev libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev
|
||||
sudo apt-get install keybinder-3.0
|
||||
cargo install grcov
|
||||
rustup component add llvm-tools-preview
|
||||
|
|
61
.github/workflows/rust_lint.yml
vendored
61
.github/workflows/rust_lint.yml
vendored
|
@ -1,61 +0,0 @@
|
|||
name: Rust lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
- "release/*"
|
||||
paths:
|
||||
- "frontend/rust-lib/**"
|
||||
- "shared-lib/**"
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- "main"
|
||||
- "release/*"
|
||||
paths:
|
||||
- "frontend/rust-lib/**"
|
||||
- "shared-lib/**"
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
rust-fmt:
|
||||
name: Rustfmt
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: 'stable-2022-04-07'
|
||||
override: true
|
||||
- uses: subosito/flutter-action@v1
|
||||
with:
|
||||
flutter-version: '3.0.5'
|
||||
channel: "stable"
|
||||
|
||||
- name: Rust Deps
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo install cargo-make
|
||||
cargo make appflowy-deps-tools
|
||||
|
||||
- name: Build FlowySDK
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo make --profile development-linux-x86_64 appflowy-sdk-dev
|
||||
|
||||
- run: rustup component add rustfmt
|
||||
working-directory: frontend/rust-lib
|
||||
- name: rustfmt
|
||||
run: cargo fmt --all -- --check
|
||||
working-directory: frontend/rust-lib/
|
||||
|
||||
|
||||
- run: rustup component add clippy
|
||||
working-directory: frontend/rust-lib
|
||||
- name: clippy
|
||||
run: cargo clippy --no-default-features
|
||||
working-directory: frontend/rust-lib
|
||||
|
60
.github/workflows/rust_test.yml
vendored
60
.github/workflows/rust_test.yml
vendored
|
@ -1,60 +0,0 @@
|
|||
name: Backend test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
- "release/*"
|
||||
paths:
|
||||
- "frontend/rust-lib/**"
|
||||
- "shared-lib/**"
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- "main"
|
||||
- "release/*"
|
||||
paths:
|
||||
- "frontend/rust-lib/**"
|
||||
- "shared-lib/**"
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- id: rust_toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: 'stable-2022-04-07'
|
||||
|
||||
- name: Cache Cargo
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.cargo
|
||||
key: ${{ runner.os }}-cargo-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}
|
||||
|
||||
- name: Cache Rust
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
frontend/rust-lib/target
|
||||
shared-lib/target
|
||||
key: ${{ runner.os }}-rust-rust-lib-share-lib-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}
|
||||
|
||||
- name: Install cargo-make
|
||||
working-directory: frontend
|
||||
run: cargo install cargo-make
|
||||
|
||||
- name: Run rust-lib tests
|
||||
working-directory: frontend/rust-lib
|
||||
run: RUST_LOG=info cargo test --no-default-features --features="sync"
|
||||
|
||||
- name: Run shared-lib tests
|
||||
working-directory: shared-lib
|
||||
run: RUST_LOG=info cargo test --no-default-features
|
|
@ -1,13 +1,13 @@
|
|||
#https://github.com/sagiegurari/cargo-make
|
||||
|
||||
extend = [
|
||||
{ path = "scripts/makefile/desktop.toml" },
|
||||
{ path = "scripts/makefile/protobuf.toml" },
|
||||
{ path = "scripts/makefile/tests.toml" },
|
||||
{ path = "scripts/makefile/docker.toml" },
|
||||
{ path = "scripts/makefile/env.toml" },
|
||||
{ path = "scripts/makefile/flutter.toml" },
|
||||
{ path = "scripts/makefile/tool.toml" },
|
||||
{ path = "scripts/makefile/desktop.toml" },
|
||||
{ path = "scripts/makefile/protobuf.toml" },
|
||||
{ path = "scripts/makefile/tests.toml" },
|
||||
{ path = "scripts/makefile/docker.toml" },
|
||||
{ path = "scripts/makefile/env.toml" },
|
||||
{ path = "scripts/makefile/flutter.toml" },
|
||||
{ path = "scripts/makefile/tool.toml" },
|
||||
]
|
||||
|
||||
[config]
|
||||
|
@ -23,11 +23,11 @@ CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
|
|||
CARGO_MAKE_CRATE_NAME = "dart-ffi"
|
||||
LIB_NAME = "dart_ffi"
|
||||
CURRENT_APP_VERSION = "0.0.9.1"
|
||||
FEATURES = "flutter"
|
||||
FLUTTER_DESKTOP_FEATURES = "flutter,rev-sqlite"
|
||||
PRODUCT_NAME = "AppFlowy"
|
||||
# CRATE_TYPE: https://doc.rust-lang.org/reference/linkage.html
|
||||
# If you update the macOS's CRATE_TYPE, don't forget to update the
|
||||
# flowy_sdk.podspec
|
||||
# appflowy_backend.podspec
|
||||
# for staticlib:
|
||||
# s.static_framework = true
|
||||
# s.vendored_libraries = "libdart_ffi.a"
|
||||
|
@ -42,7 +42,7 @@ PRODUCT_NAME = "AppFlowy"
|
|||
CRATE_TYPE = "staticlib"
|
||||
LIB_EXT = "a"
|
||||
APP_ENVIRONMENT = "local"
|
||||
FLUTTER_FLOWY_SDK_PATH = "app_flowy/packages/flowy_sdk"
|
||||
FLUTTER_FLOWY_SDK_PATH = "app_flowy/packages/appflowy_backend"
|
||||
# Test default config
|
||||
TEST_CRATE_TYPE = "cdylib"
|
||||
TEST_LIB_EXT = "dylib"
|
||||
|
@ -150,7 +150,7 @@ script = ['''
|
|||
echo BUILD_FLAG: ${BUILD_FLAG}
|
||||
echo TARGET_OS: ${TARGET_OS}
|
||||
echo RUST_COMPILE_TARGET: ${RUST_COMPILE_TARGET}
|
||||
echo FEATURES: ${FEATURES}
|
||||
echo FEATURES: ${FLUTTER_DESKTOP_FEATURES}
|
||||
echo PRODUCT_EXT: ${PRODUCT_EXT}
|
||||
echo APP_ENVIRONMENT: ${APP_ENVIRONMENT}
|
||||
echo ${platforms}
|
||||
|
@ -181,7 +181,7 @@ FEATURES = "flutter,openssl_vendored"
|
|||
[tasks.setup-crate-type]
|
||||
private = true
|
||||
script = [
|
||||
"""
|
||||
"""
|
||||
toml = readfile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml
|
||||
val = replace ${toml} "staticlib" ${CRATE_TYPE}
|
||||
result = writefile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml ${val}
|
||||
|
@ -193,7 +193,7 @@ script_runner = "@duckscript"
|
|||
[tasks.restore-crate-type]
|
||||
private = true
|
||||
script = [
|
||||
"""
|
||||
"""
|
||||
toml = readfile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml
|
||||
val = replace ${toml} ${CRATE_TYPE} "staticlib"
|
||||
result = writefile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml ${val}
|
||||
|
@ -221,7 +221,7 @@ TEST_COMPILE_TARGET = "x86_64-pc-windows-msvc"
|
|||
[tasks.setup-test-crate-type]
|
||||
private = true
|
||||
script = [
|
||||
"""
|
||||
"""
|
||||
toml = readfile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml
|
||||
val = replace ${toml} "staticlib" ${TEST_CRATE_TYPE}
|
||||
result = writefile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml ${val}
|
||||
|
@ -233,7 +233,7 @@ script_runner = "@duckscript"
|
|||
[tasks.restore-test-crate-type]
|
||||
private = true
|
||||
script = [
|
||||
"""
|
||||
"""
|
||||
toml = readfile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml
|
||||
val = replace ${toml} ${TEST_CRATE_TYPE} "staticlib"
|
||||
result = writefile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml ${val}
|
||||
|
@ -249,5 +249,3 @@ script = ["""
|
|||
cargo build -vv --features=dart
|
||||
"""]
|
||||
script_runner = "@shell"
|
||||
|
||||
|
||||
|
|
|
@ -193,6 +193,7 @@
|
|||
"grid": {
|
||||
"settings": {
|
||||
"filter": "Filter",
|
||||
"sort": "Sort",
|
||||
"sortBy": "Sort by",
|
||||
"Properties": "Properties",
|
||||
"group": "Group",
|
||||
|
@ -273,6 +274,12 @@
|
|||
"newColumn": "New column",
|
||||
"deleteFieldPromptMessage": "Are you sure? This property will be deleted"
|
||||
},
|
||||
"sort": {
|
||||
"ascending": "Ascending",
|
||||
"descending": "Descending",
|
||||
"deleteSort": "Delete sort",
|
||||
"addSort": "Add sort"
|
||||
},
|
||||
"row": {
|
||||
"duplicate": "Duplicate",
|
||||
"delete": "Delete",
|
||||
|
@ -313,5 +320,8 @@
|
|||
"column": {
|
||||
"create_new_card": "New"
|
||||
}
|
||||
},
|
||||
"calendar": {
|
||||
"menuName": "Calendar"
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ PODS:
|
|||
- Flutter
|
||||
- flowy_infra_ui (0.0.1):
|
||||
- Flutter
|
||||
- flowy_sdk (0.0.1):
|
||||
- appflowy_backend (0.0.1):
|
||||
- Flutter
|
||||
- Flutter (1.0.0)
|
||||
- flutter_inappwebview (0.0.1):
|
||||
|
@ -28,7 +28,7 @@ PODS:
|
|||
DEPENDENCIES:
|
||||
- flowy_editor (from `.symlinks/plugins/flowy_editor/ios`)
|
||||
- flowy_infra_ui (from `.symlinks/plugins/flowy_infra_ui/ios`)
|
||||
- flowy_sdk (from `.symlinks/plugins/flowy_sdk/ios`)
|
||||
- appflowy_backend (from `.symlinks/plugins/appflowy_backend/ios`)
|
||||
- Flutter (from `Flutter`)
|
||||
- flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`)
|
||||
- flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`)
|
||||
|
@ -46,8 +46,8 @@ EXTERNAL SOURCES:
|
|||
:path: ".symlinks/plugins/flowy_editor/ios"
|
||||
flowy_infra_ui:
|
||||
:path: ".symlinks/plugins/flowy_infra_ui/ios"
|
||||
flowy_sdk:
|
||||
:path: ".symlinks/plugins/flowy_sdk/ios"
|
||||
appflowy_backend:
|
||||
:path: ".symlinks/plugins/appflowy_backend/ios"
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
flutter_inappwebview:
|
||||
|
@ -66,7 +66,7 @@ EXTERNAL SOURCES:
|
|||
SPEC CHECKSUMS:
|
||||
flowy_editor: bf8d58894ddb03453bd4d8521c57267ad638b837
|
||||
flowy_infra_ui: 146c88346fd55d2ee6a41ae35059a5bf095cfbb3
|
||||
flowy_sdk: c416222c639e678828776789bf0c1a1d0d59df3c
|
||||
appflowy_backend: c416222c639e678828776789bf0c1a1d0d59df3c
|
||||
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
|
||||
flutter_inappwebview: bfd58618f49dc62f2676de690fc6dcda1d6c3721
|
||||
flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
import 'package:flowy_sdk/protobuf/dart-notify/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/dart-notify/protobuf.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
|
||||
import 'package:flowy_sdk/rust_stream.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/dart_notification.pb.dart';
|
||||
import 'package:appflowy_backend/rust_stream.dart';
|
||||
|
||||
import 'notification_helper.dart';
|
||||
|
||||
// Folder
|
||||
typedef FolderNotificationCallback = void Function(FolderNotification, Either<Uint8List, FlowyError>);
|
||||
typedef FolderNotificationCallback = void Function(
|
||||
FolderNotification, Either<Uint8List, FlowyError>);
|
||||
|
||||
class FolderNotificationParser extends NotificationParser<FolderNotification, FlowyError> {
|
||||
FolderNotificationParser({String? id, required FolderNotificationCallback callback})
|
||||
class FolderNotificationParser
|
||||
extends NotificationParser<FolderNotification, FlowyError> {
|
||||
FolderNotificationParser(
|
||||
{String? id, required FolderNotificationCallback callback})
|
||||
: super(
|
||||
id: id,
|
||||
callback: callback,
|
||||
|
@ -21,15 +24,18 @@ class FolderNotificationParser extends NotificationParser<FolderNotification, Fl
|
|||
);
|
||||
}
|
||||
|
||||
typedef FolderNotificationHandler = Function(FolderNotification ty, Either<Uint8List, FlowyError> result);
|
||||
typedef FolderNotificationHandler = Function(
|
||||
FolderNotification ty, Either<Uint8List, FlowyError> result);
|
||||
|
||||
class FolderNotificationListener {
|
||||
StreamSubscription<SubscribeObject>? _subscription;
|
||||
FolderNotificationParser? _parser;
|
||||
|
||||
FolderNotificationListener({required String objectId, required FolderNotificationHandler handler})
|
||||
FolderNotificationListener(
|
||||
{required String objectId, required FolderNotificationHandler handler})
|
||||
: _parser = FolderNotificationParser(id: objectId, callback: handler) {
|
||||
_subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable));
|
||||
_subscription =
|
||||
RustStreamReceiver.listen((observable) => _parser?.parse(observable));
|
||||
}
|
||||
|
||||
Future<void> stop() async {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
import 'package:flowy_sdk/protobuf/dart-notify/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/dart-notify/protobuf.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||
import 'package:flowy_sdk/rust_stream.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||
import 'package:appflowy_backend/rust_stream.dart';
|
||||
|
||||
import 'notification_helper.dart';
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-net/network_state.pb.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-net/network_state.pb.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class NetworkListener {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'dart:typed_data';
|
||||
import 'package:flowy_sdk/protobuf/dart-notify/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/dart-notify/protobuf.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
||||
class NotificationParser<T, E> {
|
||||
|
@ -9,7 +9,11 @@ class NotificationParser<T, E> {
|
|||
T? Function(int) tyParser;
|
||||
E Function(Uint8List) errorParser;
|
||||
|
||||
NotificationParser({this.id, required this.callback, required this.errorParser, required this.tyParser});
|
||||
NotificationParser(
|
||||
{this.id,
|
||||
required this.callback,
|
||||
required this.errorParser,
|
||||
required this.tyParser});
|
||||
void parse(SubscribeObject subject) {
|
||||
if (id != null) {
|
||||
if (subject.id != id) {
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
import 'package:flowy_sdk/protobuf/dart-notify/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/dart-notify/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/rust_stream.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/rust_stream.dart';
|
||||
|
||||
import 'notification_helper.dart';
|
||||
|
||||
// User
|
||||
typedef UserNotificationCallback = void Function(UserNotification, Either<Uint8List, FlowyError>);
|
||||
typedef UserNotificationCallback = void Function(
|
||||
UserNotification, Either<Uint8List, FlowyError>);
|
||||
|
||||
class UserNotificationParser extends NotificationParser<UserNotification, FlowyError> {
|
||||
UserNotificationParser({required String id, required UserNotificationCallback callback})
|
||||
class UserNotificationParser
|
||||
extends NotificationParser<UserNotification, FlowyError> {
|
||||
UserNotificationParser(
|
||||
{required String id, required UserNotificationCallback callback})
|
||||
: super(
|
||||
id: id,
|
||||
callback: callback,
|
||||
|
@ -21,15 +24,18 @@ class UserNotificationParser extends NotificationParser<UserNotification, FlowyE
|
|||
);
|
||||
}
|
||||
|
||||
typedef UserNotificationHandler = Function(UserNotification ty, Either<Uint8List, FlowyError> result);
|
||||
typedef UserNotificationHandler = Function(
|
||||
UserNotification ty, Either<Uint8List, FlowyError> result);
|
||||
|
||||
class UserNotificationListener {
|
||||
StreamSubscription<SubscribeObject>? _subscription;
|
||||
UserNotificationParser? _parser;
|
||||
|
||||
UserNotificationListener({required String objectId, required UserNotificationHandler handler})
|
||||
UserNotificationListener(
|
||||
{required String objectId, required UserNotificationHandler handler})
|
||||
: _parser = UserNotificationParser(id: objectId, callback: handler) {
|
||||
_subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable));
|
||||
_subscription =
|
||||
RustStreamReceiver.listen((observable) => _parser?.parse(observable));
|
||||
}
|
||||
|
||||
Future<void> stop() async {
|
||||
|
|
|
@ -7,10 +7,10 @@ import 'package:app_flowy/plugins/grid/application/row/row_service.dart';
|
|||
import 'package:appflowy_board/appflowy_board.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/protobuf.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
|
|
|
@ -4,11 +4,11 @@ import 'package:app_flowy/plugins/grid/application/view/grid_view_cache.dart';
|
|||
import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/grid_service.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/row/row_cache.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'dart:async';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/protobuf.dart';
|
||||
|
||||
import 'board_listener.dart';
|
||||
|
||||
|
@ -108,19 +108,19 @@ class BoardDataController {
|
|||
|
||||
Future<Either<Unit, FlowyError>> openGrid() async {
|
||||
final result = await _gridFFIService.openGrid();
|
||||
|
||||
return result.fold(
|
||||
(grid) async {
|
||||
_onGridChanged?.call(grid);
|
||||
final result = await fieldController.loadFields(fieldIds: grid.fields);
|
||||
return result.fold(
|
||||
(l) {
|
||||
_loadGroups();
|
||||
_viewCache.rowCache.initializeRows(grid.rows);
|
||||
return left(l);
|
||||
},
|
||||
(err) => right(err),
|
||||
);
|
||||
return fieldController.loadFields(fieldIds: grid.fields).then((result) {
|
||||
return result.fold(
|
||||
(l) => Future(() async {
|
||||
await _loadGroups();
|
||||
_viewCache.rowCache.initializeRows(grid.rows);
|
||||
return left(l);
|
||||
}),
|
||||
(err) => right(err),
|
||||
);
|
||||
});
|
||||
},
|
||||
(err) => right(err),
|
||||
);
|
||||
|
@ -132,6 +132,7 @@ class BoardDataController {
|
|||
}
|
||||
|
||||
Future<void> dispose() async {
|
||||
await _viewCache.dispose();
|
||||
await _gridFFIService.closeGrid();
|
||||
await fieldController.dispose();
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@ import 'dart:typed_data';
|
|||
|
||||
import 'package:app_flowy/core/grid_notification.dart';
|
||||
import 'package:flowy_infra/notifier.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/group.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/group_changeset.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/group.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/group_changeset.pb.dart';
|
||||
|
||||
typedef GroupUpdateValue = Either<GroupViewChangesetPB, FlowyError>;
|
||||
typedef GroupByNewFieldValue = Either<List<GroupPB>, FlowyError>;
|
||||
|
|
|
@ -64,7 +64,7 @@ class BoardCheckboxCellState with _$BoardCheckboxCellState {
|
|||
required bool isSelected,
|
||||
}) = _CheckboxCellState;
|
||||
|
||||
factory BoardCheckboxCellState.initial(GridCellController context) {
|
||||
factory BoardCheckboxCellState.initial(GridTextCellController context) {
|
||||
return BoardCheckboxCellState(
|
||||
isSelected: _isSelected(context.getCellData()));
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/date_type_option_entities.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -60,7 +60,7 @@ class BoardNumberCellState with _$BoardNumberCellState {
|
|||
required String content,
|
||||
}) = _BoardNumberCellState;
|
||||
|
||||
factory BoardNumberCellState.initial(GridCellController context) =>
|
||||
factory BoardNumberCellState.initial(GridTextCellController context) =>
|
||||
BoardNumberCellState(
|
||||
content: context.getCellData() ?? "",
|
||||
);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'dart:async';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||
|
|
|
@ -6,7 +6,7 @@ import 'dart:async';
|
|||
part 'board_text_cell_bloc.freezed.dart';
|
||||
|
||||
class BoardTextCellBloc extends Bloc<BoardTextCellEvent, BoardTextCellState> {
|
||||
final GridCellController cellController;
|
||||
final GridTextCellController cellController;
|
||||
void Function()? _onCellChangedFn;
|
||||
BoardTextCellBloc({
|
||||
required this.cellController,
|
||||
|
@ -71,7 +71,7 @@ class BoardTextCellState with _$BoardTextCellState {
|
|||
required bool enableEdit,
|
||||
}) = _BoardTextCellState;
|
||||
|
||||
factory BoardTextCellState.initial(GridCellController context) =>
|
||||
factory BoardTextCellState.initial(GridTextCellController context) =>
|
||||
BoardTextCellState(
|
||||
content: context.getCellData() ?? "",
|
||||
enableEdit: false,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/url_type_option_entities.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -3,7 +3,7 @@ import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_servic
|
|||
import 'package:app_flowy/plugins/grid/application/row/row_cache.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/row/row_service.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/row_entities.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -3,7 +3,7 @@ import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_servic
|
|||
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_field_notifier.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/row/row_cache.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/row_entities.pb.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
typedef OnCardChanged = void Function(GridCellMap, RowsChangedReason);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
|
||||
class BoardGroupService {
|
||||
final String gridId;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/protobuf.dart';
|
||||
import 'group_listener.dart';
|
||||
|
||||
typedef OnGroupError = void Function(FlowyError);
|
||||
|
|
|
@ -2,11 +2,11 @@ import 'dart:typed_data';
|
|||
|
||||
import 'package:app_flowy/core/grid_notification.dart';
|
||||
import 'package:flowy_infra/notifier.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/group.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/group.pb.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/group_changeset.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/group_changeset.pb.dart';
|
||||
|
||||
typedef UpdateGroupNotifiedValue = Either<GroupRowsNotificationPB, FlowyError>;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:app_flowy/plugins/util.dart';
|
||||
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
|
||||
import 'package:app_flowy/workspace/presentation/widgets/left_bar_item.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:app_flowy/startup/plugin/plugin.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
|
|
@ -15,12 +15,11 @@ import 'package:flowy_infra/image.dart';
|
|||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui_web.dart';
|
||||
import 'package:flowy_infra_ui/widget/error_page.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/row_entities.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../../grid/application/row/row_cache.dart';
|
||||
import '../application/board_bloc.dart';
|
||||
import 'card/card.dart';
|
||||
import 'card/card_cell_builder.dart';
|
||||
|
@ -289,7 +288,7 @@ class _BoardContentState extends State<BoardContent> {
|
|||
rowPB: rowPB,
|
||||
);
|
||||
|
||||
final dataController = GridRowDataController(
|
||||
final dataController = RowDataController(
|
||||
rowInfo: rowInfo,
|
||||
fieldController: fieldController,
|
||||
rowCache: rowCache,
|
||||
|
|
|
@ -35,7 +35,7 @@ class _BoardTextCellState extends State<BoardTextCell> {
|
|||
@override
|
||||
void initState() {
|
||||
final cellController =
|
||||
widget.cellControllerBuilder.build() as GridCellController;
|
||||
widget.cellControllerBuilder.build() as GridTextCellController;
|
||||
_cellBloc = BoardTextCellBloc(cellController: cellController)
|
||||
..add(const BoardTextCellEvent.initial());
|
||||
_controller = TextEditingController(text: _cellBloc.state.content);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'board_cell.dart';
|
||||
|
|
|
@ -13,6 +13,7 @@ import 'package:flowy_infra_ui/style_widget/text.dart';
|
|||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
import 'board_toolbar.dart';
|
||||
|
||||
|
@ -181,6 +182,6 @@ class _BoardSettingListPopoverState extends State<BoardSettingListPopover> {
|
|||
onAction: (action, settingContext) {
|
||||
setState(() => _action = action);
|
||||
},
|
||||
);
|
||||
).padding(all: 6.0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
|
||||
import 'package:app_flowy/plugins/grid/presentation/layout/sizes.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
|
@ -67,12 +68,12 @@ class _SettingButtonState extends State<_SettingButton> {
|
|||
direction: PopoverDirection.leftWithTopAligned,
|
||||
triggerActions: PopoverTriggerFlags.none,
|
||||
constraints: BoxConstraints.loose(const Size(260, 400)),
|
||||
margin: EdgeInsets.zero,
|
||||
child: FlowyTextButton(
|
||||
LocaleKeys.settings_title.tr(),
|
||||
fontSize: 14,
|
||||
fillColor: Colors.transparent,
|
||||
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||
padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 6),
|
||||
padding: GridSize.typeOptionContentInsets,
|
||||
onPressed: () {
|
||||
popoverController.show();
|
||||
},
|
||||
|
|
111
frontend/app_flowy/lib/plugins/calendar/calendar.dart
Normal file
111
frontend/app_flowy/lib/plugins/calendar/calendar.dart
Normal file
|
@ -0,0 +1,111 @@
|
|||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||
import 'package:app_flowy/startup/plugin/plugin.dart';
|
||||
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
|
||||
import 'package:app_flowy/workspace/presentation/widgets/left_bar_item.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../util.dart';
|
||||
|
||||
class CalendarPluginBuilder extends PluginBuilder {
|
||||
@override
|
||||
Plugin build(dynamic data) {
|
||||
if (data is ViewPB) {
|
||||
return CalendarPlugin(pluginType: pluginType, view: data);
|
||||
} else {
|
||||
throw FlowyPluginException.invalidData;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
String get menuName => LocaleKeys.calendar_menuName.tr();
|
||||
|
||||
@override
|
||||
String get menuIcon => "editor/date";
|
||||
|
||||
@override
|
||||
PluginType get pluginType => PluginType.calendar;
|
||||
|
||||
@override
|
||||
ViewDataFormatPB get dataFormatType => ViewDataFormatPB.DatabaseFormat;
|
||||
|
||||
@override
|
||||
ViewLayoutTypePB? get layoutType => ViewLayoutTypePB.Calendar;
|
||||
}
|
||||
|
||||
class CalendarPluginConfig implements PluginConfig {
|
||||
@override
|
||||
bool get creatable => false;
|
||||
}
|
||||
|
||||
class CalendarPlugin extends Plugin {
|
||||
@override
|
||||
final ViewPluginNotifier notifier;
|
||||
final PluginType _pluginType;
|
||||
|
||||
CalendarPlugin({
|
||||
required ViewPB view,
|
||||
required PluginType pluginType,
|
||||
}) : _pluginType = pluginType,
|
||||
notifier = ViewPluginNotifier(view: view);
|
||||
|
||||
@override
|
||||
PluginDisplay get display => CalendarPluginDisplay(notifier: notifier);
|
||||
|
||||
@override
|
||||
PluginId get id => notifier.view.id;
|
||||
|
||||
@override
|
||||
PluginType get ty => _pluginType;
|
||||
}
|
||||
|
||||
class CalendarPluginDisplay extends PluginDisplay {
|
||||
final ViewPluginNotifier notifier;
|
||||
CalendarPluginDisplay({required this.notifier, Key? key});
|
||||
|
||||
ViewPB get view => notifier.view;
|
||||
|
||||
@override
|
||||
Widget get leftBarItem => ViewLeftBarItem(view: view);
|
||||
|
||||
@override
|
||||
Widget buildWidget(PluginContext context) {
|
||||
notifier.isDeleted.addListener(() {
|
||||
notifier.isDeleted.value.fold(() => null, (deletedView) {
|
||||
if (deletedView.hasIndex()) {
|
||||
context.onDeleted(view, deletedView.index);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return BlankPage(key: ValueKey(view.id));
|
||||
// return BoardPage(key: ValueKey(view.id), view: view);
|
||||
}
|
||||
|
||||
@override
|
||||
List<NavigationItem> get navigationItems => [this];
|
||||
}
|
||||
|
||||
// mark for removal
|
||||
class BlankPage extends StatefulWidget {
|
||||
const BlankPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<BlankPage> createState() => _BlankPageState();
|
||||
}
|
||||
|
||||
class _BlankPageState extends State<BlankPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox.expand(
|
||||
child: Container(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Container(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -4,10 +4,10 @@ import 'package:app_flowy/workspace/application/view/view_listener.dart';
|
|||
import 'package:app_flowy/plugins/document/application/doc_service.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart'
|
||||
show EditorState, Document, Transaction;
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder/trash.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/trash.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-document/entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart';
|
||||
|
||||
class DocumentService {
|
||||
Future<Either<DocumentSnapshotPB, FlowyError>> openDocument({
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'package:app_flowy/plugins/document/application/share_service.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-document/entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import 'dart:async';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-document/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-document/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
|
||||
class ShareService {
|
||||
Future<Either<ExportDataPB, FlowyError>> export(
|
||||
|
|
|
@ -10,7 +10,7 @@ import 'package:app_flowy/startup/plugin/plugin.dart';
|
|||
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
|
||||
import 'package:app_flowy/workspace/presentation/widgets/left_bar_item.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart';
|
||||
import 'package:flowy_infra_ui/widget/error_page.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
|
|
@ -11,10 +11,10 @@ import 'package:clipboard/clipboard.dart';
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flowy_infra_ui/widget/rounded_button.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-document/entities.pb.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:app_flowy/core/grid_notification.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||
import 'package:flowy_infra/notifier.dart';
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
part of 'cell_service.dart';
|
||||
|
||||
typedef GridCellController = IGridCellController<String, String>;
|
||||
typedef GridCheckboxCellController = IGridCellController<String, String>;
|
||||
typedef GridNumberCellController = IGridCellController<String, String>;
|
||||
typedef GridTextCellController = GridCellController<String, String>;
|
||||
typedef GridCheckboxCellController = GridCellController<String, String>;
|
||||
typedef GridNumberCellController = GridCellController<String, String>;
|
||||
typedef GridSelectOptionCellController
|
||||
= IGridCellController<SelectOptionCellDataPB, String>;
|
||||
= GridCellController<SelectOptionCellDataPB, String>;
|
||||
typedef GridChecklistCellController
|
||||
= IGridCellController<SelectOptionCellDataPB, String>;
|
||||
= GridCellController<SelectOptionCellDataPB, String>;
|
||||
typedef GridDateCellController
|
||||
= IGridCellController<DateCellDataPB, CalendarData>;
|
||||
typedef GridURLCellController = IGridCellController<URLCellDataPB, String>;
|
||||
= GridCellController<DateCellDataPB, CalendarData>;
|
||||
typedef GridURLCellController = GridCellController<URLCellDataPB, String>;
|
||||
|
||||
abstract class GridCellControllerBuilderDelegate {
|
||||
GridCellFieldNotifier buildFieldNotifier();
|
||||
|
@ -27,7 +27,7 @@ class GridCellControllerBuilder {
|
|||
}) : _cellCache = cellCache,
|
||||
_cellId = cellId;
|
||||
|
||||
IGridCellController build() {
|
||||
GridCellController build() {
|
||||
final cellFieldNotifier = delegate.buildFieldNotifier();
|
||||
switch (_cellId.fieldType) {
|
||||
case FieldType.Checkbox:
|
||||
|
@ -35,12 +35,12 @@ class GridCellControllerBuilder {
|
|||
cellId: _cellId,
|
||||
parser: StringCellDataParser(),
|
||||
);
|
||||
return GridCellController(
|
||||
return GridTextCellController(
|
||||
cellId: _cellId,
|
||||
cellCache: _cellCache,
|
||||
cellDataLoader: cellDataLoader,
|
||||
fieldNotifier: cellFieldNotifier,
|
||||
cellDataPersistence: CellDataPersistence(cellId: _cellId),
|
||||
cellDataPersistence: TextCellDataPersistence(cellId: _cellId),
|
||||
);
|
||||
case FieldType.DateTime:
|
||||
final cellDataLoader = GridCellDataLoader(
|
||||
|
@ -67,19 +67,19 @@ class GridCellControllerBuilder {
|
|||
cellCache: _cellCache,
|
||||
cellDataLoader: cellDataLoader,
|
||||
fieldNotifier: cellFieldNotifier,
|
||||
cellDataPersistence: CellDataPersistence(cellId: _cellId),
|
||||
cellDataPersistence: TextCellDataPersistence(cellId: _cellId),
|
||||
);
|
||||
case FieldType.RichText:
|
||||
final cellDataLoader = GridCellDataLoader(
|
||||
cellId: _cellId,
|
||||
parser: StringCellDataParser(),
|
||||
);
|
||||
return GridCellController(
|
||||
return GridTextCellController(
|
||||
cellId: _cellId,
|
||||
cellCache: _cellCache,
|
||||
cellDataLoader: cellDataLoader,
|
||||
fieldNotifier: cellFieldNotifier,
|
||||
cellDataPersistence: CellDataPersistence(cellId: _cellId),
|
||||
cellDataPersistence: TextCellDataPersistence(cellId: _cellId),
|
||||
);
|
||||
case FieldType.MultiSelect:
|
||||
case FieldType.SingleSelect:
|
||||
|
@ -95,7 +95,7 @@ class GridCellControllerBuilder {
|
|||
cellCache: _cellCache,
|
||||
cellDataLoader: cellDataLoader,
|
||||
fieldNotifier: cellFieldNotifier,
|
||||
cellDataPersistence: CellDataPersistence(cellId: _cellId),
|
||||
cellDataPersistence: TextCellDataPersistence(cellId: _cellId),
|
||||
);
|
||||
|
||||
case FieldType.URL:
|
||||
|
@ -108,7 +108,7 @@ class GridCellControllerBuilder {
|
|||
cellCache: _cellCache,
|
||||
cellDataLoader: cellDataLoader,
|
||||
fieldNotifier: cellFieldNotifier,
|
||||
cellDataPersistence: CellDataPersistence(cellId: _cellId),
|
||||
cellDataPersistence: TextCellDataPersistence(cellId: _cellId),
|
||||
);
|
||||
}
|
||||
throw UnimplementedError;
|
||||
|
@ -123,14 +123,14 @@ class GridCellControllerBuilder {
|
|||
/// Generic D represents the type of data that will be saved to the disk
|
||||
///
|
||||
// ignore: must_be_immutable
|
||||
class IGridCellController<T, D> extends Equatable {
|
||||
class GridCellController<T, D> extends Equatable {
|
||||
final GridCellIdentifier cellId;
|
||||
final GridCellCache _cellsCache;
|
||||
final GridCellCacheKey _cacheKey;
|
||||
final FieldService _fieldService;
|
||||
final GridCellFieldNotifier _fieldNotifier;
|
||||
final GridCellDataLoader<T> _cellDataLoader;
|
||||
final IGridCellDataPersistence<D> _cellDataPersistence;
|
||||
final GridCellDataPersistence<D> _cellDataPersistence;
|
||||
|
||||
CellListener? _cellListener;
|
||||
CellDataNotifier<T?>? _cellDataNotifier;
|
||||
|
@ -141,12 +141,12 @@ class IGridCellController<T, D> extends Equatable {
|
|||
Timer? _saveDataOperation;
|
||||
bool _isDispose = false;
|
||||
|
||||
IGridCellController({
|
||||
GridCellController({
|
||||
required this.cellId,
|
||||
required GridCellCache cellCache,
|
||||
required GridCellFieldNotifier fieldNotifier,
|
||||
required GridCellDataLoader<T> cellDataLoader,
|
||||
required IGridCellDataPersistence<D> cellDataPersistence,
|
||||
required GridCellDataPersistence<D> cellDataPersistence,
|
||||
}) : _cellsCache = cellCache,
|
||||
_cellDataLoader = cellDataLoader,
|
||||
_cellDataPersistence = cellDataPersistence,
|
||||
|
|
|
@ -5,14 +5,14 @@ abstract class IGridCellDataConfig {
|
|||
bool get reloadOnFieldChanged;
|
||||
}
|
||||
|
||||
abstract class IGridCellDataParser<T> {
|
||||
abstract class GridCellDataParser<T> {
|
||||
T? parserData(List<int> data);
|
||||
}
|
||||
|
||||
class GridCellDataLoader<T> {
|
||||
final CellService service = CellService();
|
||||
final GridCellIdentifier cellId;
|
||||
final IGridCellDataParser<T> parser;
|
||||
final GridCellDataParser<T> parser;
|
||||
final bool reloadOnFieldChanged;
|
||||
|
||||
GridCellDataLoader({
|
||||
|
@ -43,7 +43,7 @@ class GridCellDataLoader<T> {
|
|||
}
|
||||
}
|
||||
|
||||
class StringCellDataParser implements IGridCellDataParser<String> {
|
||||
class StringCellDataParser implements GridCellDataParser<String> {
|
||||
@override
|
||||
String? parserData(List<int> data) {
|
||||
final s = utf8.decode(data);
|
||||
|
@ -51,7 +51,7 @@ class StringCellDataParser implements IGridCellDataParser<String> {
|
|||
}
|
||||
}
|
||||
|
||||
class DateCellDataParser implements IGridCellDataParser<DateCellDataPB> {
|
||||
class DateCellDataParser implements GridCellDataParser<DateCellDataPB> {
|
||||
@override
|
||||
DateCellDataPB? parserData(List<int> data) {
|
||||
if (data.isEmpty) {
|
||||
|
@ -62,7 +62,7 @@ class DateCellDataParser implements IGridCellDataParser<DateCellDataPB> {
|
|||
}
|
||||
|
||||
class SelectOptionCellDataParser
|
||||
implements IGridCellDataParser<SelectOptionCellDataPB> {
|
||||
implements GridCellDataParser<SelectOptionCellDataPB> {
|
||||
@override
|
||||
SelectOptionCellDataPB? parserData(List<int> data) {
|
||||
if (data.isEmpty) {
|
||||
|
@ -72,7 +72,7 @@ class SelectOptionCellDataParser
|
|||
}
|
||||
}
|
||||
|
||||
class URLCellDataParser implements IGridCellDataParser<URLCellDataPB> {
|
||||
class URLCellDataParser implements GridCellDataParser<URLCellDataPB> {
|
||||
@override
|
||||
URLCellDataPB? parserData(List<int> data) {
|
||||
if (data.isEmpty) {
|
||||
|
|
|
@ -2,14 +2,14 @@ part of 'cell_service.dart';
|
|||
|
||||
/// Save the cell data to disk
|
||||
/// You can extend this class to do custom operations. For example, the DateCellDataPersistence.
|
||||
abstract class IGridCellDataPersistence<D> {
|
||||
abstract class GridCellDataPersistence<D> {
|
||||
Future<Option<FlowyError>> save(D data);
|
||||
}
|
||||
|
||||
class CellDataPersistence implements IGridCellDataPersistence<String> {
|
||||
class TextCellDataPersistence implements GridCellDataPersistence<String> {
|
||||
final GridCellIdentifier cellId;
|
||||
|
||||
CellDataPersistence({
|
||||
TextCellDataPersistence({
|
||||
required this.cellId,
|
||||
});
|
||||
final CellService _cellService = CellService();
|
||||
|
@ -33,8 +33,7 @@ class CalendarData with _$CalendarData {
|
|||
_CalendarData;
|
||||
}
|
||||
|
||||
class DateCellDataPersistence
|
||||
implements IGridCellDataPersistence<CalendarData> {
|
||||
class DateCellDataPersistence implements GridCellDataPersistence<CalendarData> {
|
||||
final GridCellIdentifier cellId;
|
||||
DateCellDataPersistence({
|
||||
required this.cellId,
|
||||
|
|
|
@ -2,14 +2,14 @@ import 'dart:async';
|
|||
import 'dart:collection';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option_entities.pb.dart';
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/cell_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/date_type_option_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/url_type_option_entities.pb.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/cell/cell_listener.dart';
|
||||
|
|
|
@ -65,7 +65,7 @@ class CheckboxCellState with _$CheckboxCellState {
|
|||
required bool isSelected,
|
||||
}) = _CheckboxCellState;
|
||||
|
||||
factory CheckboxCellState.initial(GridCellController context) {
|
||||
factory CheckboxCellState.initial(GridTextCellController context) {
|
||||
return CheckboxCellState(isSelected: _isSelected(context.getCellData()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -2,8 +2,8 @@ import 'dart:async';
|
|||
|
||||
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
|
|
|
@ -2,11 +2,11 @@ import 'package:app_flowy/generated/locale_keys.g.dart';
|
|||
import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
|
||||
import 'package:easy_localization/easy_localization.dart'
|
||||
show StringTranslateExtension;
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/code.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/code.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/date_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/date_type_option_entities.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:table_calendar/table_calendar.dart';
|
||||
|
@ -41,8 +41,8 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
|
|||
},
|
||||
didReceiveCellUpdate: (DateCellDataPB? cellData) {
|
||||
final calData = calDataFromCellData(cellData);
|
||||
final time =
|
||||
calData.foldRight("", (dateData, previous) => dateData.time);
|
||||
final time = calData.foldRight(
|
||||
"", (dateData, previous) => dateData.time ?? '');
|
||||
emit(state.copyWith(calData: calData, time: time));
|
||||
},
|
||||
setIncludeTime: (includeTime) async {
|
||||
|
@ -224,7 +224,8 @@ class DateCalState with _$DateCalState {
|
|||
DateCellDataPB? cellData,
|
||||
) {
|
||||
Option<CalendarData> calData = calDataFromCellData(cellData);
|
||||
final time = calData.foldRight("", (dateData, previous) => dateData.time);
|
||||
final time =
|
||||
calData.foldRight("", (dateData, previous) => dateData.time ?? '');
|
||||
return DateCalState(
|
||||
dateTypeOptionPB: dateTypeOptionPB,
|
||||
format: CalendarFormat.month,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/date_type_option_entities.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
@ -82,7 +82,7 @@ class NumberCellState with _$NumberCellState {
|
|||
required String cellContent,
|
||||
}) = _NumberCellState;
|
||||
|
||||
factory NumberCellState.initial(GridCellController context) {
|
||||
factory NumberCellState.initial(GridTextCellController context) {
|
||||
return NumberCellState(
|
||||
cellContent: context.getCellData() ?? "",
|
||||
);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'dart:async';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import 'dart:async';
|
||||
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'select_option_service.dart';
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart';
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/cell_entities.pb.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_service.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'cell_service/cell_service.dart';
|
||||
|
||||
class SelectOptionFFIService {
|
||||
|
|
|
@ -6,7 +6,7 @@ import 'cell_service/cell_service.dart';
|
|||
part 'text_cell_bloc.freezed.dart';
|
||||
|
||||
class TextCellBloc extends Bloc<TextCellEvent, TextCellState> {
|
||||
final GridCellController cellController;
|
||||
final GridTextCellController cellController;
|
||||
void Function()? _onCellChangedFn;
|
||||
TextCellBloc({
|
||||
required this.cellController,
|
||||
|
@ -66,7 +66,8 @@ class TextCellState with _$TextCellState {
|
|||
required String content,
|
||||
}) = _TextCellState;
|
||||
|
||||
factory TextCellState.initial(GridCellController context) => TextCellState(
|
||||
factory TextCellState.initial(GridTextCellController context) =>
|
||||
TextCellState(
|
||||
content: context.getCellData() ?? "",
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/url_type_option_entities.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/url_type_option_entities.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:app_flowy/plugins/grid/application/field/field_listener.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -5,14 +5,19 @@ import 'package:app_flowy/plugins/grid/application/filter/filter_service.dart';
|
|||
import 'package:app_flowy/plugins/grid/application/grid_service.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/setting/setting_listener.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/setting/setting_service.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/sort/sort_listener.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/sort/sort_service.dart';
|
||||
import 'package:app_flowy/plugins/grid/presentation/widgets/filter/filter_info.dart';
|
||||
import 'package:app_flowy/plugins/grid/presentation/widgets/sort/sort_info.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/filter_changeset.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/sort_entities.pb.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/group.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/setting_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/util.pb.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/group.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/setting_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/util.pb.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import '../row/row_cache.dart';
|
||||
|
||||
|
@ -46,21 +51,39 @@ class _GridFilterNotifier extends ChangeNotifier {
|
|||
List<FilterInfo> get filters => _filters;
|
||||
}
|
||||
|
||||
class _GridSortNotifier extends ChangeNotifier {
|
||||
List<SortInfo> _sorts = [];
|
||||
|
||||
set sorts(List<SortInfo> sorts) {
|
||||
_sorts = sorts;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void notify() {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
List<SortInfo> get sorts => _sorts;
|
||||
}
|
||||
|
||||
typedef OnReceiveUpdateFields = void Function(List<FieldInfo>);
|
||||
typedef OnReceiveFields = void Function(List<FieldInfo>);
|
||||
typedef OnReceiveFilters = void Function(List<FilterInfo>);
|
||||
typedef OnReceiveSorts = void Function(List<SortInfo>);
|
||||
|
||||
class GridFieldController {
|
||||
final String gridId;
|
||||
// Listeners
|
||||
final GridFieldsListener _fieldListener;
|
||||
final SettingListener _settingListener;
|
||||
final FiltersListener _filterListener;
|
||||
final FiltersListener _filtersListener;
|
||||
final SortsListener _sortsListener;
|
||||
|
||||
// FFI services
|
||||
final GridFFIService _gridFFIService;
|
||||
final SettingFFIService _settingFFIService;
|
||||
final FilterFFIService _filterFFIService;
|
||||
final SortFFIService _sortFFIService;
|
||||
|
||||
// Field callbacks
|
||||
final Map<OnReceiveFields, VoidCallback> _fieldCallbacks = {};
|
||||
|
@ -78,9 +101,16 @@ class GridFieldController {
|
|||
_GridFilterNotifier? _filterNotifier = _GridFilterNotifier();
|
||||
final Map<String, FilterPB> _filterPBByFieldId = {};
|
||||
|
||||
// Sort callbacks
|
||||
final Map<OnReceiveSorts, VoidCallback> _sortCallbacks = {};
|
||||
_GridSortNotifier? _sortNotifier = _GridSortNotifier();
|
||||
final Map<String, SortPB> _sortPBByFieldId = {};
|
||||
|
||||
// Getters
|
||||
List<FieldInfo> get fieldInfos => [..._fieldNotifier?.fieldInfos ?? []];
|
||||
List<FilterInfo> get filterInfos => [..._filterNotifier?.filters ?? []];
|
||||
List<SortInfo> get sortInfos => [..._sortNotifier?.sorts ?? []];
|
||||
|
||||
FieldInfo? getField(String fieldId) {
|
||||
final fields = _fieldNotifier?.fieldInfos
|
||||
.where((element) => element.id == fieldId)
|
||||
|
@ -105,12 +135,26 @@ class GridFieldController {
|
|||
return filters.first;
|
||||
}
|
||||
|
||||
SortInfo? getSort(String sortId) {
|
||||
final sorts = _sortNotifier?.sorts
|
||||
.where((element) => element.sortId == sortId)
|
||||
.toList() ??
|
||||
[];
|
||||
if (sorts.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
assert(sorts.length == 1);
|
||||
return sorts.first;
|
||||
}
|
||||
|
||||
GridFieldController({required this.gridId})
|
||||
: _fieldListener = GridFieldsListener(gridId: gridId),
|
||||
_settingListener = SettingListener(gridId: gridId),
|
||||
_filterListener = FiltersListener(viewId: gridId),
|
||||
_gridFFIService = GridFFIService(gridId: gridId),
|
||||
_filterFFIService = FilterFFIService(viewId: gridId),
|
||||
_filtersListener = FiltersListener(viewId: gridId),
|
||||
_gridFFIService = GridFFIService(gridId: gridId),
|
||||
_sortFFIService = SortFFIService(viewId: gridId),
|
||||
_sortsListener = SortsListener(viewId: gridId),
|
||||
_settingFFIService = SettingFFIService(viewId: gridId) {
|
||||
//Listen on field's changes
|
||||
_listenOnFieldChanges();
|
||||
|
@ -121,9 +165,12 @@ class GridFieldController {
|
|||
//Listen on the fitler changes
|
||||
_listenOnFilterChanges();
|
||||
|
||||
//Listen on the sort changes
|
||||
_listenOnSortChanged();
|
||||
|
||||
_settingFFIService.getSetting().then((result) {
|
||||
result.fold(
|
||||
(setting) => _updateSettingConfiguration(setting),
|
||||
(setting) => _updateSetting(setting),
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
|
@ -131,68 +178,95 @@ class GridFieldController {
|
|||
|
||||
void _listenOnFilterChanges() {
|
||||
//Listen on the fitler changes
|
||||
_filterListener.start(onFilterChanged: (result) {
|
||||
|
||||
deleteFilterFromChangeset(
|
||||
List<FilterInfo> filters,
|
||||
FilterChangesetNotificationPB changeset,
|
||||
) {
|
||||
final deleteFilterIds = changeset.deleteFilters.map((e) => e.id).toList();
|
||||
if (deleteFilterIds.isNotEmpty) {
|
||||
filters.retainWhere(
|
||||
(element) => !deleteFilterIds.contains(element.filter.id),
|
||||
);
|
||||
|
||||
_filterPBByFieldId
|
||||
.removeWhere((key, value) => deleteFilterIds.contains(value.id));
|
||||
}
|
||||
}
|
||||
|
||||
insertFilterFromChangeset(
|
||||
List<FilterInfo> filters,
|
||||
FilterChangesetNotificationPB changeset,
|
||||
) {
|
||||
for (final newFilter in changeset.insertFilters) {
|
||||
final filterIndex =
|
||||
filters.indexWhere((element) => element.filter.id == newFilter.id);
|
||||
if (filterIndex == -1) {
|
||||
final fieldInfo = _findFieldInfo(
|
||||
fieldInfos: fieldInfos,
|
||||
fieldId: newFilter.fieldId,
|
||||
fieldType: newFilter.fieldType,
|
||||
);
|
||||
if (fieldInfo != null) {
|
||||
_filterPBByFieldId[fieldInfo.id] = newFilter;
|
||||
filters.add(FilterInfo(gridId, newFilter, fieldInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateFilterFromChangeset(
|
||||
List<FilterInfo> filters,
|
||||
FilterChangesetNotificationPB changeset,
|
||||
) {
|
||||
for (final updatedFilter in changeset.updateFilters) {
|
||||
final filterIndex = filters.indexWhere(
|
||||
(element) => element.filter.id == updatedFilter.filterId,
|
||||
);
|
||||
// Remove the old filter
|
||||
if (filterIndex != -1) {
|
||||
filters.removeAt(filterIndex);
|
||||
_filterPBByFieldId
|
||||
.removeWhere((key, value) => value.id == updatedFilter.filterId);
|
||||
}
|
||||
|
||||
// Insert the filter if there is a fitler and its field info is
|
||||
// not null
|
||||
if (updatedFilter.hasFilter()) {
|
||||
final fieldInfo = _findFieldInfo(
|
||||
fieldInfos: fieldInfos,
|
||||
fieldId: updatedFilter.filter.fieldId,
|
||||
fieldType: updatedFilter.filter.fieldType,
|
||||
);
|
||||
|
||||
if (fieldInfo != null) {
|
||||
// Insert the filter with the position: filterIndex, otherwise,
|
||||
// append it to the end of the list.
|
||||
final filterInfo =
|
||||
FilterInfo(gridId, updatedFilter.filter, fieldInfo);
|
||||
if (filterIndex != -1) {
|
||||
filters.insert(filterIndex, filterInfo);
|
||||
} else {
|
||||
filters.add(filterInfo);
|
||||
}
|
||||
_filterPBByFieldId[fieldInfo.id] = updatedFilter.filter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_filtersListener.start(onFilterChanged: (result) {
|
||||
result.fold(
|
||||
(changeset) {
|
||||
(FilterChangesetNotificationPB changeset) {
|
||||
final List<FilterInfo> filters = filterInfos;
|
||||
// Deletes the filters
|
||||
final deleteFilterIds =
|
||||
changeset.deleteFilters.map((e) => e.id).toList();
|
||||
if (deleteFilterIds.isNotEmpty) {
|
||||
filters.retainWhere(
|
||||
(element) => !deleteFilterIds.contains(element.filter.id),
|
||||
);
|
||||
|
||||
_filterPBByFieldId.removeWhere(
|
||||
(key, value) => deleteFilterIds.contains(value.id));
|
||||
}
|
||||
deleteFilterFromChangeset(filters, changeset);
|
||||
|
||||
// Inserts the new filter if it's not exist
|
||||
for (final newFilter in changeset.insertFilters) {
|
||||
final filterIndex = filters
|
||||
.indexWhere((element) => element.filter.id == newFilter.id);
|
||||
if (filterIndex == -1) {
|
||||
final fieldInfo = _findFieldInfoForFilter(fieldInfos, newFilter);
|
||||
if (fieldInfo != null) {
|
||||
_filterPBByFieldId[fieldInfo.id] = newFilter;
|
||||
filters.add(FilterInfo(gridId, newFilter, fieldInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
insertFilterFromChangeset(filters, changeset);
|
||||
|
||||
for (final updatedFilter in changeset.updateFilters) {
|
||||
final filterIndex = filters.indexWhere(
|
||||
(element) => element.filter.id == updatedFilter.filterId,
|
||||
);
|
||||
// Remove the old filter
|
||||
if (filterIndex != -1) {
|
||||
filters.removeAt(filterIndex);
|
||||
_filterPBByFieldId.removeWhere(
|
||||
(key, value) => value.id == updatedFilter.filterId);
|
||||
}
|
||||
updateFilterFromChangeset(filters, changeset);
|
||||
|
||||
// Insert the filter if there is a fitler and its field info is
|
||||
// not null
|
||||
if (updatedFilter.hasFilter()) {
|
||||
final fieldInfo = _findFieldInfoForFilter(
|
||||
fieldInfos,
|
||||
updatedFilter.filter,
|
||||
);
|
||||
|
||||
if (fieldInfo != null) {
|
||||
// Insert the filter with the position: filterIndex, otherwise,
|
||||
// append it to the end of the list.
|
||||
final filterInfo =
|
||||
FilterInfo(gridId, updatedFilter.filter, fieldInfo);
|
||||
if (filterIndex != -1) {
|
||||
filters.insert(filterIndex, filterInfo);
|
||||
} else {
|
||||
filters.add(filterInfo);
|
||||
}
|
||||
_filterPBByFieldId[fieldInfo.id] = updatedFilter.filter;
|
||||
}
|
||||
}
|
||||
}
|
||||
_updateFieldInfos();
|
||||
_filterNotifier?.filters = filters;
|
||||
},
|
||||
|
@ -201,11 +275,99 @@ class GridFieldController {
|
|||
});
|
||||
}
|
||||
|
||||
void _listenOnSortChanged() {
|
||||
deleteSortFromChangeset(
|
||||
List<SortInfo> newSortInfos,
|
||||
SortChangesetNotificationPB changeset,
|
||||
) {
|
||||
final deleteSortIds = changeset.deleteSorts.map((e) => e.id).toList();
|
||||
if (deleteSortIds.isNotEmpty) {
|
||||
newSortInfos.retainWhere(
|
||||
(element) => !deleteSortIds.contains(element.sortId),
|
||||
);
|
||||
|
||||
_sortPBByFieldId
|
||||
.removeWhere((key, value) => deleteSortIds.contains(value.id));
|
||||
}
|
||||
}
|
||||
|
||||
insertSortFromChangeset(
|
||||
List<SortInfo> newSortInfos,
|
||||
SortChangesetNotificationPB changeset,
|
||||
) {
|
||||
for (final newSortPB in changeset.insertSorts) {
|
||||
final sortIndex = newSortInfos
|
||||
.indexWhere((element) => element.sortId == newSortPB.id);
|
||||
if (sortIndex == -1) {
|
||||
final fieldInfo = _findFieldInfo(
|
||||
fieldInfos: fieldInfos,
|
||||
fieldId: newSortPB.fieldId,
|
||||
fieldType: newSortPB.fieldType,
|
||||
);
|
||||
|
||||
if (fieldInfo != null) {
|
||||
_sortPBByFieldId[newSortPB.fieldId] = newSortPB;
|
||||
newSortInfos.add(SortInfo(sortPB: newSortPB, fieldInfo: fieldInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateSortFromChangeset(
|
||||
List<SortInfo> newSortInfos,
|
||||
SortChangesetNotificationPB changeset,
|
||||
) {
|
||||
for (final updatedSort in changeset.updateSorts) {
|
||||
final sortIndex = newSortInfos.indexWhere(
|
||||
(element) => element.sortId == updatedSort.id,
|
||||
);
|
||||
// Remove the old filter
|
||||
if (sortIndex != -1) {
|
||||
newSortInfos.removeAt(sortIndex);
|
||||
}
|
||||
|
||||
final fieldInfo = _findFieldInfo(
|
||||
fieldInfos: fieldInfos,
|
||||
fieldId: updatedSort.fieldId,
|
||||
fieldType: updatedSort.fieldType,
|
||||
);
|
||||
|
||||
if (fieldInfo != null) {
|
||||
final newSortInfo = SortInfo(
|
||||
sortPB: updatedSort,
|
||||
fieldInfo: fieldInfo,
|
||||
);
|
||||
if (sortIndex != -1) {
|
||||
newSortInfos.insert(sortIndex, newSortInfo);
|
||||
} else {
|
||||
newSortInfos.add(newSortInfo);
|
||||
}
|
||||
_sortPBByFieldId[updatedSort.fieldId] = updatedSort;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_sortsListener.start(onSortChanged: (result) {
|
||||
result.fold(
|
||||
(SortChangesetNotificationPB changeset) {
|
||||
final List<SortInfo> newSortInfos = sortInfos;
|
||||
deleteSortFromChangeset(newSortInfos, changeset);
|
||||
insertSortFromChangeset(newSortInfos, changeset);
|
||||
updateSortFromChangeset(newSortInfos, changeset);
|
||||
|
||||
_updateFieldInfos();
|
||||
_sortNotifier?.sorts = newSortInfos;
|
||||
},
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
void _listenOnSettingChanges() {
|
||||
//Listen on setting changes
|
||||
_settingListener.start(onSettingUpdated: (result) {
|
||||
result.fold(
|
||||
(setting) => _updateSettingConfiguration(setting),
|
||||
(setting) => _updateSetting(setting),
|
||||
(r) => Log.error(r),
|
||||
);
|
||||
});
|
||||
|
@ -229,14 +391,18 @@ class GridFieldController {
|
|||
});
|
||||
}
|
||||
|
||||
void _updateSettingConfiguration(GridSettingPB setting) {
|
||||
void _updateSetting(GridSettingPB setting) {
|
||||
_groupConfigurationByFieldId.clear();
|
||||
for (final configuration in setting.groupConfigurations.items) {
|
||||
_groupConfigurationByFieldId[configuration.fieldId] = configuration;
|
||||
}
|
||||
|
||||
for (final configuration in setting.filters.items) {
|
||||
_filterPBByFieldId[configuration.fieldId] = configuration;
|
||||
for (final filter in setting.filters.items) {
|
||||
_filterPBByFieldId[filter.fieldId] = filter;
|
||||
}
|
||||
|
||||
for (final sort in setting.sorts.items) {
|
||||
_sortPBByFieldId[sort.fieldId] = sort;
|
||||
}
|
||||
|
||||
_updateFieldInfos();
|
||||
|
@ -247,6 +413,7 @@ class GridFieldController {
|
|||
for (var field in _fieldNotifier!.fieldInfos) {
|
||||
field._isGroupField = _groupConfigurationByFieldId[field.id] != null;
|
||||
field._hasFilter = _filterPBByFieldId[field.id] != null;
|
||||
field._hasSort = _sortPBByFieldId[field.id] != null;
|
||||
}
|
||||
_fieldNotifier?.notify();
|
||||
}
|
||||
|
@ -254,8 +421,9 @@ class GridFieldController {
|
|||
|
||||
Future<void> dispose() async {
|
||||
await _fieldListener.stop();
|
||||
await _filterListener.stop();
|
||||
await _filtersListener.stop();
|
||||
await _settingListener.stop();
|
||||
await _sortsListener.stop();
|
||||
|
||||
for (final callback in _fieldCallbacks.values) {
|
||||
_fieldNotifier?.removeListener(callback);
|
||||
|
@ -266,8 +434,15 @@ class GridFieldController {
|
|||
for (final callback in _filterCallbacks.values) {
|
||||
_filterNotifier?.removeListener(callback);
|
||||
}
|
||||
for (final callback in _sortCallbacks.values) {
|
||||
_sortNotifier?.removeListener(callback);
|
||||
}
|
||||
|
||||
_filterNotifier?.dispose();
|
||||
_filterNotifier = null;
|
||||
|
||||
_sortNotifier?.dispose();
|
||||
_sortNotifier = null;
|
||||
}
|
||||
|
||||
Future<Either<Unit, FlowyError>> loadFields({
|
||||
|
@ -280,6 +455,7 @@ class GridFieldController {
|
|||
_fieldNotifier?.fieldInfos =
|
||||
newFields.map((field) => FieldInfo(field: field)).toList();
|
||||
_loadFilters();
|
||||
_loadSorts();
|
||||
_updateFieldInfos();
|
||||
return left(unit);
|
||||
},
|
||||
|
@ -294,14 +470,17 @@ class GridFieldController {
|
|||
(filterPBs) {
|
||||
final List<FilterInfo> filters = [];
|
||||
for (final filterPB in filterPBs) {
|
||||
final fieldInfo = _findFieldInfoForFilter(fieldInfos, filterPB);
|
||||
final fieldInfo = _findFieldInfo(
|
||||
fieldInfos: fieldInfos,
|
||||
fieldId: filterPB.fieldId,
|
||||
fieldType: filterPB.fieldType,
|
||||
);
|
||||
if (fieldInfo != null) {
|
||||
final filterInfo = FilterInfo(gridId, filterPB, fieldInfo);
|
||||
filters.add(filterInfo);
|
||||
}
|
||||
}
|
||||
|
||||
_updateFieldInfos();
|
||||
_filterNotifier?.filters = filters;
|
||||
return left(unit);
|
||||
},
|
||||
|
@ -310,10 +489,38 @@ class GridFieldController {
|
|||
});
|
||||
}
|
||||
|
||||
Future<Either<Unit, FlowyError>> _loadSorts() async {
|
||||
return _sortFFIService.getAllSorts().then((result) {
|
||||
return result.fold(
|
||||
(sortPBs) {
|
||||
final List<SortInfo> sortInfos = [];
|
||||
for (final sortPB in sortPBs) {
|
||||
final fieldInfo = _findFieldInfo(
|
||||
fieldInfos: fieldInfos,
|
||||
fieldId: sortPB.fieldId,
|
||||
fieldType: sortPB.fieldType,
|
||||
);
|
||||
|
||||
if (fieldInfo != null) {
|
||||
final sortInfo = SortInfo(sortPB: sortPB, fieldInfo: fieldInfo);
|
||||
sortInfos.add(sortInfo);
|
||||
}
|
||||
}
|
||||
|
||||
_updateFieldInfos();
|
||||
_sortNotifier?.sorts = sortInfos;
|
||||
return left(unit);
|
||||
},
|
||||
(err) => right(err),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
void addListener({
|
||||
OnReceiveFields? onFields,
|
||||
OnReceiveUpdateFields? onFieldsUpdated,
|
||||
OnReceiveFilters? onFilters,
|
||||
OnReceiveSorts? onSorts,
|
||||
bool Function()? listenWhen,
|
||||
}) {
|
||||
if (onFieldsUpdated != null) {
|
||||
|
@ -350,10 +557,23 @@ class GridFieldController {
|
|||
_filterCallbacks[onFilters] = callback;
|
||||
_filterNotifier?.addListener(callback);
|
||||
}
|
||||
|
||||
if (onSorts != null) {
|
||||
callback() {
|
||||
if (listenWhen != null && listenWhen() == false) {
|
||||
return;
|
||||
}
|
||||
onSorts(sortInfos);
|
||||
}
|
||||
|
||||
_sortCallbacks[onSorts] = callback;
|
||||
_sortNotifier?.addListener(callback);
|
||||
}
|
||||
}
|
||||
|
||||
void removeListener({
|
||||
OnReceiveFields? onFieldsListener,
|
||||
OnReceiveSorts? onSortsListener,
|
||||
OnReceiveFilters? onFiltersListener,
|
||||
OnReceiveUpdateFields? onChangesetListener,
|
||||
}) {
|
||||
|
@ -369,6 +589,13 @@ class GridFieldController {
|
|||
_filterNotifier?.removeListener(callback);
|
||||
}
|
||||
}
|
||||
|
||||
if (onSortsListener != null) {
|
||||
final callback = _sortCallbacks.remove(onSortsListener);
|
||||
if (callback != null) {
|
||||
_sortNotifier?.removeListener(callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _deleteFields(List<FieldIdPB> deletedFields) {
|
||||
|
@ -425,7 +652,8 @@ class GridFieldController {
|
|||
}
|
||||
}
|
||||
|
||||
class GridRowFieldNotifierImpl extends IGridRowFieldNotifier {
|
||||
class GridRowFieldNotifierImpl extends RowChangesetNotifierForward
|
||||
with RowCacheDelegate {
|
||||
final GridFieldController _cache;
|
||||
OnReceiveUpdateFields? _onChangesetFn;
|
||||
OnReceiveFields? _onFieldFn;
|
||||
|
@ -466,11 +694,13 @@ class GridRowFieldNotifierImpl extends IGridRowFieldNotifier {
|
|||
}
|
||||
}
|
||||
|
||||
FieldInfo? _findFieldInfoForFilter(
|
||||
List<FieldInfo> fieldInfos, FilterPB filter) {
|
||||
FieldInfo? _findFieldInfo({
|
||||
required List<FieldInfo> fieldInfos,
|
||||
required String fieldId,
|
||||
required FieldType fieldType,
|
||||
}) {
|
||||
final fieldIndex = fieldInfos.indexWhere((element) {
|
||||
return element.id == filter.fieldId &&
|
||||
element.fieldType == filter.fieldType;
|
||||
return element.id == fieldId && element.fieldType == fieldType;
|
||||
});
|
||||
if (fieldIndex != -1) {
|
||||
return fieldInfos[fieldIndex];
|
||||
|
@ -485,6 +715,8 @@ class FieldInfo {
|
|||
|
||||
bool _hasFilter = false;
|
||||
|
||||
bool _hasSort = false;
|
||||
|
||||
String get id => _field.id;
|
||||
|
||||
FieldType get fieldType => _field.fieldType;
|
||||
|
@ -529,5 +761,18 @@ class FieldInfo {
|
|||
}
|
||||
}
|
||||
|
||||
bool get canCreateSort {
|
||||
if (_hasSort) return false;
|
||||
|
||||
switch (_field.fieldType) {
|
||||
case FieldType.RichText:
|
||||
case FieldType.Checkbox:
|
||||
case FieldType.Number:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
FieldInfo({required FieldPB field}) : _field = field;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'dart:async';
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import 'package:app_flowy/core/grid_notification.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||
import 'package:flowy_infra/notifier.dart';
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
|
||||
typedef UpdateFieldNotifiedValue = Either<FieldPB, FlowyError>;
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart';
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/grid_entities.pb.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'field_service.freezed.dart';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import 'package:app_flowy/core/grid_notification.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||
import 'package:flowy_infra/notifier.dart';
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
|
||||
typedef UpdateFieldNotifiedValue = Either<GridFieldChangesetPB, FlowyError>;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/date_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/date_type_option_entities.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/multi_select_type_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/multi_select_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'dart:async';
|
||||
import 'select_option_type_option_bloc.dart';
|
||||
import 'type_option_context.dart';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:flowy_sdk/protobuf/flowy-grid/format.pbenum.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/format.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/number_type_option.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import 'package:flowy_sdk/protobuf/flowy-grid/format.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/format.pbenum.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/single_select_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/single_select_type_option.pb.dart';
|
||||
import 'dart:async';
|
||||
import 'package:protobuf/protobuf.dart';
|
||||
import 'select_option_type_option_bloc.dart';
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_type_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/checklist_type_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/checkbox_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/checklist_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/date_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/multi_select_type_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/single_select_type_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/text_type_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/multi_select_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/number_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/single_select_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/text_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/url_type_option.pb.dart';
|
||||
import 'package:protobuf/protobuf.dart';
|
||||
|
||||
import 'type_option_data_controller.dart';
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
|
||||
import 'package:flowy_infra/notifier.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:protobuf/protobuf.dart' hide FieldInfo;
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
|
||||
import 'type_option_context.dart';
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/cell_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
|
||||
class TypeOptionFFIService {
|
||||
final String gridId;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:app_flowy/plugins/grid/presentation/widgets/filter/filter_info.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_filter.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/util.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/checkbox_filter.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/util.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:app_flowy/plugins/grid/presentation/widgets/filter/filter_info.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/checklist_filter.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/util.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/checklist_filter.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/util.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pbserver.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_filter.pbenum.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/checklist_filter.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/date_filter.pbenum.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/number_filter.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option_filter.pbenum.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/text_filter.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pbserver.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/checkbox_filter.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/checklist_filter.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/date_filter.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/number_filter.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/select_option_filter.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/text_filter.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -2,11 +2,11 @@ import 'dart:typed_data';
|
|||
|
||||
import 'package:app_flowy/core/grid_notification.dart';
|
||||
import 'package:flowy_infra/notifier.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/filter_changeset.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/filter_changeset.pb.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/util.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/util.pb.dart';
|
||||
|
||||
typedef UpdateFilterNotifiedValue
|
||||
= Either<FilterChangesetNotificationPB, FlowyError>;
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/checkbox_filter.pbserver.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/checklist_filter.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/date_filter.pbserver.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/number_filter.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option_filter.pbserver.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/setting_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/text_filter.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/util.pb.dart';
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/checkbox_filter.pbserver.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/checklist_filter.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/date_filter.pbserver.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/grid_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/number_filter.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/select_option_filter.pbserver.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/setting_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/text_filter.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/util.pb.dart';
|
||||
import 'package:fixnum/fixnum.dart' as $fixnum;
|
||||
|
||||
class FilterFFIService {
|
||||
|
@ -197,8 +197,6 @@ class FilterFFIService {
|
|||
required String filterId,
|
||||
required FieldType fieldType,
|
||||
}) {
|
||||
TextFilterConditionPB.DoesNotContain.value;
|
||||
|
||||
final deleteFilterPayload = DeleteFilterPayloadPB.create()
|
||||
..fieldId = fieldId
|
||||
..filterId = filterId
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:app_flowy/plugins/grid/presentation/widgets/filter/choicechip/select_option/select_option_loader.dart';
|
||||
import 'package:app_flowy/plugins/grid/presentation/widgets/filter/filter_info.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option_filter.pbserver.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/util.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/select_option_filter.pbserver.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/util.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:app_flowy/plugins/grid/presentation/widgets/filter/choicechip/select_option/select_option_loader.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:app_flowy/plugins/grid/presentation/widgets/filter/filter_info.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/text_filter.pbserver.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/util.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/text_filter.pbserver.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/util.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'grid_accessory_bloc.freezed.dart';
|
||||
|
||||
class GridAccessoryMenuBloc
|
||||
extends Bloc<GridAccessoryMenuEvent, GridAccessoryMenuState> {
|
||||
final String viewId;
|
||||
|
||||
GridAccessoryMenuBloc({required this.viewId})
|
||||
: super(GridAccessoryMenuState.initial(
|
||||
viewId,
|
||||
)) {
|
||||
on<GridAccessoryMenuEvent>(
|
||||
(event, emit) async {
|
||||
event.when(
|
||||
initial: () {},
|
||||
toggleMenu: () {
|
||||
emit(state.copyWith(isVisible: !state.isVisible));
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
class GridAccessoryMenuEvent with _$GridAccessoryMenuEvent {
|
||||
const factory GridAccessoryMenuEvent.initial() = _Initial;
|
||||
const factory GridAccessoryMenuEvent.toggleMenu() = _MenuVisibleChange;
|
||||
}
|
||||
|
||||
@freezed
|
||||
class GridAccessoryMenuState with _$GridAccessoryMenuState {
|
||||
const factory GridAccessoryMenuState({
|
||||
required String viewId,
|
||||
required bool isVisible,
|
||||
}) = _GridAccessoryMenuState;
|
||||
|
||||
factory GridAccessoryMenuState.initial(
|
||||
String viewId,
|
||||
) =>
|
||||
GridAccessoryMenuState(
|
||||
viewId: viewId,
|
||||
isVisible: false,
|
||||
);
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
import 'dart:async';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/protobuf.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'field/field_controller.dart';
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:app_flowy/plugins/grid/presentation/widgets/filter/filter_info.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/grid_entities.pb.dart';
|
||||
import 'dart:async';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'view/grid_view_cache.dart';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/group.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart';
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/grid_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/group.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/row_entities.pb.dart';
|
||||
|
||||
class GridFFIService {
|
||||
final String gridId;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:app_flowy/plugins/grid/application/row/row_service.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
|
|
@ -13,11 +13,11 @@ part 'row_bloc.freezed.dart';
|
|||
|
||||
class RowBloc extends Bloc<RowEvent, RowState> {
|
||||
final RowFFIService _rowService;
|
||||
final GridRowDataController _dataController;
|
||||
final RowDataController _dataController;
|
||||
|
||||
RowBloc({
|
||||
required RowInfo rowInfo,
|
||||
required GridRowDataController dataController,
|
||||
required RowDataController dataController,
|
||||
}) : _rowService = RowFFIService(gridId: rowInfo.gridId),
|
||||
_dataController = dataController,
|
||||
super(RowState.initial(rowInfo, dataController.loadData())) {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import 'dart:collection';
|
||||
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/field/field_controller.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-grid/protobuf.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
|
@ -12,10 +12,13 @@ part 'row_cache.freezed.dart';
|
|||
|
||||
typedef RowUpdateCallback = void Function();
|
||||
|
||||
abstract class IGridRowFieldNotifier {
|
||||
UnmodifiableListView<FieldInfo> get fields;
|
||||
abstract class RowChangesetNotifierForward {
|
||||
void onRowFieldsChanged(VoidCallback callback);
|
||||
void onRowFieldChanged(void Function(FieldInfo) callback);
|
||||
}
|
||||
|
||||
abstract class RowCacheDelegate {
|
||||
UnmodifiableListView<FieldInfo> get fields;
|
||||
void onRowDispose();
|
||||
}
|
||||
|
||||
|
@ -33,8 +36,8 @@ class GridRowCache {
|
|||
final RowList _rowList = RowList();
|
||||
|
||||
final GridCellCache _cellCache;
|
||||
final IGridRowFieldNotifier _fieldNotifier;
|
||||
final _RowChangesetNotifier _rowChangeReasonNotifier;
|
||||
final RowCacheDelegate _delegate;
|
||||
final RowChangesetNotifier _rowChangeReasonNotifier;
|
||||
|
||||
UnmodifiableListView<RowInfo> get visibleRows {
|
||||
var visibleRows = [..._rowList.rows];
|
||||
|
@ -46,10 +49,11 @@ class GridRowCache {
|
|||
GridRowCache({
|
||||
required this.gridId,
|
||||
required this.rows,
|
||||
required IGridRowFieldNotifier notifier,
|
||||
required RowChangesetNotifierForward notifier,
|
||||
required RowCacheDelegate delegate,
|
||||
}) : _cellCache = GridCellCache(gridId: gridId),
|
||||
_rowChangeReasonNotifier = _RowChangesetNotifier(),
|
||||
_fieldNotifier = notifier {
|
||||
_rowChangeReasonNotifier = RowChangesetNotifier(),
|
||||
_delegate = delegate {
|
||||
//
|
||||
notifier.onRowFieldsChanged(() => _rowChangeReasonNotifier
|
||||
.receive(const RowsChangedReason.fieldDidChange()));
|
||||
|
@ -65,7 +69,7 @@ class GridRowCache {
|
|||
}
|
||||
|
||||
Future<void> dispose() async {
|
||||
_fieldNotifier.onRowDispose();
|
||||
_delegate.onRowDispose();
|
||||
_rowChangeReasonNotifier.dispose();
|
||||
await _cellCache.dispose();
|
||||
}
|
||||
|
@ -81,6 +85,23 @@ class GridRowCache {
|
|||
_showRows(changeset.visibleRows);
|
||||
}
|
||||
|
||||
void reorderAllRows(List<String> rowIds) {
|
||||
_rowList.reorderWithRowIds(rowIds);
|
||||
_rowChangeReasonNotifier.receive(const RowsChangedReason.reorderRows());
|
||||
}
|
||||
|
||||
void reorderSingleRow(ReorderSingleRowPB reorderRow) {
|
||||
final rowInfo = _rowList.get(reorderRow.rowId);
|
||||
if (rowInfo != null) {
|
||||
_rowList.moveRow(
|
||||
reorderRow.rowId, reorderRow.oldIndex, reorderRow.newIndex);
|
||||
_rowChangeReasonNotifier.receive(RowsChangedReason.reorderSingleRow(
|
||||
reorderRow,
|
||||
rowInfo,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
void _deleteRows(List<String> deletedRowIds) {
|
||||
for (final rowId in deletedRowIds) {
|
||||
final deletedRow = _rowList.remove(rowId);
|
||||
|
@ -208,7 +229,7 @@ class GridRowCache {
|
|||
GridCellMap _makeGridCells(String rowId, RowPB? row) {
|
||||
// ignore: prefer_collection_literals
|
||||
var cellDataMap = GridCellMap();
|
||||
for (final field in _fieldNotifier.fields) {
|
||||
for (final field in _delegate.fields) {
|
||||
if (field.visibility) {
|
||||
cellDataMap[field.id] = GridCellIdentifier(
|
||||
rowId: rowId,
|
||||
|
@ -247,16 +268,16 @@ class GridRowCache {
|
|||
RowInfo buildGridRow(RowPB rowPB) {
|
||||
return RowInfo(
|
||||
gridId: gridId,
|
||||
fields: _fieldNotifier.fields,
|
||||
fields: _delegate.fields,
|
||||
rowPB: rowPB,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _RowChangesetNotifier extends ChangeNotifier {
|
||||
class RowChangesetNotifier extends ChangeNotifier {
|
||||
RowsChangedReason reason = const InitialListState();
|
||||
|
||||
_RowChangesetNotifier();
|
||||
RowChangesetNotifier();
|
||||
|
||||
void receive(RowsChangedReason newReason) {
|
||||
reason = newReason;
|
||||
|
@ -266,6 +287,8 @@ class _RowChangesetNotifier extends ChangeNotifier {
|
|||
update: (_) => notifyListeners(),
|
||||
fieldDidChange: (_) => notifyListeners(),
|
||||
initial: (_) {},
|
||||
reorderRows: (_) => notifyListeners(),
|
||||
reorderSingleRow: (_) => notifyListeners(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -292,6 +315,9 @@ class RowsChangedReason with _$RowsChangedReason {
|
|||
const factory RowsChangedReason.update(UpdatedIndexMap indexs) = _Update;
|
||||
const factory RowsChangedReason.fieldDidChange() = _FieldDidChange;
|
||||
const factory RowsChangedReason.initial() = InitialListState;
|
||||
const factory RowsChangedReason.reorderRows() = _ReorderRows;
|
||||
const factory RowsChangedReason.reorderSingleRow(
|
||||
ReorderSingleRowPB reorderRow, RowInfo rowInfo) = _ReorderSingleRow;
|
||||
}
|
||||
|
||||
class InsertedIndex {
|
||||
|
|
|
@ -7,13 +7,13 @@ import 'row_cache.dart';
|
|||
|
||||
typedef OnRowChanged = void Function(GridCellMap, RowsChangedReason);
|
||||
|
||||
class GridRowDataController extends GridCellBuilderDelegate {
|
||||
class RowDataController extends GridCellBuilderDelegate {
|
||||
final RowInfo rowInfo;
|
||||
final List<VoidCallback> _onRowChangedListeners = [];
|
||||
final GridFieldController _fieldController;
|
||||
final GridRowCache _rowCache;
|
||||
|
||||
GridRowDataController({
|
||||
RowDataController({
|
||||
required this.rowInfo,
|
||||
required GridFieldController fieldController,
|
||||
required GridRowCache rowCache,
|
||||
|
|
|
@ -7,7 +7,7 @@ import 'row_data_controller.dart';
|
|||
part 'row_detail_bloc.freezed.dart';
|
||||
|
||||
class RowDetailBloc extends Bloc<RowDetailEvent, RowDetailState> {
|
||||
final GridRowDataController dataController;
|
||||
final RowDataController dataController;
|
||||
|
||||
RowDetailBloc({
|
||||
required this.dataController,
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue