mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
Merge branch 'feat/tauri-kanban-fixes' into feat/tauri-grid
This commit is contained in:
commit
8b68b1390c
27
.github/PULL_REQUEST_TEMPLATE/pull_request_template.md
vendored
Normal file
27
.github/PULL_REQUEST_TEMPLATE/pull_request_template.md
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<!---
|
||||||
|
Thank you for submitting a pull request to AppFlowy. The team will dedicate their best efforts to reviewing and approving your pull request. If you have any questions about the project or feedback for us, please join our [Discord](https://discord.gg/wdjWUXXhtw).
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!---
|
||||||
|
If your pull request adds a new feature, please drag and drop a video into this section to showcase what you've done! If not, you may delete this section.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Feature Preview
|
||||||
|
|
||||||
|
<!---
|
||||||
|
List at least one issue here that this PR addresses. If it fixes the issue, please use the [fixes](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/using-keywords-in-issues-and-pull-requests) keyword to close the issue. For example:
|
||||||
|
fixes https://github.com/AppFlowy-IO/AppFlowy/pull/2106
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!---
|
||||||
|
Before you mark this PR ready for review, run through this checklist!
|
||||||
|
-->
|
||||||
|
|
||||||
|
#### PR Checklist
|
||||||
|
|
||||||
|
- [ ] My code adheres to the [AppFlowy Style Guide](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/software-contributions/submitting-code/style-guides)
|
||||||
|
- [ ] I've listed at least one issue that this PR fixes in the description above.
|
||||||
|
- [ ] I've added a test(s) to validate changes in this PR, or this PR only contains semantic changes.
|
||||||
|
- [ ] All existing tests are passing.
|
2
.github/workflows/flutter_ci.yaml
vendored
2
.github/workflows/flutter_ci.yaml
vendored
@ -16,7 +16,7 @@ on:
|
|||||||
- "frontend/**"
|
- "frontend/**"
|
||||||
|
|
||||||
env:
|
env:
|
||||||
FLUTTER_VERSION: "3.3.9"
|
FLUTTER_VERSION: "3.7.5"
|
||||||
RUST_TOOLCHAIN: "1.65"
|
RUST_TOOLCHAIN: "1.65"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
40
.github/workflows/integration_test.yml
vendored
40
.github/workflows/integration_test.yml
vendored
@ -35,7 +35,7 @@ jobs:
|
|||||||
- uses: subosito/flutter-action@v2
|
- uses: subosito/flutter-action@v2
|
||||||
with:
|
with:
|
||||||
channel: "stable"
|
channel: "stable"
|
||||||
flutter-version: "3.3.9"
|
flutter-version: "3.7.5"
|
||||||
cache: true
|
cache: true
|
||||||
|
|
||||||
- name: Cache Cargo
|
- name: Cache Cargo
|
||||||
@ -56,15 +56,16 @@ jobs:
|
|||||||
|
|
||||||
- name: Setup Environment
|
- name: Setup Environment
|
||||||
run: |
|
run: |
|
||||||
|
cargo install --force cargo-make
|
||||||
|
cargo install --force duckscript_cli
|
||||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
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/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 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 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
|
sudo apt-get install keybinder-3.0
|
||||||
elif [ "$RUNNER_OS" == "Windows" ]; then
|
elif [ "$RUNNER_OS" == "Windows" ]; then
|
||||||
vcpkg integrate install
|
vcpkg integrate install
|
||||||
cargo install --force duckscript_cli
|
|
||||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||||
echo 'do nothing'
|
echo 'do nothing'
|
||||||
fi
|
fi
|
||||||
@ -77,17 +78,6 @@ jobs:
|
|||||||
cargo install cargo-make
|
cargo install cargo-make
|
||||||
cargo make appflowy-flutter-deps-tools
|
cargo make appflowy-flutter-deps-tools
|
||||||
|
|
||||||
- name: Build Test lib
|
|
||||||
working-directory: frontend
|
|
||||||
run: |
|
|
||||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
|
||||||
cargo make --profile production-linux-x86_64 appflowy
|
|
||||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
|
||||||
cargo make --profile production-mac-x86_64 appflowy
|
|
||||||
elif [ "$RUNNER_OS" == "Windows" ]; then
|
|
||||||
cargo make --profile production-windows-x86 appflowy
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Config Flutter
|
- name: Config Flutter
|
||||||
run: |
|
run: |
|
||||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||||
@ -99,22 +89,27 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Flutter Code Generation
|
- name: Build Test lib
|
||||||
working-directory: frontend/appflowy_flutter
|
working-directory: frontend
|
||||||
run: |
|
run: |
|
||||||
flutter packages pub get
|
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||||
flutter packages pub run easy_localization:generate -f keys -o locale_keys.g.dart -S assets/translations -s en.json
|
cargo make --profile development-linux-x86_64 appflowy-dev
|
||||||
flutter packages pub run build_runner build --delete-conflicting-outputs
|
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||||
|
cargo make --profile development-mac-x86_64 appflowy-dev
|
||||||
|
elif [ "$RUNNER_OS" == "Windows" ]; then
|
||||||
|
cargo make --profile development-windows-x86 appflowy-dev
|
||||||
|
fi
|
||||||
|
shell: bash
|
||||||
|
|
||||||
- name: Run AppFlowy tests
|
- name: Run AppFlowy tests
|
||||||
working-directory: frontend/appflowy_flutter
|
working-directory: frontend/appflowy_flutter
|
||||||
run: |
|
run: |
|
||||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||||
flutter test integration_test -d Linux --coverage
|
flutter test integration_test/runner.dart -d Linux --coverage
|
||||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||||
flutter test integration_test -d macOS --coverage
|
flutter test integration_test/runner.dart -d macOS --coverage
|
||||||
elif [ "$RUNNER_OS" == "Windows" ]; then
|
elif [ "$RUNNER_OS" == "Windows" ]; then
|
||||||
flutter test integration_test -d Windows --coverage
|
flutter test integration_test/runner.dart -d Windows --coverage
|
||||||
fi
|
fi
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
@ -125,4 +120,3 @@ jobs:
|
|||||||
# env_vars: ${{ matrix.os }}
|
# env_vars: ${{ matrix.os }}
|
||||||
# fail_ci_if_error: true
|
# fail_ci_if_error: true
|
||||||
# verbose: true
|
# verbose: true
|
||||||
|
|
||||||
|
32
.github/workflows/release.yml
vendored
32
.github/workflows/release.yml
vendored
@ -3,10 +3,10 @@ name: release
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
- '*'
|
- "*"
|
||||||
|
|
||||||
env:
|
env:
|
||||||
FLUTTER_VERSION: "3.3.9"
|
FLUTTER_VERSION: "3.7.5"
|
||||||
RUST_TOOLCHAIN: "1.65"
|
RUST_TOOLCHAIN: "1.65"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@ -136,7 +136,11 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
job:
|
job:
|
||||||
- { target: x86_64-apple-darwin, os: macos-10.15, extra-build-args: "" }
|
- {
|
||||||
|
target: x86_64-apple-darwin,
|
||||||
|
os: macos-10.15,
|
||||||
|
extra-build-args: "",
|
||||||
|
}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout source code
|
- name: Checkout source code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
@ -172,7 +176,7 @@ jobs:
|
|||||||
working-directory: frontend
|
working-directory: frontend
|
||||||
run: |
|
run: |
|
||||||
flutter config --enable-macos-desktop
|
flutter config --enable-macos-desktop
|
||||||
cargo make --env APP_VERSION=${{ github.ref_name }} --profile production-mac-x86_64 appflowy
|
dart ./scripts/flutter_release_build/build_flowy.dart . ${{ github.ref_name }}
|
||||||
|
|
||||||
- name: Create macOS dmg
|
- name: Create macOS dmg
|
||||||
run: |
|
run: |
|
||||||
@ -225,9 +229,21 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
job:
|
job:
|
||||||
- { arch: x86_64, target: x86_64-unknown-linux-gnu, os: ubuntu-20.04, extra-build-args: "", flutter_profile: production-linux-x86_64 }
|
- {
|
||||||
|
arch: x86_64,
|
||||||
|
target: x86_64-unknown-linux-gnu,
|
||||||
|
os: ubuntu-20.04,
|
||||||
|
extra-build-args: "",
|
||||||
|
flutter_profile: production-linux-x86_64,
|
||||||
|
}
|
||||||
# - { arch: aarch64, target: aarch64-unknown-linux-gnu, os: ubuntu-20.04, extra-build-args: "", flutter_profile: production-linux-aarch64 }
|
# - { arch: aarch64, target: aarch64-unknown-linux-gnu, os: ubuntu-20.04, extra-build-args: "", flutter_profile: production-linux-aarch64 }
|
||||||
- { arch: x86_64, target: x86_64-unknown-linux-gnu, os: ubuntu-18.04, extra-build-args: "", flutter_profile: production-linux-x86_64}
|
- {
|
||||||
|
arch: x86_64,
|
||||||
|
target: x86_64-unknown-linux-gnu,
|
||||||
|
os: ubuntu-18.04,
|
||||||
|
extra-build-args: "",
|
||||||
|
flutter_profile: production-linux-x86_64,
|
||||||
|
}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout source code
|
- name: Checkout source code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
@ -275,7 +291,7 @@ jobs:
|
|||||||
working-directory: frontend
|
working-directory: frontend
|
||||||
run: |
|
run: |
|
||||||
flutter config --enable-linux-desktop
|
flutter config --enable-linux-desktop
|
||||||
cargo make --env APP_VERSION=${{ github.ref_name }} --profile ${{ matrix.job.flutter_profile}} appflowy
|
dart ./scripts/flutter_release_build/build_flowy.dart . ${{ github.ref_name }}
|
||||||
|
|
||||||
- name: Archive Assert
|
- name: Archive Assert
|
||||||
working-directory: ${{ env.LINUX_APP_RELEASE_PATH }}
|
working-directory: ${{ env.LINUX_APP_RELEASE_PATH }}
|
||||||
@ -361,4 +377,4 @@ jobs:
|
|||||||
- name: Notify Discord
|
- name: Notify Discord
|
||||||
run: |
|
run: |
|
||||||
curl -H "Content-Type: application/json" -d '{"username": "release@appflowy", "content": "🎉 AppFlowy ${{ github.ref_name }} is available. https://github.com/AppFlowy-IO/AppFlowy/releases/tag/'${{ github.ref_name }}'"}' "https://discord.com/api/webhooks/${{ secrets.DISCORD }}"
|
curl -H "Content-Type: application/json" -d '{"username": "release@appflowy", "content": "🎉 AppFlowy ${{ github.ref_name }} is available. https://github.com/AppFlowy-IO/AppFlowy/releases/tag/'${{ github.ref_name }}'"}' "https://discord.com/api/webhooks/${{ secrets.DISCORD }}"
|
||||||
shell: bash
|
shell: bash
|
||||||
|
2
.github/workflows/rust_ci.yaml
vendored
2
.github/workflows/rust_ci.yaml
vendored
@ -20,7 +20,7 @@ on:
|
|||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
RUST_TOOLCHAIN: "1.65"
|
RUST_TOOLCHAIN: "1.65"
|
||||||
FLUTTER_VERSION: "3.3.9"
|
FLUTTER_VERSION: "3.7.5"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-on-ubuntu:
|
test-on-ubuntu:
|
||||||
|
2
.github/workflows/rust_coverage.yml
vendored
2
.github/workflows/rust_coverage.yml
vendored
@ -11,7 +11,7 @@ on:
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
FLUTTER_VERSION: "3.3.9"
|
FLUTTER_VERSION: "3.7.5"
|
||||||
RUST_TOOLCHAIN: "1.65"
|
RUST_TOOLCHAIN: "1.65"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -35,3 +35,5 @@ pubspec.lock
|
|||||||
.githooks/gitlint
|
.githooks/gitlint
|
||||||
.githooks/gitlint.exe
|
.githooks/gitlint.exe
|
||||||
.fvm/
|
.fvm/
|
||||||
|
|
||||||
|
**/AppFlowy-Collab/
|
||||||
|
446
frontend/.vscode/tasks.json
vendored
446
frontend/.vscode/tasks.json
vendored
@ -1,223 +1,225 @@
|
|||||||
{
|
{
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
// https://code.visualstudio.com/docs/editor/tasks
|
// https://code.visualstudio.com/docs/editor/tasks
|
||||||
// https://gist.github.com/deadalusai/9e13e36d61ec7fb72148
|
// https://gist.github.com/deadalusai/9e13e36d61ec7fb72148
|
||||||
// ${workspaceRoot}: the root folder of the team
|
// ${workspaceRoot}: the root folder of the team
|
||||||
// ${file}: the current opened file
|
// ${file}: the current opened file
|
||||||
// ${fileBasename}: the current opened file's basename
|
// ${fileBasename}: the current opened file's basename
|
||||||
// ${fileDirname}: the current opened file's dirname
|
// ${fileDirname}: the current opened file's dirname
|
||||||
// ${fileExtname}: the current opened file's extension
|
// ${fileExtname}: the current opened file's extension
|
||||||
// ${cwd}: the current working directory of the spawned process
|
// ${cwd}: the current working directory of the spawned process
|
||||||
"tasks": [
|
"tasks": [
|
||||||
{
|
{
|
||||||
"label": "AF: Clean + Rebuild All",
|
"label": "AF: Clean + Rebuild All",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"dependsOrder": "sequence",
|
"dependsOrder": "sequence",
|
||||||
"dependsOn": [
|
"dependsOn": [
|
||||||
"AF: Dart Clean",
|
"AF: Dart Clean",
|
||||||
"AF: Flutter Clean",
|
"AF: Flutter Clean",
|
||||||
"AF: Build Appflowy Core",
|
"AF: Build Appflowy Core",
|
||||||
"AF: Flutter Pub Get",
|
"AF: Flutter Pub Get",
|
||||||
"AF: Flutter Package Get",
|
"AF: Flutter Package Get",
|
||||||
"AF: Generate Language Files",
|
"AF: Generate Language Files",
|
||||||
"AF: Generate Freezed Files"
|
"AF: Generate Freezed Files"
|
||||||
],
|
],
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"reveal": "always",
|
"reveal": "always",
|
||||||
"panel": "new"
|
"panel": "new"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "AF: Clean + Rebuild All (Android)",
|
"label": "AF: Clean + Rebuild All (Android)",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"dependsOrder": "sequence",
|
"dependsOrder": "sequence",
|
||||||
"dependsOn": [
|
"dependsOn": [
|
||||||
"AF: Dart Clean",
|
"AF: Dart Clean",
|
||||||
"AF: Flutter Clean",
|
"AF: Flutter Clean",
|
||||||
"AF: Build Appflowy Core_for_android",
|
"AF: Build Appflowy Core_for_android",
|
||||||
"AF: Flutter Pub Get",
|
"AF: Flutter Pub Get",
|
||||||
"AF: Flutter Package Get",
|
"AF: Flutter Package Get",
|
||||||
"AF: Generate Language Files",
|
"AF: Generate Language Files",
|
||||||
"AF: Generate Freezed Files"
|
"AF: Generate Freezed Files"
|
||||||
],
|
],
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"reveal": "always",
|
"reveal": "always",
|
||||||
"panel": "new"
|
"panel": "new"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "AF: Build Appflowy Core_for_android",
|
"label": "AF: Build Appflowy Core_for_android",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "cargo make --profile development-android appflowy-core-dev-android",
|
"command": "cargo make --profile development-android appflowy-core-dev-android",
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"options": {
|
"options": {
|
||||||
"cwd": "${workspaceFolder}"
|
"cwd": "${workspaceFolder}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "AF: Build Appflowy Core",
|
"label": "AF: Build Appflowy Core",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"windows": {
|
"windows": {
|
||||||
"command": "cargo make --profile development-windows-x86 appflowy-core-dev"
|
"command": "cargo make --profile development-windows-x86 appflowy-core-dev"
|
||||||
},
|
},
|
||||||
"linux": {
|
"linux": {
|
||||||
"command": "cargo make --profile \"development-linux-$(uname -m)\" appflowy-core-dev"
|
"command": "cargo make --profile \"development-linux-$(uname -m)\" appflowy-core-dev"
|
||||||
},
|
},
|
||||||
"osx": {
|
"osx": {
|
||||||
"command": "cargo make --profile \"development-mac-$(uname -m)\" appflowy-core-dev"
|
"command": "cargo make --profile \"development-mac-$(uname -m)\" appflowy-core-dev"
|
||||||
},
|
},
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"options": {
|
"options": {
|
||||||
"cwd": "${workspaceFolder}"
|
"cwd": "${workspaceFolder}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "AF: Code Gen",
|
"label": "AF: Code Gen",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"dependsOrder": "sequence",
|
"dependsOrder": "sequence",
|
||||||
"dependsOn": [
|
"dependsOn": [
|
||||||
"AF: Flutter Clean",
|
"AF: Flutter Clean",
|
||||||
"AF: Flutter Pub Get",
|
"AF: Flutter Pub Get",
|
||||||
"AF: Flutter Package Get",
|
"AF: Flutter Package Get",
|
||||||
"AF: Generate Language Files",
|
"AF: Generate Language Files",
|
||||||
"AF: Generate Freezed Files"
|
"AF: Generate Freezed Files"
|
||||||
],
|
],
|
||||||
"group": {
|
"group": {
|
||||||
"kind": "build",
|
"kind": "build",
|
||||||
"isDefault": true
|
"isDefault": true
|
||||||
},
|
},
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"reveal": "always",
|
"reveal": "always",
|
||||||
"panel": "new"
|
"panel": "new"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "AF: Flutter Clean",
|
"label": "AF: Flutter Clean",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "flutter clean",
|
"command": "flutter clean",
|
||||||
"options": {
|
"options": {
|
||||||
"cwd": "${workspaceFolder}/appflowy_flutter"
|
"cwd": "${workspaceFolder}/appflowy_flutter"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "AF: Flutter Pub Get",
|
"label": "AF: Flutter Pub Get",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "flutter pub get",
|
"command": "flutter pub get",
|
||||||
"options": {
|
"options": {
|
||||||
"cwd": "${workspaceFolder}/appflowy_flutter"
|
"cwd": "${workspaceFolder}/appflowy_flutter"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "AF: Flutter Package Get",
|
"label": "AF: Flutter Package Get",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "flutter packages pub get",
|
"command": "flutter packages pub get",
|
||||||
"options": {
|
"options": {
|
||||||
"cwd": "${workspaceFolder}/appflowy_flutter"
|
"cwd": "${workspaceFolder}/appflowy_flutter"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "AF: Generate Freezed Files",
|
"label": "AF: Generate Freezed Files",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "flutter pub run build_runner build --delete-conflicting-outputs",
|
"command": "flutter pub run build_runner build --delete-conflicting-outputs",
|
||||||
"options": {
|
"options": {
|
||||||
"cwd": "${workspaceFolder}/appflowy_flutter"
|
"cwd": "${workspaceFolder}/appflowy_flutter"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "AF: Generate Language Files",
|
"label": "AF: Generate Language Files",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "sh ./scripts/generate_language_files.sh",
|
"command": "sh ./scripts/generate_language_files.sh",
|
||||||
"windows": {
|
"windows": {
|
||||||
"options": {
|
"options": {
|
||||||
"shell": {
|
"shell": {
|
||||||
"executable": "cmd.exe",
|
"executable": "cmd.exe",
|
||||||
"args": [
|
"args": [
|
||||||
"/d",
|
"/d",
|
||||||
"/c",
|
"/c",
|
||||||
".\\scripts\\generate_language_files.cmd"
|
".\\scripts\\generate_language_files.cmd"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"options": {
|
"options": {
|
||||||
"cwd": "${workspaceFolder}"
|
"cwd": "${workspaceFolder}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "AF: Flutter Clean",
|
"label": "AF: Flutter Clean",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "cargo make flutter_clean",
|
"command": "cargo make flutter_clean",
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"options": {
|
"options": {
|
||||||
"cwd": "${workspaceFolder}"
|
"cwd": "${workspaceFolder}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "AF: flutter build aar",
|
"label": "AF: flutter build aar",
|
||||||
"type": "flutter",
|
"type": "flutter",
|
||||||
"command": "flutter",
|
"command": "flutter",
|
||||||
"args": [
|
"args": [
|
||||||
"build",
|
"build",
|
||||||
"aar"
|
"aar"
|
||||||
],
|
],
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"problemMatcher": [],
|
"problemMatcher": [],
|
||||||
"detail": "appflowy_flutter"
|
"detail": "appflowy_flutter"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "AF: Tauri UI Dev",
|
"label": "AF: Tauri UI Dev",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"isBackground": true,
|
"isBackground": true,
|
||||||
"command": "yarn",
|
"command": "yarn",
|
||||||
"args": ["dev"],
|
"args": [
|
||||||
"options": {
|
"dev"
|
||||||
"cwd": "${workspaceFolder}/appflowy_tauri"
|
],
|
||||||
}
|
"options": {
|
||||||
},
|
"cwd": "${workspaceFolder}/appflowy_tauri"
|
||||||
{
|
}
|
||||||
"label": "AF: Tauri UI Build",
|
},
|
||||||
"type": "shell",
|
{
|
||||||
"command": "npm run build",
|
"label": "AF: Tauri UI Build",
|
||||||
"options": {
|
"type": "shell",
|
||||||
"cwd": "${workspaceFolder}/appflowy_tauri"
|
"command": "npm run build",
|
||||||
}
|
"options": {
|
||||||
},
|
"cwd": "${workspaceFolder}/appflowy_tauri"
|
||||||
{
|
}
|
||||||
"label": "AF: Tauri Dev",
|
},
|
||||||
"type": "shell",
|
{
|
||||||
"command": "npm run tauri:dev",
|
"label": "AF: Tauri Dev",
|
||||||
"options": {
|
"type": "shell",
|
||||||
"cwd": "${workspaceFolder}/appflowy_tauri"
|
"command": "npm run tauri:dev",
|
||||||
}
|
"options": {
|
||||||
},
|
"cwd": "${workspaceFolder}/appflowy_tauri"
|
||||||
{
|
}
|
||||||
"label": "AF: Tauri Clean",
|
},
|
||||||
"type": "shell",
|
{
|
||||||
"command": "cargo make tauri_clean",
|
"label": "AF: Tauri Clean",
|
||||||
"options": {
|
"type": "shell",
|
||||||
"cwd": "${workspaceFolder}"
|
"command": "cargo make tauri_clean",
|
||||||
}
|
"options": {
|
||||||
},
|
"cwd": "${workspaceFolder}"
|
||||||
{
|
}
|
||||||
"label": "AF: Tauri Clean + Dev",
|
},
|
||||||
"type": "shell",
|
{
|
||||||
"dependsOrder": "sequence",
|
"label": "AF: Tauri Clean + Dev",
|
||||||
"dependsOn": [
|
"type": "shell",
|
||||||
"AF: Tauri Clean",
|
"dependsOrder": "sequence",
|
||||||
"AF: Tauri UI Dev"
|
"dependsOn": [
|
||||||
],
|
"AF: Tauri Clean",
|
||||||
"options": {
|
"AF: Tauri UI Dev"
|
||||||
"cwd": "${workspaceFolder}"
|
],
|
||||||
}
|
"options": {
|
||||||
},
|
"cwd": "${workspaceFolder}"
|
||||||
{
|
}
|
||||||
"label": "AF: Tauri ESLint",
|
},
|
||||||
"type": "shell",
|
{
|
||||||
"command": "npx eslint --fix src",
|
"label": "AF: Tauri ESLint",
|
||||||
"options": {
|
"type": "shell",
|
||||||
"cwd": "${workspaceFolder}/appflowy_tauri"
|
"command": "npx eslint --fix src",
|
||||||
}
|
"options": {
|
||||||
},
|
"cwd": "${workspaceFolder}/appflowy_tauri"
|
||||||
]
|
}
|
||||||
}
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
4
frontend/appflowy_flutter/.gitignore
vendored
4
frontend/appflowy_flutter/.gitignore
vendored
@ -40,7 +40,7 @@ lib/generated_plugin_registrant.dart
|
|||||||
lib/generated/
|
lib/generated/
|
||||||
|
|
||||||
# Freezed generated files
|
# Freezed generated files
|
||||||
*.g.dart
|
*.g.dart
|
||||||
*.freezed.dart
|
*.freezed.dart
|
||||||
|
|
||||||
# Symbolication related
|
# Symbolication related
|
||||||
@ -67,4 +67,4 @@ windows/flutter/dart_ffi/
|
|||||||
**/**/*.so
|
**/**/*.so
|
||||||
**/**/Brewfile.lock.json
|
**/**/Brewfile.lock.json
|
||||||
**/.sandbox
|
**/.sandbox
|
||||||
**/.vscode/
|
**/.vscode/
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<h1 align="center" style="margin:0"> AppFlowy_Flutter</h1>
|
<h1 align="center" style="margin:0"> AppFlowy_Flutter</h1>
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<img src="https://img.shields.io/badge/Flutter-v3.3.10-blue"/>
|
<img src="https://img.shields.io/badge/Flutter-v3.7.5-blue"/>
|
||||||
<img src="https://img.shields.io/badge/Rust-v1.65-orange"/>
|
<img src="https://img.shields.io/badge/Rust-v1.65-orange"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -9,13 +9,16 @@
|
|||||||
This Repository contains the codebase for the frontend of the application, currently we use Flutter as our frontend framework.
|
This Repository contains the codebase for the frontend of the application, currently we use Flutter as our frontend framework.
|
||||||
|
|
||||||
### Platforms Supported Using Flutter 💻
|
### Platforms Supported Using Flutter 💻
|
||||||
|
|
||||||
- Linux
|
- Linux
|
||||||
- macOS
|
- macOS
|
||||||
- Windows
|
- Windows
|
||||||
> We later expect to extend support to Android and iOS devices using Flutter.
|
> We later expect to extend support to Android and iOS devices using Flutter.
|
||||||
|
|
||||||
### Am I Eligible to Contribute?
|
### Am I Eligible to Contribute?
|
||||||
|
|
||||||
Yes! You are eligible to contribute, check out the ways in which you can [contribute to AppFlowy](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/contributing-to-appflowy). Some of the ways in which you can contribute are:
|
Yes! You are eligible to contribute, check out the ways in which you can [contribute to AppFlowy](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/contributing-to-appflowy). Some of the ways in which you can contribute are:
|
||||||
|
|
||||||
- Non-Coding Contributions
|
- Non-Coding Contributions
|
||||||
- Documentation
|
- Documentation
|
||||||
- Feature Requests and Feedbacks
|
- Feature Requests and Feedbacks
|
||||||
@ -23,26 +26,27 @@ Yes! You are eligible to contribute, check out the ways in which you can [contri
|
|||||||
- Improve Translations
|
- Improve Translations
|
||||||
- Coding Contributions
|
- Coding Contributions
|
||||||
|
|
||||||
|
|
||||||
To contribute to `AppFlowy_Flutter` codebase specifically (coding contribution) we suggest you to have basic knowledge of Flutter. In case you are new to Flutter, we may suggest you to learn the basics and then try to contribute, get started with Flutter [here](https://flutter.dev/docs/get-started/codelab).
|
To contribute to `AppFlowy_Flutter` codebase specifically (coding contribution) we suggest you to have basic knowledge of Flutter. In case you are new to Flutter, we may suggest you to learn the basics and then try to contribute, get started with Flutter [here](https://flutter.dev/docs/get-started/codelab).
|
||||||
|
|
||||||
### What OS Should I Use for Development?
|
### What OS Should I Use for Development?
|
||||||
|
|
||||||
We support all OS for Development i.e Linux, macOS and Windows. However, most of us promote macOS and Linux over Windows. We have detailed [docs](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/software-contributions/environment-setup) on How to Setup `AppFlowy_Flutter` in your local system in each OS.
|
We support all OS for Development i.e Linux, macOS and Windows. However, most of us promote macOS and Linux over Windows. We have detailed [docs](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/software-contributions/environment-setup) on How to Setup `AppFlowy_Flutter` in your local system in each OS.
|
||||||
|
|
||||||
|
|
||||||
### Getting Started ❇
|
### Getting Started ❇
|
||||||
|
|
||||||
We have a detailed documentation, on how to [get started](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/contributing-to-appflowy) with the project, and make your first contribution. However, we do have some specific picks for you.
|
We have a detailed documentation, on how to [get started](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/contributing-to-appflowy) with the project, and make your first contribution. However, we do have some specific picks for you.
|
||||||
|
|
||||||
- [Code Architecture](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/architecture/frontend/frontend/codemap)
|
- [Code Architecture](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/architecture/frontend/frontend/codemap)
|
||||||
- [Making Your First PR](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/software-contributions/submitting-code/submitting-your-first-pull-request)
|
- [Making Your First PR](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/software-contributions/submitting-code/submitting-your-first-pull-request)
|
||||||
- [The Style Guide](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/software-contributions/submitting-code/style-guides)
|
- [The Style Guide](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/software-contributions/submitting-code/style-guides)
|
||||||
- [How to run/debug the application](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/software-contributions/launcher-and-tasks)
|
- [How to run/debug the application](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/software-contributions/launcher-and-tasks)
|
||||||
|
|
||||||
|
|
||||||
### Need Help?
|
### Need Help?
|
||||||
|
|
||||||
- New to GitHub? Follow [these](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/software-contributions/submitting-code/setting-up-your-repositories) steps to get started
|
- New to GitHub? Follow [these](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/software-contributions/submitting-code/setting-up-your-repositories) steps to get started
|
||||||
- Stuck Somewhere? Join the [Discord](https://discord.gg/9Q2xaN37tV) Group and we are there to help you!
|
- Stuck Somewhere? Join the [Discord](https://discord.gg/9Q2xaN37tV) Group and we are there to help you!
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
## release check
|
## release check
|
||||||
1. [entitlements](https://flutter.dev/desktop#setting-up-entitlements)
|
1. [entitlements](https://flutter.dev/desktop#setting-up-entitlements)
|
||||||
2. [symbols stripped](https://flutter.dev/docs/development/platform-integration/c-interop) -->
|
2. [symbols stripped](https://flutter.dev/docs/development/platform-integration/c-interop) -->
|
||||||
|
@ -1,5 +1,17 @@
|
|||||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg
|
||||||
<rect width="16" height="16" rx="8" fill="#00BCF0"/>
|
width="16"
|
||||||
<rect x="7.5" y="4" width="1" height="8" rx="0.5" fill="white"/>
|
height="16"
|
||||||
<rect x="12" y="7.5" width="1" height="8" rx="0.5" transform="rotate(90 12 7.5)" fill="white"/>
|
viewBox="0 0 16 16"
|
||||||
|
fill="none"
|
||||||
|
version="1.1"
|
||||||
|
id="svg808"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs812" />
|
||||||
|
<path
|
||||||
|
id="path930"
|
||||||
|
style="fill:#00bcf0;fill-opacity:1"
|
||||||
|
transform="rotate(-90)"
|
||||||
|
d="M 0,7.9238281 A 8,8 0 0 0 -8.0585938,0 8,8 0 0 0 -16,8.0390625 8,8 0 0 0 -7.9804688,16 8,8 0 0 0 0,8 Z M -4,8 c 0,0.2769988 -0.2230012,0.5 -0.5,0.5 h -3 v 3 c 0,0.277 -0.2230012,0.5 -0.5,0.5 -0.2769988,0 -0.5,-0.223 -0.5,-0.5 v -3 h -3 C -11.777,8.5 -12,8.2769988 -12,8 c 0,-0.2769988 0.223,-0.5 0.5,-0.5 h 3 v -3 C -8.5,4.2230012 -8.2769988,4 -8,4 c 0.2769988,0 0.5,0.2230012 0.5,0.5 v 3 h 3 C -4.2230012,7.5 -4,7.7230012 -4,8 Z" />
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 317 B After Width: | Height: | Size: 766 B |
@ -1,5 +0,0 @@
|
|||||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<rect width="16" height="16" rx="8" fill="#00BCF0"/>
|
|
||||||
<rect x="7.5" y="4" width="1" height="8" rx="0.5" fill="#131720"/>
|
|
||||||
<rect x="12" y="7.5" width="1" height="8" rx="0.5" transform="rotate(90 12 7.5)" fill="#131720"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 321 B |
BIN
frontend/appflowy_flutter/assets/test/workspaces/board.zip
Normal file
BIN
frontend/appflowy_flutter/assets/test/workspaces/board.zip
Normal file
Binary file not shown.
Binary file not shown.
@ -326,7 +326,8 @@
|
|||||||
"checklist": {
|
"checklist": {
|
||||||
"panelTitle": "Add an item"
|
"panelTitle": "Add an item"
|
||||||
},
|
},
|
||||||
"menuName": "Grid"
|
"menuName": "Grid",
|
||||||
|
"referencedGridPrefix": "View of"
|
||||||
},
|
},
|
||||||
"document": {
|
"document": {
|
||||||
"menuName": "Document",
|
"menuName": "Document",
|
||||||
@ -390,7 +391,8 @@
|
|||||||
"column": {
|
"column": {
|
||||||
"create_new_card": "New"
|
"create_new_card": "New"
|
||||||
},
|
},
|
||||||
"menuName": "Board"
|
"menuName": "Board",
|
||||||
|
"referencedBoardPrefix": "View of"
|
||||||
},
|
},
|
||||||
"calendar": {
|
"calendar": {
|
||||||
"menuName": "Calendar",
|
"menuName": "Calendar",
|
||||||
|
43
frontend/appflowy_flutter/integration_test/board_test.dart
Normal file
43
frontend/appflowy_flutter/integration_test/board_test.dart
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import 'package:appflowy_board/appflowy_board.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:integration_test/integration_test.dart';
|
||||||
|
import 'util/util.dart';
|
||||||
|
|
||||||
|
/// Integration tests for an empty board. The [TestWorkspaceService] will load
|
||||||
|
/// a workspace from an empty board `assets/test/workspaces/board.zip` for all
|
||||||
|
/// tests.
|
||||||
|
///
|
||||||
|
/// To create another integration test with a preconfigured workspace.
|
||||||
|
/// Use the following steps.
|
||||||
|
/// 1. Create a new workspace from the AppFlowy launch screen.
|
||||||
|
/// 2. Modify the workspace until it is suitable as the starting point for
|
||||||
|
/// the integration test you need to land.
|
||||||
|
/// 3. Use a zip utility program to zip the workspace folder that you created.
|
||||||
|
/// 4. Add the zip file under `assets/test/workspaces/`
|
||||||
|
/// 5. Add a new enumeration to [TestWorkspace] in `integration_test/utils/data.dart`.
|
||||||
|
/// For example, if you added a workspace called `empty_calendar.zip`,
|
||||||
|
/// then [TestWorkspace] should have the following value:
|
||||||
|
/// ```dart
|
||||||
|
/// enum TestWorkspace {
|
||||||
|
/// board('board'),
|
||||||
|
/// empty_calendar('empty_calendar');
|
||||||
|
///
|
||||||
|
/// /* code */
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
/// 6. Double check that the .zip file that you added is included as an asset in
|
||||||
|
/// the pubspec.yaml file under appflowy_flutter.
|
||||||
|
void main() {
|
||||||
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
const service = TestWorkspaceService(TestWorkspace.board);
|
||||||
|
|
||||||
|
group('board', () {
|
||||||
|
setUpAll(() async => await service.setUpAll());
|
||||||
|
setUp(() async => await service.setUp());
|
||||||
|
|
||||||
|
testWidgets('integration test unzips the proper workspace and loads it correctly.', (tester) async {
|
||||||
|
await tester.initializeAppFlowy();
|
||||||
|
expect(find.byType(AppFlowyBoard), findsOneWidget);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,120 @@
|
|||||||
|
import 'package:appflowy/plugins/document/presentation/plugins/base/built_in_page_widget.dart';
|
||||||
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:integration_test/integration_test.dart';
|
||||||
|
import 'util/keyboard.dart';
|
||||||
|
import 'util/util.dart';
|
||||||
|
|
||||||
|
/// Integration tests for an empty document. The [TestWorkspaceService] will load a workspace from an empty document `assets/test/workspaces/empty_document.zip` for all tests.
|
||||||
|
///
|
||||||
|
/// To create another integration test with a preconfigured workspace. Use the following steps:
|
||||||
|
/// 1. Create a new workspace from the AppFlowy launch screen.
|
||||||
|
/// 2. Modify the workspace until it is suitable as the starting point for the integration test you need to land.
|
||||||
|
/// 3. Use a zip utility program to zip the workspace folder that you created.
|
||||||
|
/// 4. Add the zip file under `assets/test/workspaces/`
|
||||||
|
/// 5. Add a new enumeration to [TestWorkspace] in `integration_test/utils/data.dart`. For example, if you added a workspace called `empty_calendar.zip`, then [TestWorkspace] should have the following value:
|
||||||
|
/// ```dart
|
||||||
|
/// enum TestWorkspace {
|
||||||
|
/// board('board'),
|
||||||
|
/// empty_calendar('empty_calendar');
|
||||||
|
///
|
||||||
|
/// /* code */
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
/// 6. Double check that the .zip file that you added is included as an asset in the pubspec.yaml file under appflowy_flutter.
|
||||||
|
void main() {
|
||||||
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
const service = TestWorkspaceService(TestWorkspace.emptyDocument);
|
||||||
|
|
||||||
|
group('Tests on a workspace with only an empty document', () {
|
||||||
|
setUpAll(() async => await service.setUpAll());
|
||||||
|
setUp(() async => await service.setUp());
|
||||||
|
|
||||||
|
testWidgets('/board shortcut creates a new board and view of the board', (tester) async {
|
||||||
|
await tester.initializeAppFlowy();
|
||||||
|
|
||||||
|
// Needs tab to obtain focus for the app flowy editor.
|
||||||
|
// by default the tap appears at the center of the widget.
|
||||||
|
final Finder editor = find.byType(AppFlowyEditor);
|
||||||
|
await tester.tap(editor);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// tester.sendText() cannot be used since the editor
|
||||||
|
// does not contain any EditableText widgets.
|
||||||
|
// to interact with the app during an integration test,
|
||||||
|
// simulate physical keyboard events.
|
||||||
|
await FlowyTestKeyboard.simulateKeyDownEvent([
|
||||||
|
LogicalKeyboardKey.slash,
|
||||||
|
LogicalKeyboardKey.keyB,
|
||||||
|
LogicalKeyboardKey.keyO,
|
||||||
|
LogicalKeyboardKey.keyA,
|
||||||
|
LogicalKeyboardKey.keyR,
|
||||||
|
LogicalKeyboardKey.keyD,
|
||||||
|
LogicalKeyboardKey.arrowDown,
|
||||||
|
], tester: tester);
|
||||||
|
|
||||||
|
// Checks whether the options in the selection menu
|
||||||
|
// for /board exist.
|
||||||
|
expect(find.byType(SelectionMenuItemWidget), findsAtLeastNWidgets(2));
|
||||||
|
|
||||||
|
// Finalizes the slash command that creates the board.
|
||||||
|
await FlowyTestKeyboard.simulateKeyDownEvent([
|
||||||
|
LogicalKeyboardKey.enter,
|
||||||
|
], tester: tester);
|
||||||
|
|
||||||
|
// Checks whether new board is referenced and properly on the page.
|
||||||
|
expect(find.byType(BuiltInPageWidget), findsOneWidget);
|
||||||
|
|
||||||
|
// Checks whether the new database was created
|
||||||
|
const newBoardLabel = "Untitled";
|
||||||
|
expect(find.text(newBoardLabel), findsOneWidget);
|
||||||
|
|
||||||
|
// Checks whether a view of the database was created
|
||||||
|
const viewOfBoardLabel = "View of Untitled";
|
||||||
|
expect(find.text(viewOfBoardLabel), findsNWidgets(2));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('/grid shortcut creates a new grid and view of the grid', (tester) async {
|
||||||
|
await tester.initializeAppFlowy();
|
||||||
|
|
||||||
|
// Needs tab to obtain focus for the app flowy editor.
|
||||||
|
// by default the tap appears at the center of the widget.
|
||||||
|
final Finder editor = find.byType(AppFlowyEditor);
|
||||||
|
await tester.tap(editor);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// tester.sendText() cannot be used since the editor
|
||||||
|
// does not contain any EditableText widgets.
|
||||||
|
// to interact with the app during an integration test,
|
||||||
|
// simulate physical keyboard events.
|
||||||
|
await FlowyTestKeyboard.simulateKeyDownEvent([
|
||||||
|
LogicalKeyboardKey.slash,
|
||||||
|
LogicalKeyboardKey.keyG,
|
||||||
|
LogicalKeyboardKey.keyR,
|
||||||
|
LogicalKeyboardKey.keyI,
|
||||||
|
LogicalKeyboardKey.keyD,
|
||||||
|
LogicalKeyboardKey.arrowDown,
|
||||||
|
], tester: tester);
|
||||||
|
|
||||||
|
// Checks whether the options in the selection menu
|
||||||
|
// for /grid exist.
|
||||||
|
expect(find.byType(SelectionMenuItemWidget), findsAtLeastNWidgets(2));
|
||||||
|
|
||||||
|
// Finalizes the slash command that creates the board.
|
||||||
|
await simulateKeyDownEvent(LogicalKeyboardKey.enter);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Checks whether new board is referenced and properly on the page.
|
||||||
|
expect(find.byType(BuiltInPageWidget), findsOneWidget);
|
||||||
|
|
||||||
|
// Checks whether the new database was created
|
||||||
|
const newTableLabel = "Untitled";
|
||||||
|
expect(find.text(newTableLabel), findsOneWidget);
|
||||||
|
|
||||||
|
// Checks whether a view of the database was created
|
||||||
|
const viewOfTableLabel = "View of Untitled";
|
||||||
|
expect(find.text(viewOfTableLabel), findsNWidgets(2));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
19
frontend/appflowy_flutter/integration_test/runner.dart
Normal file
19
frontend/appflowy_flutter/integration_test/runner.dart
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import 'package:integration_test/integration_test.dart';
|
||||||
|
|
||||||
|
import 'board_test.dart' as board_test;
|
||||||
|
import 'switch_folder_test.dart' as switch_folder_test;
|
||||||
|
import 'empty_document_test.dart' as empty_document_test;
|
||||||
|
|
||||||
|
/// The main task runner for all integration tests in AppFlowy.
|
||||||
|
///
|
||||||
|
/// Having a single entrypoint for integration tests is necessary due to an
|
||||||
|
/// [issue caused by switching files with integration testing](https://github.com/flutter/flutter/issues/101031).
|
||||||
|
/// If flutter/flutter#101031 is resolved, this file can be removed completely.
|
||||||
|
/// Once removed, the integration_test.yaml must be updated to exclude this as
|
||||||
|
/// as the test target.
|
||||||
|
void main() {
|
||||||
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
switch_folder_test.main();
|
||||||
|
board_test.main();
|
||||||
|
empty_document_test.main();
|
||||||
|
}
|
@ -1,10 +1,5 @@
|
|||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
|
||||||
import 'package:appflowy/plugins/document/presentation/plugins/base/built_in_page_widget.dart';
|
|
||||||
import 'package:appflowy/user/presentation/folder/folder_widget.dart';
|
import 'package:appflowy/user/presentation/folder/folder_widget.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
|
||||||
import 'package:flowy_infra_ui/style_widget/text_field.dart';
|
import 'package:flowy_infra_ui/style_widget/text_field.dart';
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:integration_test/integration_test.dart';
|
import 'package:integration_test/integration_test.dart';
|
||||||
|
|
||||||
@ -162,135 +157,5 @@ void main() {
|
|||||||
await TestFolder.currentLocation(),
|
await TestFolder.currentLocation(),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('/board shortcut creates a new board', (tester) async {
|
|
||||||
const folderName = 'appflowy';
|
|
||||||
await TestFolder.cleanTestLocation(folderName);
|
|
||||||
await TestFolder.setTestLocation(folderName);
|
|
||||||
|
|
||||||
await tester.initializeAppFlowy();
|
|
||||||
|
|
||||||
// tap open button
|
|
||||||
await mockGetDirectoryPath(folderName);
|
|
||||||
await tester.tapOpenFolderButton();
|
|
||||||
|
|
||||||
await tester.wait(1000);
|
|
||||||
await tester.expectToSeeWelcomePage();
|
|
||||||
|
|
||||||
final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
|
||||||
|
|
||||||
// Necessary for being able to enterText when not in debug mode
|
|
||||||
binding.testTextInput.register();
|
|
||||||
|
|
||||||
// Needs tab to obtain focus for the app flowy editor.
|
|
||||||
// by default the tap appears at the center of the widget.
|
|
||||||
final Finder editor = find.byType(AppFlowyEditor);
|
|
||||||
await tester.tap(editor);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
|
|
||||||
// tester.sendText() cannot be used since the editor
|
|
||||||
// does not contain any EditableText widgets.
|
|
||||||
// to interact with the app during an integration test,
|
|
||||||
// simulate physical keyboard events.
|
|
||||||
await simulateKeyDownEvent(LogicalKeyboardKey.enter);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
await simulateKeyDownEvent(LogicalKeyboardKey.enter);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
await simulateKeyDownEvent(LogicalKeyboardKey.arrowLeft);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
await simulateKeyDownEvent(LogicalKeyboardKey.slash);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
await simulateKeyDownEvent(LogicalKeyboardKey.keyB);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
await simulateKeyDownEvent(LogicalKeyboardKey.keyO);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
await simulateKeyDownEvent(LogicalKeyboardKey.keyA);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
await simulateKeyDownEvent(LogicalKeyboardKey.keyR);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
await simulateKeyDownEvent(LogicalKeyboardKey.keyD);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
await simulateKeyDownEvent(LogicalKeyboardKey.arrowDown);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
|
|
||||||
// Checks whether the options in the selection menu
|
|
||||||
// for /board exist.
|
|
||||||
expect(find.byType(SelectionMenuItemWidget), findsAtLeastNWidgets(2));
|
|
||||||
|
|
||||||
// Finalizes the slash command that creates the board.
|
|
||||||
await simulateKeyDownEvent(LogicalKeyboardKey.enter);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
|
|
||||||
// Checks whether new board is referenced and properly on the page.
|
|
||||||
expect(find.byType(BuiltInPageWidget), findsOneWidget);
|
|
||||||
|
|
||||||
// Checks whether the new board is in the side bar.
|
|
||||||
final sidebarLabel = LocaleKeys.newPageText.tr();
|
|
||||||
expect(find.text(sidebarLabel), findsOneWidget);
|
|
||||||
});
|
|
||||||
|
|
||||||
testWidgets('/grid shortcut creates a new grid', (tester) async {
|
|
||||||
const folderName = 'appflowy';
|
|
||||||
await TestFolder.cleanTestLocation(folderName);
|
|
||||||
await TestFolder.setTestLocation(folderName);
|
|
||||||
|
|
||||||
await tester.initializeAppFlowy();
|
|
||||||
|
|
||||||
// tap open button
|
|
||||||
await mockGetDirectoryPath(folderName);
|
|
||||||
await tester.tapOpenFolderButton();
|
|
||||||
|
|
||||||
await tester.wait(1000);
|
|
||||||
await tester.expectToSeeWelcomePage();
|
|
||||||
|
|
||||||
final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
|
||||||
|
|
||||||
// Necessary for being able to enterText when not in debug mode
|
|
||||||
binding.testTextInput.register();
|
|
||||||
|
|
||||||
// Needs tab to obtain focus for the app flowy editor.
|
|
||||||
// by default the tap appears at the center of the widget.
|
|
||||||
final Finder editor = find.byType(AppFlowyEditor);
|
|
||||||
await tester.tap(editor);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
|
|
||||||
// tester.sendText() cannot be used since the editor
|
|
||||||
// does not contain any EditableText widgets.
|
|
||||||
// to interact with the app during an integration test,
|
|
||||||
// simulate physical keyboard events.
|
|
||||||
await simulateKeyDownEvent(LogicalKeyboardKey.enter);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
await simulateKeyDownEvent(LogicalKeyboardKey.enter);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
await simulateKeyDownEvent(LogicalKeyboardKey.arrowLeft);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
await simulateKeyDownEvent(LogicalKeyboardKey.slash);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
await simulateKeyDownEvent(LogicalKeyboardKey.keyG);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
await simulateKeyDownEvent(LogicalKeyboardKey.keyR);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
await simulateKeyDownEvent(LogicalKeyboardKey.keyI);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
await simulateKeyDownEvent(LogicalKeyboardKey.keyD);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
await simulateKeyDownEvent(LogicalKeyboardKey.arrowDown);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
|
|
||||||
// Checks whether the options in the selection menu
|
|
||||||
// for /grid exist.
|
|
||||||
expect(find.byType(SelectionMenuItemWidget), findsAtLeastNWidgets(2));
|
|
||||||
|
|
||||||
// Finalizes the slash command that creates the board.
|
|
||||||
await simulateKeyDownEvent(LogicalKeyboardKey.enter);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
|
|
||||||
// Checks whether new board is referenced and properly on the page.
|
|
||||||
expect(find.byType(BuiltInPageWidget), findsOneWidget);
|
|
||||||
|
|
||||||
// Checks whether the new board is in the side bar.
|
|
||||||
final sidebarLabel = LocaleKeys.newPageText.tr();
|
|
||||||
expect(find.text(sidebarLabel), findsOneWidget);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
66
frontend/appflowy_flutter/integration_test/util/data.dart
Normal file
66
frontend/appflowy_flutter/integration_test/util/data.dart
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:appflowy/workspace/application/settings/settings_location_cubit.dart';
|
||||||
|
import 'package:archive/archive_io.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:path/path.dart' as p;
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
enum TestWorkspace {
|
||||||
|
board("board"),
|
||||||
|
emptyDocument("empty_document");
|
||||||
|
|
||||||
|
const TestWorkspace(this._name);
|
||||||
|
|
||||||
|
final String _name;
|
||||||
|
|
||||||
|
Future<File> get zip async {
|
||||||
|
final Directory parent = await TestWorkspace._parent;
|
||||||
|
final File out = File(p.join(parent.path, '$_name.zip'));
|
||||||
|
if (await out.exists()) return out;
|
||||||
|
await out.create();
|
||||||
|
final ByteData data = await rootBundle.load(_asset);
|
||||||
|
await out.writeAsBytes(data.buffer.asUint8List());
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Directory> get root async {
|
||||||
|
final Directory parent = await TestWorkspace._parent;
|
||||||
|
return Directory(p.join(parent.path, _name));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<Directory> get _parent async {
|
||||||
|
final Directory root = await getTemporaryDirectory();
|
||||||
|
if (await root.exists()) return root;
|
||||||
|
await root.create();
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
String get _asset => 'assets/test/workspaces/$_name.zip';
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestWorkspaceService {
|
||||||
|
const TestWorkspaceService(this.workspace);
|
||||||
|
|
||||||
|
final TestWorkspace workspace;
|
||||||
|
|
||||||
|
/// Instructs the application to read workspace data from the workspace found under this [TestWorkspace]'s path.
|
||||||
|
Future<void> setUpAll() async {
|
||||||
|
SharedPreferences.setMockInitialValues(
|
||||||
|
{
|
||||||
|
kSettingsLocationDefaultLocation:
|
||||||
|
await workspace.root.then((value) => value.path),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Workspaces that are checked into source are compressed. [TestWorkspaceService.setUp()] decompresses the file into an ephemeral directory that will be ignored by source control.
|
||||||
|
Future<void> setUp() async {
|
||||||
|
final inputStream =
|
||||||
|
InputFileStream(await workspace.zip.then((value) => value.path));
|
||||||
|
final archive = ZipDecoder().decodeBuffer(inputStream);
|
||||||
|
extractArchiveToDisk(
|
||||||
|
archive, await TestWorkspace._parent.then((value) => value.path));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart' as flutter_test;
|
||||||
|
|
||||||
|
class FlowyTestKeyboard {
|
||||||
|
static Future<void> simulateKeyDownEvent(List<LogicalKeyboardKey> keys,
|
||||||
|
{required flutter_test.WidgetTester tester}) async {
|
||||||
|
for (final LogicalKeyboardKey key in keys) {
|
||||||
|
await flutter_test.simulateKeyDownEvent(key);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
export 'base.dart';
|
export 'base.dart';
|
||||||
export 'launch.dart';
|
export 'launch.dart';
|
||||||
export 'settings.dart';
|
export 'settings.dart';
|
||||||
|
export 'data.dart';
|
||||||
|
@ -3,7 +3,7 @@ import 'dart:typed_data';
|
|||||||
import 'package:appflowy_backend/protobuf/flowy-notification/protobuf.dart';
|
import 'package:appflowy_backend/protobuf/flowy-notification/protobuf.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/notification.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/notification.pb.dart';
|
||||||
import 'package:appflowy_backend/rust_stream.dart';
|
import 'package:appflowy_backend/rust_stream.dart';
|
||||||
|
|
||||||
import 'notification_helper.dart';
|
import 'notification_helper.dart';
|
||||||
|
@ -9,7 +9,7 @@ import 'package:appflowy_backend/protobuf/flowy-database/group_changeset.pb.dart
|
|||||||
import 'package:appflowy_backend/protobuf/flowy-database/row_entities.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/row_entities.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database/setting_entities.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/setting_entities.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.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-folder2/view.pb.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
@ -79,7 +79,7 @@ class DatabaseController {
|
|||||||
final DatabaseViewBackendService _databaseViewBackendSvc;
|
final DatabaseViewBackendService _databaseViewBackendSvc;
|
||||||
final FieldController fieldController;
|
final FieldController fieldController;
|
||||||
late DatabaseViewCache _viewCache;
|
late DatabaseViewCache _viewCache;
|
||||||
final LayoutTypePB layoutType;
|
final DatabaseLayoutPB layoutType;
|
||||||
|
|
||||||
// Callbacks
|
// Callbacks
|
||||||
DatabaseCallbacks? _databaseCallbacks;
|
DatabaseCallbacks? _databaseCallbacks;
|
||||||
@ -110,7 +110,7 @@ class DatabaseController {
|
|||||||
_listenOnFieldsChanged();
|
_listenOnFieldsChanged();
|
||||||
_listenOnGroupChanged();
|
_listenOnGroupChanged();
|
||||||
_listenOnLayoutChanged();
|
_listenOnLayoutChanged();
|
||||||
if (layoutType == LayoutTypePB.Calendar) {
|
if (layoutType == DatabaseLayoutPB.Calendar) {
|
||||||
_listenOnCalendarLayoutChanged();
|
_listenOnCalendarLayoutChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import 'package:dartz/dartz.dart';
|
|||||||
|
|
||||||
class DatabaseBackendService {
|
class DatabaseBackendService {
|
||||||
static Future<Either<List<DatabaseDescriptionPB>, FlowyError>>
|
static Future<Either<List<DatabaseDescriptionPB>, FlowyError>>
|
||||||
getAllDatabase() {
|
getAllDatabases() {
|
||||||
return DatabaseEventGetDatabases().send().then((result) {
|
return DatabaseEventGetDatabases().send().then((result) {
|
||||||
return result.fold((l) => left(l.items), (r) => right(r));
|
return result.fold((l) => left(l.items), (r) => right(r));
|
||||||
});
|
});
|
||||||
|
@ -5,7 +5,7 @@ import 'package:appflowy_backend/protobuf/flowy-database/setting_entities.pb.dar
|
|||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.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-folder2/view.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database/field_entities.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/field_entities.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database/group.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/group.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database/row_entities.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/row_entities.pb.dart';
|
||||||
@ -86,7 +86,7 @@ class DatabaseViewBackendService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<LayoutSettingPB, FlowyError>> getLayoutSetting(
|
Future<Either<LayoutSettingPB, FlowyError>> getLayoutSetting(
|
||||||
LayoutTypePB layoutType) {
|
DatabaseLayoutPB layoutType) {
|
||||||
final payload = DatabaseLayoutIdPB.create()
|
final payload = DatabaseLayoutIdPB.create()
|
||||||
..viewId = viewId
|
..viewId = viewId
|
||||||
..layout = layoutType;
|
..layout = layoutType;
|
||||||
|
@ -2,7 +2,6 @@ import 'package:appflowy_backend/log.dart';
|
|||||||
import 'package:appflowy_backend/protobuf/flowy-database/field_entities.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/field_entities.pb.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'dart:async';
|
|
||||||
import 'field_service.dart';
|
import 'field_service.dart';
|
||||||
|
|
||||||
part 'field_action_sheet_bloc.freezed.dart';
|
part 'field_action_sheet_bloc.freezed.dart';
|
||||||
@ -64,11 +63,6 @@ class FieldActionSheetBloc
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> close() async {
|
|
||||||
return super.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import 'package:appflowy_backend/protobuf/flowy-database/field_entities.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/field_entities.pb.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'dart:async';
|
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'field_service.dart';
|
import 'field_service.dart';
|
||||||
import 'type_option/type_option_context.dart';
|
import 'type_option/type_option_context.dart';
|
||||||
@ -17,8 +16,7 @@ class FieldEditorBloc extends Bloc<FieldEditorEvent, FieldEditorState> {
|
|||||||
required String fieldName,
|
required String fieldName,
|
||||||
required bool isGroupField,
|
required bool isGroupField,
|
||||||
required IFieldTypeOptionLoader loader,
|
required IFieldTypeOptionLoader loader,
|
||||||
}) : dataController =
|
}) : dataController = TypeOptionController(viewId: viewId, loader: loader),
|
||||||
TypeOptionController(viewId: viewId, loader: loader),
|
|
||||||
super(FieldEditorState.initial(viewId, fieldName, isGroupField)) {
|
super(FieldEditorState.initial(viewId, fieldName, isGroupField)) {
|
||||||
on<FieldEditorEvent>(
|
on<FieldEditorEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
@ -63,11 +61,6 @@ class FieldEditorBloc extends Bloc<FieldEditorEvent, FieldEditorState> {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> close() async {
|
|
||||||
return super.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
@ -2,7 +2,6 @@ import 'package:appflowy_backend/protobuf/flowy-database/date_type_option.pb.dar
|
|||||||
import 'package:appflowy_backend/protobuf/flowy-database/date_type_option_entities.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/date_type_option_entities.pb.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'dart:async';
|
|
||||||
import 'package:protobuf/protobuf.dart';
|
import 'package:protobuf/protobuf.dart';
|
||||||
|
|
||||||
import 'type_option_context.dart';
|
import 'type_option_context.dart';
|
||||||
@ -52,11 +51,6 @@ class DateTypeOptionBloc
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> close() async {
|
|
||||||
return super.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import 'package:appflowy_backend/protobuf/flowy-database/select_type_option.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/select_type_option.pb.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'dart:async';
|
|
||||||
import 'package:protobuf/protobuf.dart';
|
import 'package:protobuf/protobuf.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
part 'edit_select_option_bloc.freezed.dart';
|
part 'edit_select_option_bloc.freezed.dart';
|
||||||
@ -27,11 +26,6 @@ class EditSelectOptionBloc
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> close() async {
|
|
||||||
return super.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
SelectOptionPB _updateColor(SelectOptionColorPB color) {
|
SelectOptionPB _updateColor(SelectOptionColorPB color) {
|
||||||
state.option.freeze();
|
state.option.freeze();
|
||||||
return state.option.rebuild((option) {
|
return state.option.rebuild((option) {
|
||||||
|
@ -2,7 +2,6 @@ import 'package:appflowy_backend/protobuf/flowy-database/format.pbenum.dart';
|
|||||||
import 'package:appflowy_backend/protobuf/flowy-database/number_type_option.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/number_type_option.pb.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'dart:async';
|
|
||||||
import 'package:protobuf/protobuf.dart';
|
import 'package:protobuf/protobuf.dart';
|
||||||
import 'type_option_context.dart';
|
import 'type_option_context.dart';
|
||||||
|
|
||||||
@ -29,11 +28,6 @@ class NumberTypeOptionBloc
|
|||||||
typeOption.format = format;
|
typeOption.format = format;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> close() async {
|
|
||||||
return super.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import 'package:appflowy_backend/protobuf/flowy-database/format.pbenum.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/format.pbenum.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'dart:async';
|
|
||||||
part 'number_format_bloc.freezed.dart';
|
part 'number_format_bloc.freezed.dart';
|
||||||
|
|
||||||
class NumberFormatBloc extends Bloc<NumberFormatEvent, NumberFormatState> {
|
class NumberFormatBloc extends Bloc<NumberFormatEvent, NumberFormatState> {
|
||||||
@ -21,11 +20,6 @@ class NumberFormatBloc extends Bloc<NumberFormatEvent, NumberFormatState> {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> close() async {
|
|
||||||
return super.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
@ -49,11 +49,6 @@ class SelectOptionTypeOptionBloc
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> close() async {
|
|
||||||
return super.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'dart:async';
|
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
|
|
||||||
part 'setting_bloc.freezed.dart';
|
part 'setting_bloc.freezed.dart';
|
||||||
@ -18,11 +17,6 @@ class DatabaseSettingBloc
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> close() async {
|
|
||||||
return super.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
@ -6,7 +6,7 @@ import 'package:dartz/dartz.dart';
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:appflowy_backend/log.dart';
|
import 'package:appflowy_backend/log.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.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-folder2/view.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database/protobuf.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/protobuf.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
@ -30,7 +30,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
BoardBloc({required ViewPB view})
|
BoardBloc({required ViewPB view})
|
||||||
: _databaseController = DatabaseController(
|
: _databaseController = DatabaseController(
|
||||||
view: view,
|
view: view,
|
||||||
layoutType: LayoutTypePB.Board,
|
layoutType: DatabaseLayoutPB.Board,
|
||||||
),
|
),
|
||||||
super(BoardState.initial(view.id)) {
|
super(BoardState.initial(view.id)) {
|
||||||
boardController = AppFlowyBoardController(
|
boardController = AppFlowyBoardController(
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'dart:async';
|
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
|
|
||||||
part 'board_setting_bloc.freezed.dart';
|
part 'board_setting_bloc.freezed.dart';
|
||||||
@ -17,11 +16,6 @@ class BoardSettingBloc extends Bloc<BoardSettingEvent, BoardSettingState> {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> close() async {
|
|
||||||
return super.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
@ -3,7 +3,7 @@ import 'package:appflowy/plugins/util.dart';
|
|||||||
import 'package:appflowy/startup/plugin/plugin.dart';
|
import 'package:appflowy/startup/plugin/plugin.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/home_stack.dart';
|
import 'package:appflowy/workspace/presentation/home/home_stack.dart';
|
||||||
import 'package:appflowy/workspace/presentation/widgets/left_bar_item.dart';
|
import 'package:appflowy/workspace/presentation/widgets/left_bar_item.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ class BoardPluginBuilder implements PluginBuilder {
|
|||||||
PluginType get pluginType => PluginType.board;
|
PluginType get pluginType => PluginType.board;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ViewLayoutTypePB? get layoutType => ViewLayoutTypePB.Board;
|
ViewLayoutPB? get layoutType => ViewLayoutPB.Board;
|
||||||
}
|
}
|
||||||
|
|
||||||
class BoardPluginConfig implements PluginConfig {
|
class BoardPluginConfig implements PluginConfig {
|
||||||
|
@ -7,7 +7,7 @@ import 'package:appflowy/plugins/database_view/application/field/field_controlle
|
|||||||
import 'package:appflowy/plugins/database_view/application/row/row_cache.dart';
|
import 'package:appflowy/plugins/database_view/application/row/row_cache.dart';
|
||||||
import 'package:appflowy/plugins/database_view/application/row/row_data_controller.dart';
|
import 'package:appflowy/plugins/database_view/application/row/row_data_controller.dart';
|
||||||
import 'package:appflowy/plugins/database_view/widgets/row/row_detail.dart';
|
import 'package:appflowy/plugins/database_view/widgets/row/row_detail.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database/field_entities.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/field_entities.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database/row_entities.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/row_entities.pb.dart';
|
||||||
import 'package:appflowy_board/appflowy_board.dart';
|
import 'package:appflowy_board/appflowy_board.dart';
|
||||||
|
@ -3,7 +3,7 @@ import 'package:appflowy/plugins/database_view/application/field/field_controlle
|
|||||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||||
import 'package:appflowy_backend/log.dart';
|
import 'package:appflowy_backend/log.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/protobuf.dart';
|
import 'package:appflowy_backend/protobuf/flowy-error/protobuf.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/protobuf.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database/protobuf.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/protobuf.dart';
|
||||||
import 'package:calendar_view/calendar_view.dart';
|
import 'package:calendar_view/calendar_view.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
@ -28,7 +28,7 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
|||||||
CalendarBloc({required ViewPB view})
|
CalendarBloc({required ViewPB view})
|
||||||
: _databaseController = DatabaseController(
|
: _databaseController = DatabaseController(
|
||||||
view: view,
|
view: view,
|
||||||
layoutType: LayoutTypePB.Calendar,
|
layoutType: DatabaseLayoutPB.Calendar,
|
||||||
),
|
),
|
||||||
super(CalendarState.initial()) {
|
super(CalendarState.initial()) {
|
||||||
on<CalendarEvent>(
|
on<CalendarEvent>(
|
||||||
|
@ -23,8 +23,6 @@ class CalendarSettingBloc
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> close() async => super.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
@ -3,7 +3,7 @@ import 'package:appflowy/startup/plugin/plugin.dart';
|
|||||||
import 'package:appflowy/workspace/presentation/home/home_stack.dart';
|
import 'package:appflowy/workspace/presentation/home/home_stack.dart';
|
||||||
import 'package:appflowy/workspace/presentation/widgets/left_bar_item.dart';
|
import 'package:appflowy/workspace/presentation/widgets/left_bar_item.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import '../../util.dart';
|
import '../../util.dart';
|
||||||
@ -29,7 +29,7 @@ class CalendarPluginBuilder extends PluginBuilder {
|
|||||||
PluginType get pluginType => PluginType.calendar;
|
PluginType get pluginType => PluginType.calendar;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ViewLayoutTypePB? get layoutType => ViewLayoutTypePB.Calendar;
|
ViewLayoutPB? get layoutType => ViewLayoutPB.Calendar;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CalendarPluginConfig implements PluginConfig {
|
class CalendarPluginConfig implements PluginConfig {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/plugins/database_view/calendar/application/calendar_bloc.dart';
|
import 'package:appflowy/plugins/database_view/calendar/application/calendar_bloc.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||||
import 'package:calendar_view/calendar_view.dart';
|
import 'package:calendar_view/calendar_view.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/filter/choicechip/select_option/select_option_loader.dart';
|
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/filter/choicechip/select_option/select_option_loader.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database/field_entities.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/field_entities.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database/select_type_option.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/select_type_option.pb.dart';
|
||||||
@ -63,11 +61,6 @@ class SelectOptionFilterListBloc<T>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> close() async {
|
|
||||||
return super.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _updateSelectOptions({
|
void _updateSelectOptions({
|
||||||
String? predicate,
|
String? predicate,
|
||||||
Set<String>? selectedOptionIds,
|
Set<String>? selectedOptionIds,
|
||||||
|
@ -4,7 +4,7 @@ import 'package:appflowy/plugins/database_view/application/row/row_service.dart'
|
|||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.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-folder2/view.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database/protobuf.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/protobuf.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
@ -61,11 +61,6 @@ class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
|
|||||||
listenWhen: () => !isClosed,
|
listenWhen: () => !isClosed,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> close() async {
|
|
||||||
return super.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
@ -2,7 +2,6 @@ import 'package:appflowy_backend/log.dart';
|
|||||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'dart:async';
|
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
|
|
||||||
import '../../../application/row/row_cache.dart';
|
import '../../../application/row/row_cache.dart';
|
||||||
@ -34,11 +33,6 @@ class RowActionSheetBloc
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> close() async {
|
|
||||||
return super.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void logResult(Either<Unit, FlowyError> result) {
|
void logResult(Either<Unit, FlowyError> result) {
|
||||||
result.fold((l) => null, (err) => Log.error(err));
|
result.fold((l) => null, (err) => Log.error(err));
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import 'package:appflowy/startup/plugin/plugin.dart';
|
|||||||
import 'package:appflowy/workspace/presentation/home/home_stack.dart';
|
import 'package:appflowy/workspace/presentation/home/home_stack.dart';
|
||||||
import 'package:appflowy/workspace/presentation/widgets/left_bar_item.dart';
|
import 'package:appflowy/workspace/presentation/widgets/left_bar_item.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'presentation/grid_page.dart';
|
import 'presentation/grid_page.dart';
|
||||||
@ -29,7 +29,7 @@ class GridPluginBuilder implements PluginBuilder {
|
|||||||
PluginType get pluginType => PluginType.grid;
|
PluginType get pluginType => PluginType.grid;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ViewLayoutTypePB? get layoutType => ViewLayoutTypePB.Grid;
|
ViewLayoutPB? get layoutType => ViewLayoutPB.Grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
class GridPluginConfig implements PluginConfig {
|
class GridPluginConfig implements PluginConfig {
|
||||||
|
@ -8,7 +8,7 @@ import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart';
|
|||||||
import 'package:flowy_infra_ui/style_widget/scrolling/styled_scrollview.dart';
|
import 'package:flowy_infra_ui/style_widget/scrolling/styled_scrollview.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
import 'package:flowy_infra_ui/widget/error_page.dart';
|
import 'package:flowy_infra_ui/widget/error_page.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:linked_scroll_controller/linked_scroll_controller.dart';
|
import 'package:linked_scroll_controller/linked_scroll_controller.dart';
|
||||||
@ -38,7 +38,7 @@ class GridPage extends StatefulWidget {
|
|||||||
Key? key,
|
Key? key,
|
||||||
}) : databaseController = DatabaseController(
|
}) : databaseController = DatabaseController(
|
||||||
view: view,
|
view: view,
|
||||||
layoutType: LayoutTypePB.Grid,
|
layoutType: DatabaseLayoutPB.Grid,
|
||||||
),
|
),
|
||||||
super(key: key);
|
super(key: key);
|
||||||
|
|
||||||
|
@ -38,7 +38,10 @@ class ChoiceChipButton extends StatelessWidget {
|
|||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
decoration: decoration,
|
decoration: decoration,
|
||||||
useIntrinsicWidth: true,
|
useIntrinsicWidth: true,
|
||||||
text: FlowyText(filterInfo.fieldInfo.name),
|
text: FlowyText(
|
||||||
|
filterInfo.fieldInfo.name,
|
||||||
|
color: AFThemeExtension.of(context).textColor,
|
||||||
|
),
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
|
margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
|
||||||
radius: const BorderRadius.all(Radius.circular(14)),
|
radius: const BorderRadius.all(Radius.circular(14)),
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
@ -62,7 +65,8 @@ class _ChoicechipFilterDesc extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final arrow = Transform.rotate(
|
final arrow = Transform.rotate(
|
||||||
angle: -math.pi / 2,
|
angle: -math.pi / 2,
|
||||||
child: svgWidget("home/arrow_left"),
|
child: svgWidget("home/arrow_left",
|
||||||
|
color: AFThemeExtension.of(context).textColor),
|
||||||
);
|
);
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 2),
|
padding: const EdgeInsets.symmetric(horizontal: 2),
|
||||||
|
@ -18,14 +18,19 @@ class ConditionButton extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final arrow = Transform.rotate(
|
final arrow = Transform.rotate(
|
||||||
angle: -math.pi / 2,
|
angle: -math.pi / 2,
|
||||||
child: svgWidget("home/arrow_left"),
|
child: svgWidget("home/arrow_left",
|
||||||
|
color: AFThemeExtension.of(context).textColor),
|
||||||
);
|
);
|
||||||
|
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: 20,
|
height: 20,
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
useIntrinsicWidth: true,
|
useIntrinsicWidth: true,
|
||||||
text: FlowyText(conditionName, fontSize: 10),
|
text: FlowyText(
|
||||||
|
conditionName,
|
||||||
|
fontSize: 10,
|
||||||
|
color: AFThemeExtension.of(context).textColor,
|
||||||
|
),
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 4),
|
margin: const EdgeInsets.symmetric(horizontal: 4),
|
||||||
radius: const BorderRadius.all(Radius.circular(2)),
|
radius: const BorderRadius.all(Radius.circular(2)),
|
||||||
rightIcon: arrow,
|
rightIcon: arrow,
|
||||||
|
@ -3,6 +3,7 @@ import 'package:appflowy/plugins/database_view/grid/presentation/layout/sizes.da
|
|||||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/field_type_extension.dart';
|
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/field_type_extension.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
@ -117,19 +118,16 @@ class _FilterTextFieldDelegate extends SliverPersistentHeaderDelegate {
|
|||||||
@override
|
@override
|
||||||
Widget build(
|
Widget build(
|
||||||
BuildContext context, double shrinkOffset, bool overlapsContent) {
|
BuildContext context, double shrinkOffset, bool overlapsContent) {
|
||||||
return Padding(
|
return Container(
|
||||||
padding: const EdgeInsets.only(top: 4),
|
padding: const EdgeInsets.only(top: 4),
|
||||||
child: Container(
|
height: fixHeight,
|
||||||
color: Theme.of(context).colorScheme.background,
|
child: FlowyTextField(
|
||||||
height: fixHeight,
|
hintText: LocaleKeys.grid_settings_filterBy.tr(),
|
||||||
child: FlowyTextField(
|
onChanged: (text) {
|
||||||
hintText: LocaleKeys.grid_settings_filterBy.tr(),
|
context
|
||||||
onChanged: (text) {
|
.read<GridCreateFilterBloc>()
|
||||||
context
|
.add(GridCreateFilterEvent.didReceiveFilterText(text));
|
||||||
.read<GridCreateFilterBloc>()
|
},
|
||||||
.add(GridCreateFilterEvent.didReceiveFilterText(text));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -158,7 +156,11 @@ class _FilterPropertyCell extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return FlowyButton(
|
return FlowyButton(
|
||||||
text: FlowyText.medium(fieldInfo.name),
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
|
text: FlowyText.medium(
|
||||||
|
fieldInfo.name,
|
||||||
|
color: AFThemeExtension.of(context).textColor,
|
||||||
|
),
|
||||||
onTap: () => onTap(fieldInfo),
|
onTap: () => onTap(fieldInfo),
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
fieldInfo.fieldType.iconName(),
|
fieldInfo.fieldType.iconName(),
|
||||||
|
@ -3,6 +3,7 @@ import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart';
|
|||||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
|
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
@ -31,6 +32,7 @@ class _DisclosureButtonState extends State<DisclosureButton> {
|
|||||||
.toList(),
|
.toList(),
|
||||||
buildChild: (controller) {
|
buildChild: (controller) {
|
||||||
return FlowyIconButton(
|
return FlowyIconButton(
|
||||||
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
width: 20,
|
width: 20,
|
||||||
icon: svgWidget(
|
icon: svgWidget(
|
||||||
"editor/details",
|
"editor/details",
|
||||||
|
@ -71,7 +71,10 @@ class _AddFilterButtonState extends State<AddFilterButton> {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
height: 28,
|
height: 28,
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
text: FlowyText(LocaleKeys.grid_settings_addFilter.tr()),
|
text: FlowyText(
|
||||||
|
LocaleKeys.grid_settings_addFilter.tr(),
|
||||||
|
color: AFThemeExtension.of(context).textColor,
|
||||||
|
),
|
||||||
useIntrinsicWidth: true,
|
useIntrinsicWidth: true,
|
||||||
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
|
@ -14,12 +14,15 @@ class GridAddRowButton extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return FlowyButton(
|
return FlowyButton(
|
||||||
text: FlowyText.medium(LocaleKeys.grid_row_newRow.tr()),
|
text: FlowyText.medium(
|
||||||
|
LocaleKeys.grid_row_newRow.tr(),
|
||||||
|
color: Theme.of(context).colorScheme.tertiary,
|
||||||
|
),
|
||||||
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
onTap: () => context.read<GridBloc>().add(const GridEvent.createRow()),
|
onTap: () => context.read<GridBloc>().add(const GridEvent.createRow()),
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
"home/add",
|
"home/add",
|
||||||
color: Theme.of(context).iconTheme.color,
|
color: Theme.of(context).colorScheme.tertiary,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -164,11 +164,10 @@ class FieldCellButton extends StatelessWidget {
|
|||||||
.replaceAll(Characters(''), Characters('\u{200B}'))
|
.replaceAll(Characters(''), Characters('\u{200B}'))
|
||||||
.toString();
|
.toString();
|
||||||
return FlowyButton(
|
return FlowyButton(
|
||||||
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
hoverColor: AFThemeExtension.of(context).greyHover,
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
leftIcon: svgWidget(
|
leftIcon: FlowySvg(
|
||||||
field.fieldType.iconName(),
|
name: field.fieldType.iconName(),
|
||||||
color: Theme.of(context).iconTheme.color,
|
|
||||||
),
|
),
|
||||||
radius: BorderRadius.zero,
|
radius: BorderRadius.zero,
|
||||||
text: FlowyText.medium(
|
text: FlowyText.medium(
|
||||||
|
@ -5,6 +5,7 @@ import 'package:appflowy/startup/startup.dart';
|
|||||||
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
|
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
|
||||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||||
@ -81,8 +82,10 @@ class _EditFieldButton extends StatelessWidget {
|
|||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: GridSize.popoverItemHeight,
|
height: GridSize.popoverItemHeight,
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
text: FlowyText.medium(
|
text: FlowyText.medium(
|
||||||
LocaleKeys.grid_field_editProperty.tr(),
|
LocaleKeys.grid_field_editProperty.tr(),
|
||||||
|
color: AFThemeExtension.of(context).textColor,
|
||||||
),
|
),
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
),
|
),
|
||||||
@ -148,9 +151,12 @@ class FieldActionCell extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return FlowyButton(
|
return FlowyButton(
|
||||||
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
text: FlowyText.medium(
|
text: FlowyText.medium(
|
||||||
action.title(),
|
action.title(),
|
||||||
color: enable ? null : Theme.of(context).disabledColor,
|
color: enable
|
||||||
|
? AFThemeExtension.of(context).textColor
|
||||||
|
: Theme.of(context).disabledColor,
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (enable) {
|
if (enable) {
|
||||||
@ -160,7 +166,7 @@ class FieldActionCell extends StatelessWidget {
|
|||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
action.iconName(),
|
action.iconName(),
|
||||||
color: enable
|
color: enable
|
||||||
? Theme.of(context).colorScheme.onSurface
|
? AFThemeExtension.of(context).textColor
|
||||||
: Theme.of(context).disabledColor,
|
: Theme.of(context).disabledColor,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database/field_entities.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/field_entities.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -57,7 +58,11 @@ class FieldTypeCell extends StatelessWidget {
|
|||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: GridSize.popoverItemHeight,
|
height: GridSize.popoverItemHeight,
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
text: FlowyText.medium(fieldType.title()),
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
|
text: FlowyText.medium(
|
||||||
|
fieldType.title(),
|
||||||
|
color: AFThemeExtension.of(context).textColor,
|
||||||
|
),
|
||||||
onTap: () => onSelectField(fieldType),
|
onTap: () => onSelectField(fieldType),
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
fieldType.iconName(),
|
fieldType.iconName(),
|
||||||
|
@ -4,6 +4,7 @@ import 'package:appflowy/plugins/database_view/application/field/type_option/typ
|
|||||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:dartz/dartz.dart' show Either;
|
import 'package:dartz/dartz.dart' show Either;
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database/field_entities.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/field_entities.pb.dart';
|
||||||
@ -110,8 +111,10 @@ class _SwitchFieldButton extends StatelessWidget {
|
|||||||
Widget _buildMoreButton(BuildContext context) {
|
Widget _buildMoreButton(BuildContext context) {
|
||||||
final bloc = context.read<FieldTypeOptionEditBloc>();
|
final bloc = context.read<FieldTypeOptionEditBloc>();
|
||||||
return FlowyButton(
|
return FlowyButton(
|
||||||
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
text: FlowyText.medium(
|
text: FlowyText.medium(
|
||||||
bloc.state.field.fieldType.title(),
|
bloc.state.field.fieldType.title(),
|
||||||
|
color: AFThemeExtension.of(context).textColor,
|
||||||
),
|
),
|
||||||
margin: GridSize.typeOptionContentInsets,
|
margin: GridSize.typeOptionContentInsets,
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
|
@ -178,12 +178,9 @@ class CreateFieldButton extends StatelessWidget {
|
|||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
radius: BorderRadius.zero,
|
radius: BorderRadius.zero,
|
||||||
text: FlowyText.medium(LocaleKeys.grid_field_newColumn.tr()),
|
text: FlowyText.medium(LocaleKeys.grid_field_newColumn.tr()),
|
||||||
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
hoverColor: AFThemeExtension.of(context).greyHover,
|
||||||
onTap: () {},
|
onTap: () {},
|
||||||
leftIcon: svgWidget(
|
leftIcon: const FlowySvg(name: 'home/add'),
|
||||||
"home/add",
|
|
||||||
color: Theme.of(context).iconTheme.color,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
popupBuilder: (BuildContext popover) {
|
popupBuilder: (BuildContext popover) {
|
||||||
return FieldEditor(
|
return FieldEditor(
|
||||||
|
@ -151,10 +151,7 @@ class DateFormatButton extends StatelessWidget {
|
|||||||
margin: buttonMargins,
|
margin: buttonMargins,
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
onHover: onHover,
|
onHover: onHover,
|
||||||
rightIcon: svgWidget(
|
rightIcon: const FlowySvg(name: 'grid/more'),
|
||||||
"grid/more",
|
|
||||||
color: Theme.of(context).iconTheme.color,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -182,10 +179,7 @@ class TimeFormatButton extends StatelessWidget {
|
|||||||
margin: buttonMargins,
|
margin: buttonMargins,
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
onHover: onHover,
|
onHover: onHover,
|
||||||
rightIcon: svgWidget(
|
rightIcon: const FlowySvg(name: 'grid/more'),
|
||||||
"grid/more",
|
|
||||||
color: Theme.of(context).iconTheme.color,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:appflowy/plugins/database_view/application/field/type_option/select_option_type_option_bloc.dart';
|
import 'package:appflowy/plugins/database_view/application/field/type_option/select_option_type_option_bloc.dart';
|
||||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database/select_type_option.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/select_type_option.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -243,7 +244,11 @@ class _AddOptionButton extends StatelessWidget {
|
|||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: GridSize.popoverItemHeight,
|
height: GridSize.popoverItemHeight,
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
text: FlowyText.medium(LocaleKeys.grid_field_addSelectOption.tr()),
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
|
text: FlowyText.medium(
|
||||||
|
LocaleKeys.grid_field_addSelectOption.tr(),
|
||||||
|
color: AFThemeExtension.of(context).textColor,
|
||||||
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context
|
context
|
||||||
.read<SelectOptionTypeOptionBloc>()
|
.read<SelectOptionTypeOptionBloc>()
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:appflowy/plugins/database_view/application/field/type_option/edit_select_option_bloc.dart';
|
import 'package:appflowy/plugins/database_view/application/field/type_option/edit_select_option_bloc.dart';
|
||||||
import 'package:appflowy/plugins/database_view/widgets/row/cells/select_option_cell/extension.dart';
|
import 'package:appflowy/plugins/database_view/widgets/row/cells/select_option_cell/extension.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
@ -103,7 +104,11 @@ class _DeleteTag extends StatelessWidget {
|
|||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: GridSize.popoverItemHeight,
|
height: GridSize.popoverItemHeight,
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
text: FlowyText.medium(LocaleKeys.grid_selectOption_deleteTag.tr()),
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
|
text: FlowyText.medium(
|
||||||
|
LocaleKeys.grid_selectOption_deleteTag.tr(),
|
||||||
|
color: AFThemeExtension.of(context).textColor,
|
||||||
|
),
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
"grid/delete",
|
"grid/delete",
|
||||||
color: Theme.of(context).iconTheme.color,
|
color: Theme.of(context).iconTheme.color,
|
||||||
|
@ -3,6 +3,7 @@ import 'package:appflowy/plugins/database_view/grid/application/row/row_action_s
|
|||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
@ -56,9 +57,12 @@ class _ActionCell extends StatelessWidget {
|
|||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: GridSize.popoverItemHeight,
|
height: GridSize.popoverItemHeight,
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
text: FlowyText.medium(
|
text: FlowyText.medium(
|
||||||
action.title(),
|
action.title(),
|
||||||
color: action.enable() ? null : Theme.of(context).disabledColor,
|
color: action.enable()
|
||||||
|
? AFThemeExtension.of(context).textColor
|
||||||
|
: Theme.of(context).disabledColor,
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (action.enable()) {
|
if (action.enable()) {
|
||||||
|
@ -5,6 +5,7 @@ import 'package:appflowy/plugins/database_view/grid/application/row/row_bloc.dar
|
|||||||
import 'package:appflowy/plugins/database_view/widgets/row/cell_builder.dart';
|
import 'package:appflowy/plugins/database_view/widgets/row/cell_builder.dart';
|
||||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -152,11 +153,15 @@ class _InsertButton extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return FlowyIconButton(
|
return FlowyIconButton(
|
||||||
tooltipText: LocaleKeys.tooltip_addNewRow.tr(),
|
tooltipText: LocaleKeys.tooltip_addNewRow.tr(),
|
||||||
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
width: 20,
|
width: 20,
|
||||||
height: 30,
|
height: 30,
|
||||||
onPressed: () => context.read<RowBloc>().add(const RowEvent.createRow()),
|
onPressed: () => context.read<RowBloc>().add(const RowEvent.createRow()),
|
||||||
iconPadding: const EdgeInsets.all(3),
|
iconPadding: const EdgeInsets.all(3),
|
||||||
icon: svgWidget("home/add"),
|
icon: svgWidget(
|
||||||
|
'home/add',
|
||||||
|
color: Theme.of(context).colorScheme.tertiary,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -182,11 +187,15 @@ class _MenuButtonState extends State<_MenuButton> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return FlowyIconButton(
|
return FlowyIconButton(
|
||||||
tooltipText: LocaleKeys.tooltip_openMenu.tr(),
|
tooltipText: LocaleKeys.tooltip_openMenu.tr(),
|
||||||
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
width: 20,
|
width: 20,
|
||||||
height: 30,
|
height: 30,
|
||||||
onPressed: () => widget.openMenu(),
|
onPressed: () => widget.openMenu(),
|
||||||
iconPadding: const EdgeInsets.all(3),
|
iconPadding: const EdgeInsets.all(3),
|
||||||
icon: svgWidget("editor/details"),
|
icon: svgWidget(
|
||||||
|
'editor/details',
|
||||||
|
color: Theme.of(context).colorScheme.tertiary,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import 'package:appflowy/plugins/database_view/grid/presentation/layout/sizes.da
|
|||||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/field_type_extension.dart';
|
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/field_type_extension.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
@ -116,19 +117,16 @@ class _FilterTextFieldDelegate extends SliverPersistentHeaderDelegate {
|
|||||||
@override
|
@override
|
||||||
Widget build(
|
Widget build(
|
||||||
BuildContext context, double shrinkOffset, bool overlapsContent) {
|
BuildContext context, double shrinkOffset, bool overlapsContent) {
|
||||||
return Padding(
|
return Container(
|
||||||
padding: const EdgeInsets.only(top: 4),
|
padding: const EdgeInsets.only(top: 4),
|
||||||
child: Container(
|
height: fixHeight,
|
||||||
color: Theme.of(context).colorScheme.background,
|
child: FlowyTextField(
|
||||||
height: fixHeight,
|
hintText: LocaleKeys.grid_settings_sortBy.tr(),
|
||||||
child: FlowyTextField(
|
onChanged: (text) {
|
||||||
hintText: LocaleKeys.grid_settings_sortBy.tr(),
|
context
|
||||||
onChanged: (text) {
|
.read<CreateSortBloc>()
|
||||||
context
|
.add(CreateSortEvent.didReceiveFilterText(text));
|
||||||
.read<CreateSortBloc>()
|
},
|
||||||
.add(CreateSortEvent.didReceiveFilterText(text));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -157,7 +155,11 @@ class _SortPropertyCell extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return FlowyButton(
|
return FlowyButton(
|
||||||
text: FlowyText.medium(fieldInfo.name),
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
|
text: FlowyText.medium(
|
||||||
|
fieldInfo.name,
|
||||||
|
color: AFThemeExtension.of(context).textColor,
|
||||||
|
),
|
||||||
onTap: () => onTap(fieldInfo),
|
onTap: () => onTap(fieldInfo),
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
fieldInfo.fieldType.iconName(),
|
fieldInfo.fieldType.iconName(),
|
||||||
|
@ -37,7 +37,10 @@ class SortChoiceButton extends StatelessWidget {
|
|||||||
return FlowyButton(
|
return FlowyButton(
|
||||||
decoration: decoration,
|
decoration: decoration,
|
||||||
useIntrinsicWidth: true,
|
useIntrinsicWidth: true,
|
||||||
text: FlowyText(text),
|
text: FlowyText(
|
||||||
|
text,
|
||||||
|
color: AFThemeExtension.of(context).textColor,
|
||||||
|
),
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
|
margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
|
||||||
radius: BorderRadius.all(radius),
|
radius: BorderRadius.all(radius),
|
||||||
leftIcon: leftIcon,
|
leftIcon: leftIcon,
|
||||||
|
@ -182,13 +182,11 @@ class _AddSortButtonState extends State<_AddSortButton> {
|
|||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: GridSize.popoverItemHeight,
|
height: GridSize.popoverItemHeight,
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
|
hoverColor: AFThemeExtension.of(context).greyHover,
|
||||||
disable: getCreatableSorts(widget.fieldController.fieldInfos).isEmpty,
|
disable: getCreatableSorts(widget.fieldController.fieldInfos).isEmpty,
|
||||||
text: FlowyText.medium(LocaleKeys.grid_sort_addSort.tr()),
|
text: FlowyText.medium(LocaleKeys.grid_sort_addSort.tr()),
|
||||||
onTap: () => _popoverController.show(),
|
onTap: () => _popoverController.show(),
|
||||||
leftIcon: svgWidget(
|
leftIcon: const FlowySvg(name: 'home/add'),
|
||||||
"home/add",
|
|
||||||
color: Theme.of(context).iconTheme.color,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
popupBuilder: (BuildContext context) {
|
popupBuilder: (BuildContext context) {
|
||||||
@ -220,10 +218,7 @@ class _DeleteSortButton extends StatelessWidget {
|
|||||||
.read<SortEditorBloc>()
|
.read<SortEditorBloc>()
|
||||||
.add(const SortEditorEvent.deleteAllSorts());
|
.add(const SortEditorEvent.deleteAllSorts());
|
||||||
},
|
},
|
||||||
leftIcon: svgWidget(
|
leftIcon: const FlowySvg(name: 'editor/delete'),
|
||||||
"editor/delete",
|
|
||||||
color: Theme.of(context).iconTheme.color,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -55,7 +55,10 @@ class SortChoiceChip extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final arrow = Transform.rotate(
|
final arrow = Transform.rotate(
|
||||||
angle: -math.pi / 2,
|
angle: -math.pi / 2,
|
||||||
child: svgWidget("home/arrow_left"),
|
child: svgWidget(
|
||||||
|
"home/arrow_left",
|
||||||
|
color: Theme.of(context).iconTheme.color,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
final text = LocaleKeys.grid_settings_sort.tr();
|
final text = LocaleKeys.grid_settings_sort.tr();
|
||||||
|
@ -25,7 +25,7 @@ class _FilterButtonState extends State<FilterButton> {
|
|||||||
return BlocBuilder<GridFilterMenuBloc, GridFilterMenuState>(
|
return BlocBuilder<GridFilterMenuBloc, GridFilterMenuState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final textColor = state.filters.isEmpty
|
final textColor = state.filters.isEmpty
|
||||||
? null
|
? AFThemeExtension.of(context).textColor
|
||||||
: Theme.of(context).colorScheme.primary;
|
: Theme.of(context).colorScheme.primary;
|
||||||
|
|
||||||
return _wrapPopover(
|
return _wrapPopover(
|
||||||
|
@ -5,6 +5,7 @@ import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/
|
|||||||
import 'package:appflowy/startup/startup.dart';
|
import 'package:appflowy/startup/startup.dart';
|
||||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -115,7 +116,11 @@ class _GridPropertyCellState extends State<_GridPropertyCell> {
|
|||||||
triggerActions: PopoverTriggerFlags.none,
|
triggerActions: PopoverTriggerFlags.none,
|
||||||
margin: EdgeInsets.zero,
|
margin: EdgeInsets.zero,
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
text: FlowyText.medium(widget.fieldInfo.name),
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
|
text: FlowyText.medium(
|
||||||
|
widget.fieldInfo.name,
|
||||||
|
color: AFThemeExtension.of(context).textColor,
|
||||||
|
),
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
widget.fieldInfo.fieldType.iconName(),
|
widget.fieldInfo.fieldType.iconName(),
|
||||||
color: Theme.of(context).iconTheme.color,
|
color: Theme.of(context).iconTheme.color,
|
||||||
|
@ -2,6 +2,7 @@ import 'package:appflowy/plugins/database_view/application/field/field_controlle
|
|||||||
import 'package:appflowy/plugins/database_view/application/setting/setting_bloc.dart';
|
import 'package:appflowy/plugins/database_view/application/setting/setting_bloc.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
@ -71,9 +72,12 @@ class _SettingItem extends StatelessWidget {
|
|||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: GridSize.popoverItemHeight,
|
height: GridSize.popoverItemHeight,
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
text: FlowyText.medium(
|
text: FlowyText.medium(
|
||||||
action.title(),
|
action.title(),
|
||||||
color: action.enable() ? null : Theme.of(context).disabledColor,
|
color: action.enable()
|
||||||
|
? AFThemeExtension.of(context).textColor
|
||||||
|
: Theme.of(context).disabledColor,
|
||||||
),
|
),
|
||||||
onTap: () => onAction(action),
|
onTap: () => onAction(action),
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
|
@ -52,6 +52,7 @@ class _SettingButtonState extends State<SettingButton> {
|
|||||||
triggerActions: PopoverTriggerFlags.none,
|
triggerActions: PopoverTriggerFlags.none,
|
||||||
child: FlowyTextButton(
|
child: FlowyTextButton(
|
||||||
LocaleKeys.settings_title.tr(),
|
LocaleKeys.settings_title.tr(),
|
||||||
|
fontColor: AFThemeExtension.of(context).textColor,
|
||||||
fillColor: Colors.transparent,
|
fillColor: Colors.transparent,
|
||||||
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
padding: GridSize.typeOptionContentInsets,
|
padding: GridSize.typeOptionContentInsets,
|
||||||
|
@ -24,7 +24,7 @@ class _SortButtonState extends State<SortButton> {
|
|||||||
return BlocBuilder<SortMenuBloc, SortMenuState>(
|
return BlocBuilder<SortMenuBloc, SortMenuState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final textColor = state.sortInfos.isEmpty
|
final textColor = state.sortInfos.isEmpty
|
||||||
? null
|
? AFThemeExtension.of(context).textColor
|
||||||
: Theme.of(context).colorScheme.primary;
|
: Theme.of(context).colorScheme.primary;
|
||||||
|
|
||||||
return wrapPopover(
|
return wrapPopover(
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
|
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
|
||||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -116,7 +117,11 @@ class _ChecklistOptionCellState extends State<_ChecklistOptionCell> {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
text: FlowyText(widget.option.data.name),
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
|
text: FlowyText(
|
||||||
|
widget.option.data.name,
|
||||||
|
color: AFThemeExtension.of(context).textColor,
|
||||||
|
),
|
||||||
leftIcon: icon,
|
leftIcon: icon,
|
||||||
onTap: () => context
|
onTap: () => context
|
||||||
.read<ChecklistCellEditorBloc>()
|
.read<ChecklistCellEditorBloc>()
|
||||||
@ -132,6 +137,7 @@ class _ChecklistOptionCellState extends State<_ChecklistOptionCell> {
|
|||||||
|
|
||||||
Widget _disclosureButton() {
|
Widget _disclosureButton() {
|
||||||
return FlowyIconButton(
|
return FlowyIconButton(
|
||||||
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
width: 20,
|
width: 20,
|
||||||
onPressed: () => _popoverController.show(),
|
onPressed: () => _popoverController.show(),
|
||||||
iconPadding: const EdgeInsets.fromLTRB(2, 2, 2, 2),
|
iconPadding: const EdgeInsets.fromLTRB(2, 2, 2, 2),
|
||||||
|
@ -20,7 +20,7 @@ class ChecklistProgressBar extends StatelessWidget {
|
|||||||
percent: percent,
|
percent: percent,
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
progressColor: Theme.of(context).colorScheme.primary,
|
progressColor: Theme.of(context).colorScheme.primary,
|
||||||
backgroundColor: AFThemeExtension.of(context).tint9,
|
backgroundColor: AFThemeExtension.of(context).progressBarBGcolor,
|
||||||
barRadius: const Radius.circular(5),
|
barRadius: const Radius.circular(5),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -385,10 +385,7 @@ class _DateTypeOptionButton extends StatelessWidget {
|
|||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
text: FlowyText.medium(title),
|
text: FlowyText.medium(title),
|
||||||
margin: GridSize.typeOptionContentInsets,
|
margin: GridSize.typeOptionContentInsets,
|
||||||
rightIcon: svgWidget(
|
rightIcon: const FlowySvg(name: 'grid/more'),
|
||||||
"grid/more",
|
|
||||||
color: Theme.of(context).iconTheme.color,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -106,7 +106,11 @@ class SelectOptionTag extends StatelessWidget {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Flexible(
|
Flexible(
|
||||||
child: FlowyText.medium(name, overflow: TextOverflow.ellipsis),
|
child: FlowyText.medium(
|
||||||
|
name,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
if (onRemove != null)
|
if (onRemove != null)
|
||||||
FlowyIconButton(
|
FlowyIconButton(
|
||||||
@ -116,7 +120,7 @@ class SelectOptionTag extends StatelessWidget {
|
|||||||
hoverColor: Colors.transparent,
|
hoverColor: Colors.transparent,
|
||||||
icon: svgWidget(
|
icon: svgWidget(
|
||||||
'home/close',
|
'home/close',
|
||||||
color: Theme.of(context).iconTheme.color,
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -139,6 +143,9 @@ class SelectOptionTagCell extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return FlowyHover(
|
return FlowyHover(
|
||||||
|
style: HoverStyle(
|
||||||
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
|
),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
@ -210,7 +210,7 @@ class _CreateOptionCell extends StatelessWidget {
|
|||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
child: SelectOptionTag(
|
child: SelectOptionTag(
|
||||||
name: name,
|
name: name,
|
||||||
color: AFThemeExtension.of(context).lightGreyHover,
|
color: AFThemeExtension.of(context).greyHover,
|
||||||
onSelected: () => context
|
onSelected: () => context
|
||||||
.read<SelectOptionCellEditorBloc>()
|
.read<SelectOptionCellEditorBloc>()
|
||||||
.add(SelectOptionEditorEvent.newOption(name)),
|
.add(SelectOptionEditorEvent.newOption(name)),
|
||||||
|
@ -5,6 +5,7 @@ import 'package:appflowy/workspace/presentation/home/toast.dart';
|
|||||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
@ -211,10 +212,8 @@ class _EditURLAccessoryState extends State<_EditURLAccessory>
|
|||||||
controller: _popoverController,
|
controller: _popoverController,
|
||||||
direction: PopoverDirection.bottomWithLeftAligned,
|
direction: PopoverDirection.bottomWithLeftAligned,
|
||||||
offset: const Offset(0, 8),
|
offset: const Offset(0, 8),
|
||||||
child: svgWidget(
|
child: svgWidget("editor/edit",
|
||||||
"editor/edit",
|
color: AFThemeExtension.of(context).textColor),
|
||||||
color: Theme.of(context).iconTheme.color,
|
|
||||||
),
|
|
||||||
popupBuilder: (BuildContext popoverContext) {
|
popupBuilder: (BuildContext popoverContext) {
|
||||||
return URLEditorPopover(
|
return URLEditorPopover(
|
||||||
cellController:
|
cellController:
|
||||||
|
@ -8,9 +8,8 @@ import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart';
|
|||||||
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pbserver.dart';
|
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pbserver.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart'
|
import 'package:appflowy_editor/appflowy_editor.dart'
|
||||||
show EditorState, Document, Transaction, Node;
|
show EditorState, Document, Transaction, Node;
|
||||||
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-error/errors.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||||
import 'package:appflowy_backend/log.dart';
|
import 'package:appflowy_backend/log.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -49,8 +48,7 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
|
|||||||
emit(state.copyWith(isDeleted: false));
|
emit(state.copyWith(isDeleted: false));
|
||||||
},
|
},
|
||||||
deletePermanently: (DeletePermanently value) async {
|
deletePermanently: (DeletePermanently value) async {
|
||||||
final result = await _trashService
|
final result = await _trashService.deleteViews([view.id]);
|
||||||
.deleteViews([Tuple2(view.id, TrashType.TrashView)]);
|
|
||||||
|
|
||||||
final newState = result.fold(
|
final newState = result.fold(
|
||||||
(l) => state.copyWith(forceClose: true), (r) => state);
|
(l) => state.copyWith(forceClose: true), (r) => state);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||||
|
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart';
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import 'package:appflowy/plugins/document/presentation/plugins/parsers/divider_n
|
|||||||
import 'package:appflowy/plugins/document/presentation/plugins/parsers/math_equation_node_parser.dart';
|
import 'package:appflowy/plugins/document/presentation/plugins/parsers/math_equation_node_parser.dart';
|
||||||
import 'package:appflowy/plugins/document/presentation/plugins/parsers/code_block_node_parser.dart';
|
import 'package:appflowy/plugins/document/presentation/plugins/parsers/code_block_node_parser.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-document/entities.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-folder2/view.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
@ -3,7 +3,7 @@ import 'package:dartz/dartz.dart';
|
|||||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.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-document/protobuf.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||||
|
|
||||||
class ShareService {
|
class ShareService {
|
||||||
Future<Either<ExportDataPB, FlowyError>> export(
|
Future<Either<ExportDataPB, FlowyError>> export(
|
||||||
|
@ -10,7 +10,7 @@ import 'package:appflowy/startup/plugin/plugin.dart';
|
|||||||
import 'package:appflowy/workspace/presentation/home/home_stack.dart';
|
import 'package:appflowy/workspace/presentation/home/home_stack.dart';
|
||||||
import 'package:appflowy/workspace/presentation/widgets/left_bar_item.dart';
|
import 'package:appflowy/workspace/presentation/widgets/left_bar_item.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ class DocumentPluginBuilder extends PluginBuilder {
|
|||||||
PluginType get pluginType => PluginType.editor;
|
PluginType get pluginType => PluginType.editor;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ViewLayoutTypePB? get layoutType => ViewLayoutTypePB.Document;
|
ViewLayoutPB? get layoutType => ViewLayoutPB.Document;
|
||||||
}
|
}
|
||||||
|
|
||||||
class DocumentPlugin extends Plugin<int> {
|
class DocumentPlugin extends Plugin<int> {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:appflowy/plugins/document/presentation/plugins/board/board_view_menu_item.dart';
|
import 'package:appflowy/plugins/document/presentation/plugins/board/board_view_menu_item.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||||
import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart';
|
import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:appflowy/plugins/document/presentation/plugins/board/board_node_widget.dart';
|
import 'package:appflowy/plugins/document/presentation/plugins/board/board_node_widget.dart';
|
||||||
|
@ -3,7 +3,7 @@ import 'package:appflowy/startup/startup.dart';
|
|||||||
import 'package:appflowy/workspace/application/app/app_service.dart';
|
import 'package:appflowy/workspace/application/app/app_service.dart';
|
||||||
import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart';
|
import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pbserver.dart';
|
import 'package:appflowy_backend/protobuf/flowy-error/errors.pbserver.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:dartz/dartz.dart' as dartz;
|
import 'package:dartz/dartz.dart' as dartz;
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
@ -59,7 +59,7 @@ class _BuiltInPageWidgetState extends State<BuiltInPageWidget> {
|
|||||||
child: CircularProgressIndicator(),
|
child: CircularProgressIndicator(),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
future: AppBackendService().getView(appID, gridID),
|
future: AppBackendService().getChildView(appID, gridID),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,20 +1,53 @@
|
|||||||
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
|
import 'package:appflowy/plugins/database_view/application/database_view_service.dart';
|
||||||
import 'package:appflowy/plugins/document/presentation/plugins/board/board_node_widget.dart';
|
import 'package:appflowy/plugins/document/presentation/plugins/board/board_node_widget.dart';
|
||||||
import 'package:appflowy/plugins/document/presentation/plugins/grid/grid_node_widget.dart';
|
import 'package:appflowy/plugins/document/presentation/plugins/grid/grid_node_widget.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/app.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy/workspace/application/app/app_service.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
|
||||||
const String kAppID = 'app_id';
|
const String kAppID = 'app_id';
|
||||||
const String kViewID = 'view_id';
|
const String kViewID = 'view_id';
|
||||||
|
|
||||||
extension InsertPage on EditorState {
|
extension InsertPage on EditorState {
|
||||||
void insertPage(AppPB appPB, ViewPB viewPB) {
|
Future<void> insertPage(ViewPB appPB, ViewPB viewPB) async {
|
||||||
final selection = service.selectionService.currentSelection.value;
|
final selection = service.selectionService.currentSelection.value;
|
||||||
final textNodes =
|
final textNodes =
|
||||||
service.selectionService.currentSelectedNodes.whereType<TextNode>();
|
service.selectionService.currentSelectedNodes.whereType<TextNode>();
|
||||||
if (selection == null || textNodes.isEmpty) {
|
if (selection == null || textNodes.isEmpty) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get the database that the view is associated with
|
||||||
|
final database =
|
||||||
|
await DatabaseViewBackendService(viewId: viewPB.id).openGrid().then(
|
||||||
|
(value) => value.getLeftOrNull(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (database == null) {
|
||||||
|
throw StateError(
|
||||||
|
'The database associated with ${viewPB.id} could not be found while attempting to create a referenced ${viewPB.layout.name}.');
|
||||||
|
}
|
||||||
|
|
||||||
|
final prefix = referencedBoardPrefix(viewPB.layout);
|
||||||
|
|
||||||
|
final ref = await AppBackendService().createView(
|
||||||
|
appId: appPB.id,
|
||||||
|
name: "$prefix ${viewPB.name}",
|
||||||
|
layoutType: viewPB.layout,
|
||||||
|
ext: {
|
||||||
|
'database_id': database.id,
|
||||||
|
},
|
||||||
|
).then(
|
||||||
|
(value) => value.getLeftOrNull(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO(a-wallen): Show error dialog here.
|
||||||
|
if (ref == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final transaction = this.transaction;
|
final transaction = this.transaction;
|
||||||
transaction.insertNode(
|
transaction.insertNode(
|
||||||
selection.end.path,
|
selection.end.path,
|
||||||
@ -22,18 +55,29 @@ extension InsertPage on EditorState {
|
|||||||
type: _convertPageType(viewPB),
|
type: _convertPageType(viewPB),
|
||||||
attributes: {
|
attributes: {
|
||||||
kAppID: appPB.id,
|
kAppID: appPB.id,
|
||||||
kViewID: viewPB.id,
|
kViewID: ref.id,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
apply(transaction);
|
apply(transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String referencedBoardPrefix(ViewLayoutPB layout) {
|
||||||
|
switch (layout) {
|
||||||
|
case ViewLayoutPB.Grid:
|
||||||
|
return LocaleKeys.grid_referencedGridPrefix.tr();
|
||||||
|
case ViewLayoutPB.Board:
|
||||||
|
return LocaleKeys.board_referencedBoardPrefix.tr();
|
||||||
|
default:
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String _convertPageType(ViewPB viewPB) {
|
String _convertPageType(ViewPB viewPB) {
|
||||||
switch (viewPB.layout) {
|
switch (viewPB.layout) {
|
||||||
case ViewLayoutTypePB.Grid:
|
case ViewLayoutPB.Grid:
|
||||||
return kGridType;
|
return kGridType;
|
||||||
case ViewLayoutTypePB.Board:
|
case ViewLayoutPB.Board:
|
||||||
return kBoardType;
|
return kBoardType;
|
||||||
default:
|
default:
|
||||||
throw Exception('Unknown layout type');
|
throw Exception('Unknown layout type');
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import 'package:appflowy/workspace/application/app/app_service.dart';
|
import 'package:appflowy/workspace/application/app/app_service.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/app.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:dartz/dartz.dart' as dartz;
|
import 'package:dartz/dartz.dart' as dartz;
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'insert_page_command.dart';
|
import 'insert_page_command.dart';
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
@ -18,7 +18,7 @@ void showLinkToPageMenu(
|
|||||||
EditorState editorState,
|
EditorState editorState,
|
||||||
SelectionMenuService menuService,
|
SelectionMenuService menuService,
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
ViewLayoutTypePB pageType,
|
ViewLayoutPB pageType,
|
||||||
) {
|
) {
|
||||||
final alignment = menuService.alignment;
|
final alignment = menuService.alignment;
|
||||||
final offset = menuService.offset;
|
final offset = menuService.offset;
|
||||||
@ -28,10 +28,10 @@ void showLinkToPageMenu(
|
|||||||
|
|
||||||
String hintText = '';
|
String hintText = '';
|
||||||
switch (pageType) {
|
switch (pageType) {
|
||||||
case ViewLayoutTypePB.Grid:
|
case ViewLayoutPB.Grid:
|
||||||
hintText = LocaleKeys.document_slashMenu_grid_selectAGridToLinkTo.tr();
|
hintText = LocaleKeys.document_slashMenu_grid_selectAGridToLinkTo.tr();
|
||||||
break;
|
break;
|
||||||
case ViewLayoutTypePB.Board:
|
case ViewLayoutPB.Board:
|
||||||
hintText = LocaleKeys.document_slashMenu_board_selectABoardToLinkTo.tr();
|
hintText = LocaleKeys.document_slashMenu_board_selectABoardToLinkTo.tr();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -50,15 +50,15 @@ void showLinkToPageMenu(
|
|||||||
editorState: editorState,
|
editorState: editorState,
|
||||||
layoutType: pageType,
|
layoutType: pageType,
|
||||||
hintText: hintText,
|
hintText: hintText,
|
||||||
onSelected: (appPB, viewPB) {
|
onSelected: (viewPB, childViewPB) {
|
||||||
editorState.insertPage(appPB, viewPB);
|
editorState.insertPage(viewPB, childViewPB);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
Overlay.of(context)?.insert(_linkToPageMenu!);
|
Overlay.of(context).insert(_linkToPageMenu!);
|
||||||
|
|
||||||
editorState.service.selectionService.currentSelection
|
editorState.service.selectionService.currentSelection
|
||||||
.addListener(dismissLinkToPageMenu);
|
.addListener(dismissLinkToPageMenu);
|
||||||
@ -83,23 +83,59 @@ class LinkToPageMenu extends StatefulWidget {
|
|||||||
});
|
});
|
||||||
|
|
||||||
final EditorState editorState;
|
final EditorState editorState;
|
||||||
final ViewLayoutTypePB layoutType;
|
final ViewLayoutPB layoutType;
|
||||||
final String hintText;
|
final String hintText;
|
||||||
final void Function(AppPB appPB, ViewPB viewPB) onSelected;
|
final void Function(ViewPB view, ViewPB childView) onSelected;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<LinkToPageMenu> createState() => _LinkToPageMenuState();
|
State<LinkToPageMenu> createState() => _LinkToPageMenuState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _LinkToPageMenuState extends State<LinkToPageMenu> {
|
class _LinkToPageMenuState extends State<LinkToPageMenu> {
|
||||||
|
final _focusNode = FocusNode(debugLabel: 'reference_list_widget');
|
||||||
EditorStyle get style => widget.editorState.editorStyle;
|
EditorStyle get style => widget.editorState.editorStyle;
|
||||||
|
int _selectedIndex = 0;
|
||||||
|
int _totalItems = 0;
|
||||||
|
Future<List<dartz.Tuple2<ViewPB, List<ViewPB>>>>? _availableLayout;
|
||||||
|
final Map<int, dartz.Tuple2<ViewPB, ViewPB>> _items = {};
|
||||||
|
|
||||||
|
Future<List<dartz.Tuple2<ViewPB, List<ViewPB>>>> fetchItems() async {
|
||||||
|
final items = await AppBackendService().fetchViews(widget.layoutType);
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
for (final app in items) {
|
||||||
|
for (final view in app.value2) {
|
||||||
|
_items.putIfAbsent(index, () => dartz.Tuple2(app.value1, view));
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_totalItems = _items.length;
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_availableLayout = fetchItems();
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
_focusNode.requestFocus();
|
||||||
|
});
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_focusNode.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Focus(
|
||||||
color: Colors.transparent,
|
focusNode: _focusNode,
|
||||||
width: 300,
|
onKey: _onKey,
|
||||||
child: Container(
|
child: Container(
|
||||||
|
width: 300,
|
||||||
padding: const EdgeInsets.fromLTRB(10, 6, 10, 6),
|
padding: const EdgeInsets.fromLTRB(10, 6, 10, 6),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: style.selectionMenuBackgroundColor,
|
color: style.selectionMenuBackgroundColor,
|
||||||
@ -112,17 +148,62 @@ class _LinkToPageMenuState extends State<LinkToPageMenu> {
|
|||||||
],
|
],
|
||||||
borderRadius: BorderRadius.circular(6.0),
|
borderRadius: BorderRadius.circular(6.0),
|
||||||
),
|
),
|
||||||
child: _buildListWidget(context),
|
child: _buildListWidget(context, _selectedIndex, _availableLayout),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildListWidget(BuildContext context) {
|
KeyEventResult _onKey(FocusNode node, RawKeyEvent event) {
|
||||||
return FutureBuilder<List<dartz.Tuple2<AppPB, List<ViewPB>>>>(
|
if (event is! RawKeyDownEvent ||
|
||||||
|
_availableLayout == null ||
|
||||||
|
_items.isEmpty) {
|
||||||
|
return KeyEventResult.ignored;
|
||||||
|
}
|
||||||
|
|
||||||
|
final acceptedKeys = [
|
||||||
|
LogicalKeyboardKey.arrowUp,
|
||||||
|
LogicalKeyboardKey.arrowDown,
|
||||||
|
LogicalKeyboardKey.tab,
|
||||||
|
LogicalKeyboardKey.enter
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!acceptedKeys.contains(event.logicalKey)) {
|
||||||
|
return KeyEventResult.handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
var newSelectedIndex = _selectedIndex;
|
||||||
|
if (event.logicalKey == LogicalKeyboardKey.arrowDown &&
|
||||||
|
newSelectedIndex != _totalItems - 1) {
|
||||||
|
newSelectedIndex += 1;
|
||||||
|
} else if (event.logicalKey == LogicalKeyboardKey.arrowUp &&
|
||||||
|
newSelectedIndex != 0) {
|
||||||
|
newSelectedIndex -= 1;
|
||||||
|
} else if (event.logicalKey == LogicalKeyboardKey.tab) {
|
||||||
|
newSelectedIndex += 1;
|
||||||
|
newSelectedIndex %= _totalItems;
|
||||||
|
} else if (event.logicalKey == LogicalKeyboardKey.enter) {
|
||||||
|
widget.onSelected(
|
||||||
|
_items[_selectedIndex]!.value1, _items[_selectedIndex]!.value2);
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_selectedIndex = newSelectedIndex;
|
||||||
|
});
|
||||||
|
|
||||||
|
return KeyEventResult.handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildListWidget(
|
||||||
|
BuildContext context,
|
||||||
|
int selectedIndex,
|
||||||
|
Future<List<dartz.Tuple2<ViewPB, List<ViewPB>>>>? items,
|
||||||
|
) {
|
||||||
|
int index = 0;
|
||||||
|
return FutureBuilder<List<dartz.Tuple2<ViewPB, List<ViewPB>>>>(
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.hasData &&
|
if (snapshot.hasData &&
|
||||||
snapshot.connectionState == ConnectionState.done) {
|
snapshot.connectionState == ConnectionState.done) {
|
||||||
final apps = snapshot.data;
|
final views = snapshot.data;
|
||||||
final children = <Widget>[
|
final children = <Widget>[
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||||
@ -133,28 +214,31 @@ class _LinkToPageMenuState extends State<LinkToPageMenu> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
if (apps != null && apps.isNotEmpty) {
|
if (views != null && views.isNotEmpty) {
|
||||||
for (final app in apps) {
|
for (final view in views) {
|
||||||
if (app.value2.isNotEmpty) {
|
if (view.value2.isNotEmpty) {
|
||||||
children.add(
|
children.add(
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||||
child: FlowyText.regular(
|
child: FlowyText.regular(
|
||||||
app.value1.name,
|
view.value1.name,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
for (final value in app.value2) {
|
for (final value in view.value2) {
|
||||||
children.add(
|
children.add(
|
||||||
FlowyButton(
|
FlowyButton(
|
||||||
|
isSelected: index == _selectedIndex,
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
_iconName(value),
|
_iconName(value),
|
||||||
color: Theme.of(context).iconTheme.color,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
text: FlowyText.regular(value.name),
|
text: FlowyText.regular(value.name),
|
||||||
onTap: () => widget.onSelected(app.value1, value),
|
onTap: () => widget.onSelected(view.value1, value),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
index += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -169,15 +253,15 @@ class _LinkToPageMenuState extends State<LinkToPageMenu> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
future: AppBackendService().fetchViews(widget.layoutType),
|
future: items,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String _iconName(ViewPB viewPB) {
|
String _iconName(ViewPB viewPB) {
|
||||||
switch (viewPB.layout) {
|
switch (viewPB.layout) {
|
||||||
case ViewLayoutTypePB.Grid:
|
case ViewLayoutPB.Grid:
|
||||||
return 'editor/grid';
|
return 'editor/grid';
|
||||||
case ViewLayoutTypePB.Board:
|
case ViewLayoutPB.Board:
|
||||||
return 'editor/board';
|
return 'editor/board';
|
||||||
default:
|
default:
|
||||||
throw Exception('Unknown layout type');
|
throw Exception('Unknown layout type');
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/plugins/document/presentation/plugins/base/link_to_page_widget.dart';
|
import 'package:appflowy/plugins/document/presentation/plugins/base/link_to_page_widget.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
@ -24,7 +24,7 @@ SelectionMenuItem boardMenuItem = SelectionMenuItem(
|
|||||||
editorState,
|
editorState,
|
||||||
menuService,
|
menuService,
|
||||||
context,
|
context,
|
||||||
ViewLayoutTypePB.Board,
|
ViewLayoutPB.Board,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/plugins/document/application/prelude.dart';
|
import 'package:appflowy/plugins/document/application/prelude.dart';
|
||||||
@ -23,17 +23,17 @@ SelectionMenuItem boardViewMenuItem(DocumentBloc documentBloc) =>
|
|||||||
// TODO(a-wallen): Translate keywords.
|
// TODO(a-wallen): Translate keywords.
|
||||||
keywords: ['board', 'kanban'],
|
keywords: ['board', 'kanban'],
|
||||||
handler: (editorState, menuService, context) async {
|
handler: (editorState, menuService, context) async {
|
||||||
if (!documentBloc.view.hasAppId()) {
|
if (!documentBloc.view.hasParentViewId()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final appId = documentBloc.view.appId;
|
final appId = documentBloc.view.parentViewId;
|
||||||
final service = AppBackendService();
|
final service = AppBackendService();
|
||||||
|
|
||||||
final result = (await service.createView(
|
final result = (await service.createView(
|
||||||
appId: appId,
|
appId: appId,
|
||||||
name: LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
|
name: LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
|
||||||
layoutType: ViewLayoutTypePB.Board,
|
layoutType: ViewLayoutPB.Board,
|
||||||
))
|
))
|
||||||
.getLeftOrNull();
|
.getLeftOrNull();
|
||||||
|
|
||||||
@ -42,15 +42,14 @@ SelectionMenuItem boardViewMenuItem(DocumentBloc documentBloc) =>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final app =
|
final app = (await service.getView(result.viewId)).getLeftOrNull();
|
||||||
(await service.readApp(appId: result.appId)).getLeftOrNull();
|
|
||||||
// We should show an error dialog.
|
// We should show an error dialog.
|
||||||
if (app == null) {
|
if (app == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final view =
|
final view = (await service.getChildView(result.viewId, result.id))
|
||||||
(await service.getView(result.appId, result.id)).getLeftOrNull();
|
.getLeftOrNull();
|
||||||
// As this.
|
// As this.
|
||||||
if (view == null) {
|
if (view == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/plugins/document/presentation/plugins/base/link_to_page_widget.dart';
|
import 'package:appflowy/plugins/document/presentation/plugins/base/link_to_page_widget.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
@ -23,7 +23,7 @@ SelectionMenuItem gridMenuItem = SelectionMenuItem(
|
|||||||
editorState,
|
editorState,
|
||||||
menuService,
|
menuService,
|
||||||
context,
|
context,
|
||||||
ViewLayoutTypePB.Grid,
|
ViewLayoutPB.Grid,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -2,7 +2,7 @@ import 'package:appflowy/generated/locale_keys.g.dart';
|
|||||||
import 'package:appflowy/plugins/document/application/doc_bloc.dart';
|
import 'package:appflowy/plugins/document/application/doc_bloc.dart';
|
||||||
import 'package:appflowy/plugins/document/presentation/plugins/base/insert_page_command.dart';
|
import 'package:appflowy/plugins/document/presentation/plugins/base/insert_page_command.dart';
|
||||||
import 'package:appflowy/workspace/application/app/app_service.dart';
|
import 'package:appflowy/workspace/application/app/app_service.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
@ -22,17 +22,17 @@ SelectionMenuItem gridViewMenuItem(DocumentBloc documentBloc) =>
|
|||||||
},
|
},
|
||||||
keywords: ['grid'],
|
keywords: ['grid'],
|
||||||
handler: (editorState, menuService, context) async {
|
handler: (editorState, menuService, context) async {
|
||||||
if (!documentBloc.view.hasAppId()) {
|
if (!documentBloc.view.hasParentViewId()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final appId = documentBloc.view.appId;
|
final appId = documentBloc.view.parentViewId;
|
||||||
final service = AppBackendService();
|
final service = AppBackendService();
|
||||||
|
|
||||||
final result = (await service.createView(
|
final result = (await service.createView(
|
||||||
appId: appId,
|
appId: appId,
|
||||||
name: LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
|
name: LocaleKeys.menuAppHeader_defaultNewPageName.tr(),
|
||||||
layoutType: ViewLayoutTypePB.Grid,
|
layoutType: ViewLayoutPB.Grid,
|
||||||
))
|
))
|
||||||
.getLeftOrNull();
|
.getLeftOrNull();
|
||||||
|
|
||||||
@ -41,15 +41,14 @@ SelectionMenuItem gridViewMenuItem(DocumentBloc documentBloc) =>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final app =
|
final app = (await service.getView(result.viewId)).getLeftOrNull();
|
||||||
(await service.readApp(appId: result.appId)).getLeftOrNull();
|
|
||||||
// We should show an error dialog.
|
// We should show an error dialog.
|
||||||
if (app == null) {
|
if (app == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final view =
|
final view = (await service.getChildView(result.viewId, result.id))
|
||||||
(await service.getView(result.appId, result.id)).getLeftOrNull();
|
.getLeftOrNull();
|
||||||
// As this.
|
// As this.
|
||||||
if (view == null) {
|
if (view == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -13,7 +13,7 @@ import 'package:file_picker/file_picker.dart';
|
|||||||
import 'package:flowy_infra_ui/widget/rounded_button.dart';
|
import 'package:flowy_infra_ui/widget/rounded_button.dart';
|
||||||
import 'package:appflowy_backend/log.dart';
|
import 'package:appflowy_backend/log.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.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-folder2/view.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:appflowy_backend/log.dart';
|
import 'package:appflowy_backend/log.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/trash.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/trash.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
@ -31,8 +31,7 @@ class TrashBloc extends Bloc<TrashEvent, TrashState> {
|
|||||||
final result = await _service.putback(e.trashId);
|
final result = await _service.putback(e.trashId);
|
||||||
await _handleResult(result, emit);
|
await _handleResult(result, emit);
|
||||||
}, delete: (e) async {
|
}, delete: (e) async {
|
||||||
final result =
|
final result = await _service.deleteViews([e.trash.id]);
|
||||||
await _service.deleteViews([Tuple2(e.trash.id, e.trash.ty)]);
|
|
||||||
await _handleResult(result, emit);
|
await _handleResult(result, emit);
|
||||||
}, deleteAll: (e) async {
|
}, deleteAll: (e) async {
|
||||||
final result = await _service.deleteAll();
|
final result = await _service.deleteAll();
|
||||||
|
@ -3,9 +3,9 @@ import 'dart:typed_data';
|
|||||||
import 'package:appflowy/core/folder_notification.dart';
|
import 'package:appflowy/core/folder_notification.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-notification/subject.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-notification/subject.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/notification.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/notification.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/trash.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/trash.pb.dart';
|
||||||
import 'package:appflowy_backend/rust_stream.dart';
|
import 'package:appflowy_backend/rust_stream.dart';
|
||||||
|
|
||||||
typedef TrashUpdatedCallback = void Function(
|
typedef TrashUpdatedCallback = void Function(
|
||||||
@ -19,7 +19,10 @@ class TrashListener {
|
|||||||
|
|
||||||
void start({TrashUpdatedCallback? trashUpdated}) {
|
void start({TrashUpdatedCallback? trashUpdated}) {
|
||||||
_trashUpdated = trashUpdated;
|
_trashUpdated = trashUpdated;
|
||||||
_parser = FolderNotificationParser(callback: _observableCallback);
|
_parser = FolderNotificationParser(
|
||||||
|
id: "trash",
|
||||||
|
callback: _observableCallback,
|
||||||
|
);
|
||||||
_subscription =
|
_subscription =
|
||||||
RustStreamReceiver.listen((observable) => _parser?.parse(observable));
|
RustStreamReceiver.listen((observable) => _parser?.parse(observable));
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import 'dart:async';
|
|||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/trash.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/trash.pb.dart';
|
||||||
|
|
||||||
class TrashService {
|
class TrashService {
|
||||||
Future<Either<RepeatedTrashPB, FlowyError>> readTrash() {
|
Future<Either<RepeatedTrashPB, FlowyError>> readTrash() {
|
||||||
@ -15,12 +15,9 @@ class TrashService {
|
|||||||
return FolderEventPutbackTrash(id).send();
|
return FolderEventPutbackTrash(id).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<Unit, FlowyError>> deleteViews(
|
Future<Either<Unit, FlowyError>> deleteViews(List<String> trash) {
|
||||||
List<Tuple2<String, TrashType>> trashList) {
|
final items = trash.map((trash) {
|
||||||
final items = trashList.map((trash) {
|
return TrashIdPB.create()..id = trash;
|
||||||
return TrashIdPB.create()
|
|
||||||
..id = trash.value1
|
|
||||||
..ty = trash.value2;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
final ids = RepeatedTrashIdPB(items: items);
|
final ids = RepeatedTrashIdPB(items: items);
|
||||||
|
@ -2,7 +2,7 @@ import 'package:flowy_infra/image.dart';
|
|||||||
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
|
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/trash.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/trash.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:fixnum/fixnum.dart' as $fixnum;
|
import 'package:fixnum/fixnum.dart' as $fixnum;
|
||||||
|
@ -2,7 +2,7 @@ import 'package:appflowy/startup/plugin/plugin.dart';
|
|||||||
import 'package:appflowy/workspace/application/view/view_listener.dart';
|
import 'package:appflowy/workspace/application/view/view_listener.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:appflowy_backend/log.dart';
|
import 'package:appflowy_backend/log.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class ViewPluginNotifier extends PluginNotifier<Option<DeletedViewPB>> {
|
class ViewPluginNotifier extends PluginNotifier<Option<DeletedViewPB>> {
|
||||||
|
@ -8,7 +8,6 @@ import 'package:appflowy/user/application/user_listener.dart';
|
|||||||
import 'package:appflowy/user/application/user_service.dart';
|
import 'package:appflowy/user/application/user_service.dart';
|
||||||
import 'package:appflowy/util/file_picker/file_picker_impl.dart';
|
import 'package:appflowy/util/file_picker/file_picker_impl.dart';
|
||||||
import 'package:appflowy/util/file_picker/file_picker_service.dart';
|
import 'package:appflowy/util/file_picker/file_picker_service.dart';
|
||||||
import 'package:appflowy/workspace/application/app/prelude.dart';
|
|
||||||
import 'package:appflowy/plugins/document/application/prelude.dart';
|
import 'package:appflowy/plugins/document/application/prelude.dart';
|
||||||
import 'package:appflowy/workspace/application/settings/settings_location_cubit.dart';
|
import 'package:appflowy/workspace/application/settings/settings_location_cubit.dart';
|
||||||
import 'package:appflowy/workspace/application/user/prelude.dart';
|
import 'package:appflowy/workspace/application/user/prelude.dart';
|
||||||
@ -22,8 +21,7 @@ import 'package:appflowy/user/presentation/router.dart';
|
|||||||
import 'package:appflowy/plugins/trash/application/prelude.dart';
|
import 'package:appflowy/plugins/trash/application/prelude.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/home_stack.dart';
|
import 'package:appflowy/workspace/presentation/home/home_stack.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/menu/menu.dart';
|
import 'package:appflowy/workspace/presentation/home/menu/menu.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/app.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
|
||||||
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
|
||||||
import 'package:fluttertoast/fluttertoast.dart';
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
import 'package:get_it/get_it.dart';
|
import 'package:get_it/get_it.dart';
|
||||||
@ -122,11 +120,6 @@ void _resolveFolderDeps(GetIt getIt) {
|
|||||||
(user, _) => SettingsUserViewBloc(user),
|
(user, _) => SettingsUserViewBloc(user),
|
||||||
);
|
);
|
||||||
|
|
||||||
// AppPB
|
|
||||||
getIt.registerFactoryParam<AppBloc, AppPB, void>(
|
|
||||||
(app, _) => AppBloc(app: app),
|
|
||||||
);
|
|
||||||
|
|
||||||
// trash
|
// trash
|
||||||
getIt.registerLazySingleton<TrashService>(() => TrashService());
|
getIt.registerLazySingleton<TrashService>(() => TrashService());
|
||||||
getIt.registerLazySingleton<TrashListener>(() => TrashListener());
|
getIt.registerLazySingleton<TrashListener>(() => TrashListener());
|
||||||
|
@ -3,7 +3,7 @@ library flowy_plugin;
|
|||||||
import 'package:appflowy/startup/plugin/plugin.dart';
|
import 'package:appflowy/startup/plugin/plugin.dart';
|
||||||
import 'package:appflowy/startup/startup.dart';
|
import 'package:appflowy/startup/startup.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/home_stack.dart';
|
import 'package:appflowy/workspace/presentation/home/home_stack.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
export "./src/sandbox.dart";
|
export "./src/sandbox.dart";
|
||||||
@ -52,7 +52,7 @@ abstract class PluginBuilder {
|
|||||||
|
|
||||||
PluginType get pluginType;
|
PluginType get pluginType;
|
||||||
|
|
||||||
ViewLayoutTypePB? get layoutType => ViewLayoutTypePB.Document;
|
ViewLayoutPB? get layoutType => ViewLayoutPB.Document;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class PluginConfig {
|
abstract class PluginConfig {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user