Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4850a97315 | ||
|
|
8fd9b68d9d | ||
|
|
20b4e5da7e | ||
|
|
ad5ab10cdd | ||
|
|
6bf1d9c19a | ||
|
|
9b6451506f | ||
|
|
39ee73cb64 | ||
|
|
7c03924e9c | ||
|
|
2dfb7261c7 | ||
|
|
59a1b0d869 | ||
|
|
f61bebe869 | ||
|
|
fbf7c9c9b8 | ||
|
|
523caca2ea | ||
|
|
a9a75230a2 | ||
|
|
bb22ca5d93 | ||
|
|
1a83cb65ed | ||
|
|
f4a62209df | ||
|
|
46f69ee00d | ||
|
|
0f71851433 | ||
|
|
897035004c | ||
|
|
4887885aae | ||
|
|
2342a9b834 | ||
|
|
e2778aef9c | ||
|
|
cf6ad8575f | ||
|
|
81efee557c | ||
|
|
72e26ab229 | ||
|
|
8b40244c73 | ||
|
|
481fd9df51 | ||
|
|
4f250a9130 | ||
|
|
cad5e5d718 | ||
|
|
4b88aa8683 | ||
|
|
a384404814 | ||
|
|
b286276108 | ||
|
|
0b83684c66 | ||
|
|
5bd0fb9fae | ||
|
|
57e5c36fe8 | ||
|
|
10365217ca | ||
|
|
9518e164b5 | ||
|
|
9c5081bc07 | ||
|
|
cdfe94cf98 | ||
|
|
a568f6323d | ||
|
|
7071db65e9 | ||
|
|
3d41cb0cec | ||
|
|
ab896cbc8f | ||
|
|
4e3d2672ec | ||
|
|
14b012686b | ||
|
|
e177a1433f | ||
|
|
76da44999c | ||
|
|
84454469b4 | ||
|
|
546b1d22f4 | ||
|
|
43ae87c797 | ||
|
|
5da8144456 | ||
|
|
bfa3eb9577 | ||
|
|
7ff841c3d8 | ||
|
|
4a9627b31d | ||
|
|
ae0f71b5ee | ||
|
|
7cb9ec3042 | ||
|
|
9844c02cbc | ||
|
|
81cf96986e | ||
|
|
b8582b9b68 | ||
|
|
62c322ab21 | ||
|
|
8d766f3bb4 | ||
|
|
166438ad73 | ||
|
|
c4db17f73c | ||
|
|
78e979e438 | ||
|
|
7a7ec10085 | ||
|
|
40e7b42a63 | ||
|
|
9a93a72c33 | ||
|
|
1170e0324b | ||
|
|
8706b81ac0 | ||
|
|
60b80005ac | ||
|
|
89ff8517fa | ||
|
|
d331a68bd1 | ||
|
|
aad33f6746 | ||
|
|
896123860d | ||
|
|
ef2e9cb57e | ||
|
|
2698fb43ad | ||
|
|
1ca602fb72 | ||
|
|
8c7b0bd5a7 | ||
|
|
5b2b50dc9c | ||
|
|
1ae0b188b1 | ||
|
|
f521c18512 | ||
|
|
1b5b8f19d7 | ||
|
|
36abd969ac | ||
|
|
7950f8170b | ||
|
|
ef0d59ff30 | ||
|
|
e8540b4b78 | ||
|
|
23900b49f5 | ||
|
|
f3b87d419f | ||
|
|
1267c7524e | ||
|
|
5f5177355f | ||
|
|
4840d23fff | ||
|
|
a59a0af05b | ||
|
|
7b71fd77ca | ||
|
|
0d40817cad | ||
|
|
7e975e8e1d | ||
|
|
467e0093b2 | ||
|
|
f8d6aa3c74 | ||
|
|
3307e2f8fd | ||
|
|
6d392c240a | ||
|
|
afc563d781 | ||
|
|
c6edd1a6da | ||
|
|
efbac6c92d | ||
|
|
76079d8ce0 | ||
|
|
4f9470b076 | ||
|
|
a178546acd | ||
|
|
6fb163b296 | ||
|
|
19da42f210 | ||
|
|
a2dfc8bc03 | ||
|
|
81d75147d5 | ||
|
|
d3841154a5 | ||
|
|
f617a04900 | ||
|
|
f21ca6c52a | ||
|
|
13cb7eeb24 | ||
|
|
cb0a86893b | ||
|
|
18752e7af8 | ||
|
|
228695d517 | ||
|
|
2f2b69d1a6 | ||
|
|
448c134704 | ||
|
|
6c2c3b0666 | ||
|
|
0b8083cfc6 | ||
|
|
bd0907b0a4 | ||
|
|
a298f7c576 | ||
|
|
1488caa97e | ||
|
|
8d125a07c5 | ||
|
|
f3b899d742 | ||
|
|
cf05d7da41 | ||
|
|
5c4a681909 | ||
|
|
b66d8fc5aa | ||
|
|
2848ecb5ba | ||
|
|
3435e427c2 | ||
|
|
518d11162b | ||
|
|
6b5126b12e | ||
|
|
5e8c8909fb | ||
|
|
371f75343c | ||
|
|
1ad7e0ece2 | ||
|
|
40443ced80 | ||
|
|
f102ca3c85 | ||
|
|
fa3a28e850 | ||
|
|
b779097978 | ||
|
|
10d4021d25 | ||
|
|
2d4aafd26f | ||
|
|
233b9366af | ||
|
|
6e52b470a7 | ||
|
|
3d0036a926 | ||
|
|
0662e376ff | ||
|
|
7e7fe41026 | ||
|
|
f2cd3846f1 | ||
|
|
66cf0ca544 | ||
|
|
296013dcbf | ||
|
|
371c52022b | ||
|
|
0285b286a6 | ||
|
|
ecd2dc3e72 | ||
|
|
f972cdd3fb | ||
|
|
d0b4abb0c8 | ||
|
|
70abe546a1 | ||
|
|
c3ff984c3f | ||
|
|
b29f53c995 | ||
|
|
e8bb6f0a7f | ||
|
|
7f7801d04e | ||
|
|
25548ad9eb | ||
|
|
0b1f0ed401 | ||
|
|
c8945133dc | ||
|
|
b3764e601f | ||
|
|
c7d34465e1 | ||
|
|
d390ef9a3a | ||
|
|
8b4c46f75b | ||
|
|
0ac17fa6df | ||
|
|
cffd8fbec6 | ||
|
|
6d385877a9 | ||
|
|
af5f42d296 | ||
|
|
be49784f5a | ||
|
|
ec16fbe551 | ||
|
|
5af378c810 | ||
|
|
b0f5af679c | ||
|
|
fa7097587f | ||
|
|
bf93376cf3 | ||
|
|
1946959d01 | ||
|
|
b9135d26a9 | ||
|
|
8a7c3a9cfc | ||
|
|
27c40c7b34 | ||
|
|
e1711980c6 | ||
|
|
f66adb53c9 | ||
|
|
eeba6884ce | ||
|
|
f40e0c18e6 | ||
|
|
b3a99be7f8 | ||
|
|
5ee4b8a2bc | ||
|
|
3af558fd94 | ||
|
|
006b3c3811 | ||
|
|
0acc0b0e81 | ||
|
|
13e8c62988 | ||
|
|
917e15a1b7 | ||
|
|
0a19364ea7 | ||
|
|
e647fd0a57 | ||
|
|
c82754f284 | ||
|
|
3cc7c8e6de | ||
|
|
792f8b95aa | ||
|
|
d4de5767a6 | ||
|
|
f3c82f5c30 | ||
|
|
ea654b602c | ||
|
|
0c8850503f | ||
|
|
6dbb708991 | ||
|
|
d71e0de8c3 | ||
|
|
676dffbf21 | ||
|
|
a81db92ee1 | ||
|
|
b282a14b58 | ||
|
|
ac766c0359 | ||
|
|
b606c5ba7b | ||
|
|
fd9e13bf4b | ||
|
|
06af45a8ed | ||
|
|
2fa6adeee6 | ||
|
|
b0e07c952e | ||
|
|
a707410548 | ||
|
|
3089180630 | ||
|
|
943b4507ac | ||
|
|
ee0939ab86 | ||
|
|
a0553b1255 | ||
|
|
f4b206d196 | ||
|
|
a049034110 | ||
|
|
cd14598199 | ||
|
|
ce21c3207c | ||
|
|
2495675fd7 | ||
|
|
722bacd118 | ||
|
|
a19536d525 | ||
|
|
16a167c19c | ||
|
|
d0d8295e15 | ||
|
|
ac584fb7ef | ||
|
|
f5b140a4d9 | ||
|
|
31b2ace48f | ||
|
|
6af78641d2 | ||
|
|
82840e1201 | ||
|
|
f438898831 | ||
|
|
2dd5930560 | ||
|
|
9d629412c8 | ||
|
|
43095cb0dd | ||
|
|
5db5fd118e | ||
|
|
5d9763ff7f | ||
|
|
df6871e777 | ||
|
|
fbb2f49b6f | ||
|
|
f01d3250ae | ||
|
|
420b8ca05d | ||
|
|
a755d52371 | ||
|
|
b92660058c | ||
|
|
d08f298fb6 | ||
|
|
b93feb49c3 | ||
|
|
ed10ebac7a | ||
|
|
ce85050114 | ||
|
|
a53ffdfade | ||
|
|
8a94644add | ||
|
|
0ba0bb62ce | ||
|
|
953af35029 | ||
|
|
1e997ccaad | ||
|
|
fc4ed6c057 | ||
|
|
fc77e0857a | ||
|
|
59fbe02ded | ||
|
|
4f2c733746 | ||
|
|
a035228798 | ||
|
|
6de7933a2f | ||
|
|
5e686906ec | ||
|
|
1f657f3bf8 | ||
|
|
7b98e8dbca | ||
|
|
814fdfe8e9 | ||
|
|
ef008a7b0b | ||
|
|
9073351cbb | ||
|
|
65993b7205 | ||
|
|
11627269be | ||
|
|
e15d335fed | ||
|
|
c82c6d9c6e | ||
|
|
bf8a752b4d | ||
|
|
a3770a699c | ||
|
|
d09a5bf42b | ||
|
|
6a36e2bcfd | ||
|
|
c7a3bb73b9 | ||
|
|
2607822412 | ||
|
|
99d827f07d | ||
|
|
5358203a46 | ||
|
|
271a8485b6 | ||
|
|
1abf0b565f | ||
|
|
5c3500e24c | ||
|
|
aa9e3d065b | ||
|
|
6a94594a35 | ||
|
|
5d007c5359 | ||
|
|
79c178a6e1 | ||
|
|
147e948b35 | ||
|
|
6ac2617113 | ||
|
|
ca45673a9e | ||
|
|
2262dd0d7b | ||
|
|
82eed0506b | ||
|
|
915d71991a | ||
|
|
e0b969595c | ||
|
|
80f82fa5b1 | ||
|
|
3749168861 | ||
|
|
c3c75dde9f | ||
|
|
7c6a857a69 | ||
|
|
4b27fef76e | ||
|
|
547b8ec29c | ||
|
|
065a72a8da | ||
|
|
55b888e364 | ||
|
|
0c1670cdab | ||
|
|
32aa19dc39 | ||
|
|
dd589e0768 | ||
|
|
47e2571f38 | ||
|
|
4a797fcf96 | ||
|
|
f829c63bd2 | ||
|
|
d2080a6c03 | ||
|
|
35e27b579f | ||
|
|
8b7eee46bb | ||
|
|
c7bba01fe5 | ||
|
|
b65b4796d2 | ||
|
|
16598650ff | ||
|
|
28948e567c | ||
|
|
90e7873135 | ||
|
|
2eccd0452b | ||
|
|
933689269b | ||
|
|
8ab2fe3e30 | ||
|
|
3fdf922f81 | ||
|
|
694963a47d | ||
|
|
188302d4ba | ||
|
|
2bbcfaf3ce | ||
|
|
475d511829 | ||
|
|
1f30a77f1d | ||
|
|
c77a31806d | ||
|
|
6a3820253f | ||
|
|
b1d87d95cf | ||
|
|
27628cc78e | ||
|
|
d6a1afe326 | ||
|
|
f181ce106d | ||
|
|
318d7e6456 | ||
|
|
05bcd38534 | ||
|
|
9a40fc9974 | ||
|
|
4730ca9302 | ||
|
|
1237962ab2 | ||
|
|
34530a58ec | ||
|
|
7fd06361b3 | ||
|
|
694c612c67 | ||
|
|
8c148e3b67 | ||
|
|
b3ed254caf | ||
|
|
47081f3095 | ||
|
|
50f32521c5 | ||
|
|
46be04f94e | ||
|
|
196d254278 | ||
|
|
d101509b32 | ||
|
|
572e38ec1c | ||
|
|
baa70f2ee6 | ||
|
|
1e6d82c0ec | ||
|
|
6579940dc8 | ||
|
|
df399d3f35 | ||
|
|
e11176436d | ||
|
|
9a791974b4 | ||
|
|
cea7d30a53 | ||
|
|
7ac6a1dc89 | ||
|
|
e45be3b81e | ||
|
|
fe8811392b | ||
|
|
321682717c | ||
|
|
00db755c29 | ||
|
|
808d848f62 | ||
|
|
54cf451826 | ||
|
|
0502eec717 | ||
|
|
1c1e955151 | ||
|
|
733b6f7176 | ||
|
|
a323073244 | ||
|
|
05441f865e | ||
|
|
9bb516786e | ||
|
|
264166fa29 | ||
|
|
628e53adc1 | ||
|
|
1b80934899 | ||
|
|
5c155a07bf | ||
|
|
11ceb96f65 | ||
|
|
8029f1035d | ||
|
|
d0b457c007 | ||
|
|
9125db7ef0 | ||
|
|
49807a0b57 | ||
|
|
67e6b091a5 | ||
|
|
477fa5f4f6 | ||
|
|
0bbf17f776 | ||
|
|
03f34b143d | ||
|
|
4187e99433 | ||
|
|
5549cff177 | ||
|
|
84afc50cd3 | ||
|
|
383925ba55 | ||
|
|
2e6dd39780 | ||
|
|
0e8ac4828b | ||
|
|
be14a6b0ad | ||
|
|
31467d3e98 | ||
|
|
c2f2ad24db | ||
|
|
853d9e8968 | ||
|
|
33c758e711 | ||
|
|
e7033aa6e8 | ||
|
|
8a0308703e | ||
|
|
b16b61f46c | ||
|
|
6eddb7c8c5 | ||
|
|
cace6248e0 | ||
|
|
dd61dd4d2f | ||
|
|
d1ce1686a4 | ||
|
|
7a36fed778 | ||
|
|
65917da468 | ||
|
|
64d651ab13 | ||
|
|
4180765dc6 | ||
|
|
afab7f23c4 | ||
|
|
289b3e31e7 | ||
|
|
871d0bb7be | ||
|
|
156d38179a | ||
|
|
a979037644 | ||
|
|
b6de0caad6 | ||
|
|
95d33c75a5 | ||
|
|
6509247fbd | ||
|
|
8128283ad4 | ||
|
|
9112bbbcd3 | ||
|
|
d1e1813002 | ||
|
|
8747457836 | ||
|
|
d9f7b1047d | ||
|
|
74831964a6 | ||
|
|
d00425d50b | ||
|
|
5d09e1509d | ||
|
|
11fee0a815 | ||
|
|
4cf509d695 | ||
|
|
8f50d0c6dc | ||
|
|
912fb0b9da | ||
|
|
3021bdc1af | ||
|
|
23ccfa54b5 | ||
|
|
d18e06a9ef | ||
|
|
c843571e3d | ||
|
|
e282a7672f | ||
|
|
d6770c6690 | ||
|
|
01985848f9 | ||
|
|
0a9fb53ef8 | ||
|
|
e9226243df | ||
|
|
2d7d61bdaa | ||
|
|
3eacf70edd | ||
|
|
cebf097fb2 | ||
|
|
6078e46d3d | ||
|
|
349a8350c3 | ||
|
|
d13a6b9649 | ||
|
|
d5cc168d75 | ||
|
|
926b1666dd | ||
|
|
8bdcb43332 | ||
|
|
f8f77db79b | ||
|
|
be3141b08e | ||
|
|
87cc542275 | ||
|
|
441627783b | ||
|
|
03192f8d7e | ||
|
|
ed9a48fc1c | ||
|
|
93695dc4be | ||
|
|
62c104179a | ||
|
|
b855a1199d | ||
|
|
5fdeff83dd | ||
|
|
959b2db9a3 | ||
|
|
d30ac55b0f | ||
|
|
67a3ba6b34 | ||
|
|
74ca10cf28 | ||
|
|
4bcc05fc8a | ||
|
|
c5759baea4 | ||
|
|
0c9fc35cb3 | ||
|
|
d05e4bbc82 | ||
|
|
aa77d52b58 | ||
|
|
6ffa1ad191 | ||
|
|
3a2424cda3 | ||
|
|
288afbe68b | ||
|
|
c1237452ab | ||
|
|
6e1c6d7a47 | ||
|
|
6ae8efbdfe | ||
|
|
a0654d8a41 | ||
|
|
a829d2ac61 | ||
|
|
3bfda80911 | ||
|
|
0b2bb33b73 | ||
|
|
b8a4897056 | ||
|
|
3028195e5e | ||
|
|
fe3533cb2c | ||
|
|
06d3aace92 | ||
|
|
3f90170c71 | ||
|
|
ef770980f5 | ||
|
|
b5d463578a | ||
|
|
ca0851418e | ||
|
|
a6221d34cb | ||
|
|
7eada39a8b | ||
|
|
23795e1b67 | ||
|
|
7314f02282 | ||
|
|
e3d9d4c42a | ||
|
|
22742c904b | ||
|
|
9012494e1f | ||
|
|
c9424c5d55 | ||
|
|
cdec567cbb | ||
|
|
33358c2a04 | ||
|
|
e9ba9ad149 | ||
|
|
7d93ed8e81 | ||
|
|
860ebc567b | ||
|
|
bf7e1b9829 | ||
|
|
0b0cbe192b | ||
|
|
0acb7063ed | ||
|
|
cf1ecaf89b | ||
|
|
2781809f87 | ||
|
|
6fc8197468 | ||
|
|
c559c5cc6b | ||
|
|
2c3aade0f9 | ||
|
|
cea62a5c8e | ||
|
|
7820c8e70d | ||
|
|
bde597a10b |
No files matched your search
@@ -1,79 +1,85 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
branches:
|
||||
- 'main'
|
||||
|
||||
pull_request:
|
||||
branches: [main]
|
||||
branches:
|
||||
- 'main'
|
||||
|
||||
jobs:
|
||||
build-macos:
|
||||
runs-on: macOS-latest
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
flutter_profile: development-linux-x86
|
||||
- os: macos-latest
|
||||
flutter_profile: development-mac-x86_64
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- id: rust_toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
- name: Checkout Flutter
|
||||
uses: actions/checkout@v2
|
||||
toolchain: 'stable-2022-01-20'
|
||||
|
||||
- id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
repository: flutter/flutter
|
||||
path: flutter
|
||||
- name: Flutter
|
||||
working-directory: flutter
|
||||
run: |
|
||||
echo "$(pwd)/bin" >> $GITHUB_PATH
|
||||
export PATH="$PATH:$(pwd)/bin"
|
||||
flutter channel stable
|
||||
flutter config --enable-macos-desktop
|
||||
flutter doctor
|
||||
channel: 'stable'
|
||||
cache: true
|
||||
flutter-version: '3.0.0'
|
||||
|
||||
- name: Cache Cargo
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.cargo
|
||||
key: ${{ runner.os }}-cargo-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}
|
||||
|
||||
- name: Cache Rust
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
frontend/rust-lib/target
|
||||
shared-lib/target
|
||||
key: ${{ runner.os }}-rust-rust-lib-share-lib-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}
|
||||
|
||||
- name: Setup Environment
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||
sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub
|
||||
sudo wget -qO /etc/apt/sources.list.d/dart_stable.list https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y dart curl build-essential libsqlite3-dev libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev
|
||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||
echo 'do nothing'
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Deps
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo install --force cargo-make
|
||||
cargo install --force duckscript_cli
|
||||
cargo install cargo-make
|
||||
cargo install duckscript_cli
|
||||
cargo make flowy_dev
|
||||
echo PATH="$PATH":"$HOME/.pub-cache/bin" >> $GITHUB_PATH
|
||||
|
||||
- name: Config Flutter
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||
flutter config --enable-linux-desktop
|
||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||
flutter config --enable-macos-desktop
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Build
|
||||
working-directory: frontend
|
||||
run: cargo make --profile production-mac-x86 appflowy
|
||||
build-ubuntu:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Packages
|
||||
run: |
|
||||
sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub
|
||||
sudo wget -qO /etc/apt/sources.list.d/dart_stable.list https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y dart curl build-essential libsqlite3-dev libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev
|
||||
- name: Rust
|
||||
run: |
|
||||
curl \
|
||||
--proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
source $HOME/.cargo/env
|
||||
rustup toolchain install stable
|
||||
rustup default stable
|
||||
- name: Checkout Flutter
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: flutter/flutter
|
||||
path: flutter
|
||||
- name: Flutter
|
||||
working-directory: flutter
|
||||
run: |
|
||||
echo "$(pwd)/bin" >> $GITHUB_PATH
|
||||
export PATH="$PATH:$(pwd)/bin"
|
||||
flutter channel stable
|
||||
flutter config --enable-linux-desktop
|
||||
flutter doctor
|
||||
- name: Deps
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo install --force cargo-make
|
||||
cargo install --force duckscript_cli
|
||||
cargo make flowy_dev
|
||||
echo PATH="$PATH":"$HOME/.pub-cache/bin" >> $GITHUB_PATH
|
||||
- name: Build
|
||||
working-directory: frontend
|
||||
run: cargo make --profile production-linux-x86 appflowy
|
||||
cargo make --profile ${{ matrix.flutter_profile }} appflowy-dev
|
||||
@@ -11,7 +11,6 @@ on:
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
@@ -24,15 +23,17 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
- uses: subosito/flutter-action@v1
|
||||
with:
|
||||
flutter-version: '3.0.0'
|
||||
channel: "stable"
|
||||
- name: Flutter pub get
|
||||
run: flutter pub get
|
||||
- name: Deps Flutter
|
||||
run: flutter packages pub get
|
||||
working-directory: frontend/app_flowy
|
||||
- name: Generate language files
|
||||
- name: Code Generation
|
||||
working-directory: frontend/app_flowy
|
||||
run:
|
||||
flutter pub run easy_localization:generate --source-dir ./assets/translations -f keys -O lib/generated -o locale_keys.g.dart
|
||||
- name: flutter analyze
|
||||
run: |
|
||||
flutter packages pub run easy_localization:generate -f keys -o locale_keys.g.dart -S assets/translations -s en.json
|
||||
flutter packages pub run build_runner build --delete-conflicting-outputs
|
||||
- name: Run Flutter Analyzer
|
||||
working-directory: frontend/app_flowy
|
||||
run: flutter analyze
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
name: Unit test(Flutter)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- 'main'
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: 'stable-2022-01-20'
|
||||
|
||||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version: '3.0.0'
|
||||
cache: true
|
||||
|
||||
- name: Cache Cargo
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.cargo
|
||||
key: ${{ runner.os }}-cargo-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}
|
||||
|
||||
- name: Cache Rust
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
frontend/rust-lib/target
|
||||
shared-lib/target
|
||||
key: ${{ runner.os }}-rust-rust-lib-share-lib-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}
|
||||
|
||||
- name: Deps Flutter
|
||||
working-directory: frontend/app_flowy
|
||||
run: |
|
||||
flutter config --enable-linux-desktop
|
||||
|
||||
- name: Deps Rust
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo install cargo-make
|
||||
cargo install duckscript_cli
|
||||
cargo make flowy_dev
|
||||
|
||||
- name: Code Generation
|
||||
working-directory: frontend/app_flowy
|
||||
run: |
|
||||
flutter packages pub get
|
||||
flutter packages pub run easy_localization:generate -f keys -o locale_keys.g.dart -S assets/translations -s en.json
|
||||
flutter packages pub run build_runner build --delete-conflicting-outputs
|
||||
|
||||
- name: Build FlowySDK
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo make --profile development-linux-x86 flowy-sdk-dev
|
||||
|
||||
- name: Run bloc tests
|
||||
working-directory: frontend/app_flowy
|
||||
run: |
|
||||
flutter pub get
|
||||
flutter test
|
||||
|
||||
@@ -17,7 +17,6 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Build release notes
|
||||
working-directory: frontend/app_flowy
|
||||
run: |
|
||||
touch ${{ env.RELEASE_NOTES_PATH }}
|
||||
cat CHANGELOG.md | sed -e '/./{H;$!d;}' -e "x;/##\ Version\ ${{ github.ref_name }}/"'!d;' >> ${{ env.RELEASE_NOTES_PATH }}
|
||||
@@ -35,22 +34,23 @@ jobs:
|
||||
build-linux-x86:
|
||||
runs-on: ubuntu-latest
|
||||
needs: create-release
|
||||
env:
|
||||
env:
|
||||
LINUX_APP_RELEASE_PATH: frontend/app_flowy/product/${{ github.ref_name }}/linux/Release
|
||||
LINUX_ZIP_NAME: AppFlowy-linux-x86.tar.gz
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
|
||||
- name: Setup environment - Rust and Cargo
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
toolchain: 'stable-2022-01-20'
|
||||
|
||||
- name: Setup environment - Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version: '3.0.0'
|
||||
|
||||
- name: Pre build
|
||||
working-directory: frontend
|
||||
@@ -62,13 +62,13 @@ jobs:
|
||||
cargo install --force cargo-make
|
||||
cargo install --force duckscript_cli
|
||||
cargo make flowy_dev
|
||||
|
||||
|
||||
- name: Build Linux app
|
||||
working-directory: frontend
|
||||
run: |
|
||||
flutter config --enable-linux-desktop
|
||||
cargo make --profile production-linux-x86 appflowy
|
||||
|
||||
cargo make --env APP_VERSION=${{ github.ref_name }} --profile production-linux-x86 appflowy
|
||||
|
||||
- name: Upload Release Asset
|
||||
id: upload-release-asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
@@ -83,7 +83,7 @@ jobs:
|
||||
build-macos-x86_64:
|
||||
runs-on: macos-latest
|
||||
needs: create-release
|
||||
env:
|
||||
env:
|
||||
MACOS_APP_RELEASE_PATH: frontend/app_flowy/product/${{ github.ref_name }}/macos/Release
|
||||
MACOS_X86_ZIP_NAME: Appflowy-macos-x86_64.zip
|
||||
steps:
|
||||
@@ -93,12 +93,13 @@ jobs:
|
||||
- name: Setup environment - Rust and Cargo
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
|
||||
toolchain: 'stable-2022-01-20'
|
||||
|
||||
- name: Setup environment - Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version: '3.0.0'
|
||||
|
||||
- name: Pre build
|
||||
working-directory: frontend
|
||||
@@ -107,17 +108,17 @@ jobs:
|
||||
cargo install --force cargo-make
|
||||
cargo install --force duckscript_cli
|
||||
cargo make flowy_dev
|
||||
|
||||
|
||||
- name: Build macOS app for x86_64
|
||||
working-directory: frontend
|
||||
run: |
|
||||
flutter config --enable-macos-desktop
|
||||
cargo make --profile production-mac-x86 appflowy
|
||||
|
||||
cargo make --env APP_VERSION=${{ github.ref_name }} --profile production-mac-x86_64 appflowy
|
||||
|
||||
- name: Archive macOS app
|
||||
working-directory: ${{ env.MACOS_APP_RELEASE_PATH }}
|
||||
run: zip -qr ${{ env.MACOS_X86_ZIP_NAME }} AppFlowy.app
|
||||
|
||||
|
||||
- name: Upload Release Asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
@@ -126,4 +127,4 @@ jobs:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||
asset_path: ${{ env.MACOS_APP_RELEASE_PATH }}/${{ env.MACOS_X86_ZIP_NAME }}
|
||||
asset_name: ${{ env.MACOS_X86_ZIP_NAME }}
|
||||
asset_content_type: application/octet-stream
|
||||
asset_content_type: application/octet-stream
|
||||
@@ -0,0 +1,35 @@
|
||||
name: release_docker
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
build-docker-image:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./frontend/scripts/docker-buildfiles/Dockerfile
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
push: true
|
||||
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/appflowy_client:${{ github.ref_name }}
|
||||
cache-from: type=registry,ref=${{ secrets.DOCKER_HUB_USERNAME }}/af_build_cache:buildcache
|
||||
cache-to: type=registry,ref=${{ secrets.DOCKER_HUB_USERNAME }}/af_build_cache:buildcache,mode=max
|
||||
@@ -3,14 +3,8 @@ name: Rust lint
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
paths:
|
||||
- 'frontend/rust-lib'
|
||||
- 'shared-lib'
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
paths:
|
||||
- 'frontend/rust-lib'
|
||||
- 'shared-lib'
|
||||
|
||||
|
||||
env:
|
||||
@@ -24,7 +18,7 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
toolchain: 'stable-2022-01-20'
|
||||
override: true
|
||||
- run: rustup component add rustfmt
|
||||
working-directory: frontend/rust-lib
|
||||
@@ -39,7 +33,7 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
toolchain: 'stable-2022-01-20'
|
||||
override: true
|
||||
- run: rustup component add clippy
|
||||
working-directory: frontend/rust-lib
|
||||
|
||||
@@ -2,15 +2,11 @@ name: Unit test(Rust)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
# paths:
|
||||
# - 'frontend/rust-lib'
|
||||
# - 'shared-lib'
|
||||
branches:
|
||||
- 'main'
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
# paths:
|
||||
# - 'frontend/rust-lib'
|
||||
# - 'shared-lib'
|
||||
branches:
|
||||
- 'main'
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
@@ -21,19 +17,35 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Install Rust
|
||||
run: |
|
||||
curl \
|
||||
--proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
source $HOME/.cargo/env
|
||||
rustup toolchain install stable
|
||||
rustup default stable
|
||||
|
||||
- id: rust_toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: 'stable-2022-01-20'
|
||||
|
||||
- name: Cache Cargo
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.cargo
|
||||
key: ${{ runner.os }}-cargo-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}
|
||||
|
||||
- name: Cache Rust
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
frontend/rust-lib/target
|
||||
shared-lib/target
|
||||
key: ${{ runner.os }}-rust-rust-lib-share-lib-${{ steps.rust_toolchain.outputs.rustc_hash }}-${{ hashFiles('./frontend/rust-lib/Cargo.toml') }}
|
||||
|
||||
- name: Install cargo-make
|
||||
run: cargo install --force cargo-make
|
||||
working-directory: frontend
|
||||
- name: RustLib tests
|
||||
run: cargo test --no-default-features
|
||||
run: cargo install cargo-make
|
||||
|
||||
- name: Run rust-lib tests
|
||||
working-directory: frontend/rust-lib
|
||||
- name: Sharedlib tests
|
||||
run: cargo test --no-default-features
|
||||
run: RUST_LOG=info cargo test --no-default-features --features="sync"
|
||||
|
||||
- name: Run shared-lib tests
|
||||
working-directory: shared-lib
|
||||
run: RUST_LOG=info cargo test --no-default-features
|
||||
@@ -16,4 +16,5 @@ package-lock.json
|
||||
yarn.lock
|
||||
node_modules
|
||||
**/.proto_cache
|
||||
**/.cache
|
||||
**/.cache
|
||||
**/.DS_Store
|
||||
@@ -0,0 +1,27 @@
|
||||
# Release Notes
|
||||
|
||||
## Version 0.0.4 - beta.1 - 2022-04-08
|
||||
v0.0.4 - beta.1 is pre-release
|
||||
|
||||
New features
|
||||
- Table-view database
|
||||
- supported column types: Text, Checbox, Single-select, Multi-select, Numbers
|
||||
- hide / delete columns
|
||||
- insert rows
|
||||
|
||||
## Version 0.0.3 - 2022-02-23
|
||||
v0.0.3 is production ready, available on Linux, macOS, and Windows
|
||||
|
||||
New features
|
||||
- Dark Mode
|
||||
- Support new languages: French, Italian, Russian, Simplified Chinese, Spanish
|
||||
- Add Settings: Toggle on Dark Mode; Select a language
|
||||
- Show device info
|
||||
- Add tooltip on toolbar icons
|
||||
|
||||
Bug fixes and improvements
|
||||
- Increased height of action
|
||||
- CPU performance issue
|
||||
- Fix potential data parser error
|
||||
- More foundation work for online collaboration
|
||||
|
||||
@@ -20,12 +20,13 @@ You are in charge of your data and customizations.
|
||||
<p align="center">
|
||||
<a href="http://www.appflowy.io"><b>Website</b></a> •
|
||||
<a href="https://discord.gg/9Q2xaN37tV"><b>Discord</b></a> •
|
||||
<a href="https://twitter.com/appflowy"><b>Twitter</b></a>
|
||||
</p>
|
||||
<a href="https://twitter.com/appflowy"><b>Twitter</b></a>
|
||||
</p>
|
||||
|
||||
<p align="center"><img src="https://github.com/AppFlowy-IO/appflowy/blob/main/doc/imgs/welcome.png" alt="The Open Source Alternative To Notion." width="1000px" /></p>
|
||||
|
||||
## User Installation
|
||||
|
||||
Please view the [documentation](https://appflowy.gitbook.io/docs/essential-documentation/install-appflowy/installation-methods) for OS specific installation instructions.
|
||||
|
||||
## Built With
|
||||
@@ -85,4 +86,4 @@ Distributed under the AGPLv3 License. See `LICENSE.md` for more information.
|
||||
Special thanks to these amazing projects which help power AppFlowy.IO:
|
||||
|
||||
- [flutter-quill](https://github.com/singerdmx/flutter-quill)
|
||||
- [cargo-make](https://github.com/sagiegurari/cargo-make)
|
||||
- [cargo-make](https://github.com/sagiegurari/cargo-make)
|
||||
@@ -1,20 +1,24 @@
|
||||
// module.exports = {extends: ['@commitlint/config-conventional']}
|
||||
module.exports = {
|
||||
rules: {
|
||||
'type-enum': [2, 'always', ['chore', 'ci', 'docs', 'feat', 'fix', 'refactor', 'style', 'test']],
|
||||
'body-leading-blank': [1, 'always'],
|
||||
'body-max-line-length': [2, 'always', 100],
|
||||
'footer-leading-blank': [1, 'always'],
|
||||
'footer-max-line-length': [2, 'always', 100],
|
||||
'header-max-length': [2, 'always', 100],
|
||||
|
||||
'type-enum': [2, 'always', ['build', 'chore', 'ci', 'docs', 'feat', 'feature', 'fix', 'refactor', 'style', 'test']],
|
||||
'type-empty': [2, 'never'],
|
||||
'type-case': [2, 'always', 'lower-case'],
|
||||
|
||||
'subject-empty': [2, 'never'],
|
||||
'subject-case': [
|
||||
2,
|
||||
0,
|
||||
'never',
|
||||
['sentence-case', 'start-case', 'pascal-case', 'upper-case'],
|
||||
],
|
||||
'subject-empty': [2, 'never'],
|
||||
'type-empty': [2, 'never'],
|
||||
'type-case': [2, 'always', 'lower-case'],
|
||||
'body-case': [2, 'never', []]
|
||||
|
||||
'body-leading-blank': [2, 'always'],
|
||||
'body-max-line-length': [2, 'always', 200],
|
||||
'body-case': [0, 'never', []],
|
||||
|
||||
'footer-leading-blank': [1, 'always'],
|
||||
'footer-max-line-length': [2, 'always', 100]
|
||||
},
|
||||
};
|
||||
@@ -11,7 +11,7 @@
|
||||
"type": "dart",
|
||||
"preLaunchTask": "build_flowy_sdk",
|
||||
"env":{
|
||||
"RUST_LOG":"info",
|
||||
"RUST_LOG":"info"
|
||||
},
|
||||
"cwd": "${workspaceRoot}/app_flowy"
|
||||
},
|
||||
@@ -22,7 +22,7 @@
|
||||
"type": "dart",
|
||||
"preLaunchTask": "build_flowy_sdk",
|
||||
"env":{
|
||||
"RUST_LOG":"trace",
|
||||
"RUST_LOG":"trace"
|
||||
},
|
||||
"cwd": "${workspaceRoot}/app_flowy"
|
||||
},
|
||||
|
||||
@@ -7,32 +7,61 @@ extend = [
|
||||
{ path = "scripts/makefile/docker.toml" },
|
||||
{ path = "scripts/makefile/env.toml" },
|
||||
{ path = "scripts/makefile/flutter.toml" },
|
||||
{ path = "scripts/makefile/tool.toml" },
|
||||
]
|
||||
|
||||
[config]
|
||||
on_error_task = "catch"
|
||||
|
||||
[tasks.catch]
|
||||
run_task = {name = ["restore-crate-type"]}
|
||||
|
||||
[env]
|
||||
RUST_LOG = "info"
|
||||
CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
|
||||
CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
|
||||
CARGO_MAKE_CRATE_NAME = "dart-ffi"
|
||||
VERSION = "0.0.3"
|
||||
LIB_NAME = "dart_ffi"
|
||||
CURRENT_APP_VERSION = "0.0.4"
|
||||
FEATURES = "flutter"
|
||||
PRODUCT_NAME = "AppFlowy"
|
||||
#CRATE_TYPE: https://doc.rust-lang.org/reference/linkage.html
|
||||
# CRATE_TYPE: https://doc.rust-lang.org/reference/linkage.html
|
||||
# If you update the macOS's CRATE_TYPE, don't forget to update the
|
||||
# flowy_sdk.podspec
|
||||
# for staticlib:
|
||||
# s.static_framework = true
|
||||
# s.vendored_libraries = "libdart_ffi.a"
|
||||
# for cdylib:
|
||||
# s.vendored_libraries = "libdart_ffi.dylib"
|
||||
#
|
||||
# Remember to update the ffi.dart:
|
||||
# for staticlib:
|
||||
# if (Platform.isMacOS) return DynamicLibrary.open('${prefix}/libdart_ffi.a');
|
||||
# for cdylib:
|
||||
# if (Platform.isMacOS) return DynamicLibrary.open('${prefix}/libdart_ffi.dylib');
|
||||
CRATE_TYPE = "staticlib"
|
||||
SDK_EXT = "a"
|
||||
APP_ENVIRONMENT = "local"
|
||||
FLUTTER_FLOWY_SDK_PATH="app_flowy/packages/flowy_sdk"
|
||||
PROTOBUF_DERIVE_CACHE="../shared-lib/flowy-derive/src/derive_cache/derive_cache.rs"
|
||||
|
||||
[env.development-mac]
|
||||
RUST_LOG = "trace"
|
||||
[env.development-mac-arm64]
|
||||
RUST_LOG = "info"
|
||||
TARGET_OS = "macos"
|
||||
RUST_COMPILE_TARGET = "aarch64-apple-darwin"
|
||||
BUILD_FLAG = "debug"
|
||||
FLUTTER_OUTPUT_DIR = "Debug"
|
||||
PRODUCT_EXT = "app"
|
||||
|
||||
[env.development-mac-x86_64]
|
||||
RUST_LOG = "info"
|
||||
TARGET_OS = "macos"
|
||||
RUST_COMPILE_TARGET = "x86_64-apple-darwin"
|
||||
BUILD_FLAG = "debug"
|
||||
FLUTTER_OUTPUT_DIR = "Debug"
|
||||
PRODUCT_EXT = "app"
|
||||
|
||||
[env.production-mac-aarch64]
|
||||
[env.production-mac-arm64]
|
||||
BUILD_FLAG = "release"
|
||||
TARGET_OS = "macos"
|
||||
RUST_COMPILE_TARGET = "aarch64-apple-darwin"
|
||||
@@ -40,7 +69,7 @@ FLUTTER_OUTPUT_DIR = "Release"
|
||||
PRODUCT_EXT = "app"
|
||||
APP_ENVIRONMENT = "production"
|
||||
|
||||
[env.production-mac-x86]
|
||||
[env.production-mac-x86_64]
|
||||
BUILD_FLAG = "release"
|
||||
TARGET_OS = "macos"
|
||||
RUST_COMPILE_TARGET = "x86_64-apple-darwin"
|
||||
@@ -124,7 +153,6 @@ script_runner = "@shell"
|
||||
[env.production-ios]
|
||||
BUILD_FLAG = "release"
|
||||
TARGET_OS = "ios"
|
||||
CRATE_TYPE = "staticlib"
|
||||
FLUTTER_OUTPUT_DIR = "Release"
|
||||
PRODUCT_EXT = "ipa"
|
||||
|
||||
@@ -153,7 +181,6 @@ script = [
|
||||
]
|
||||
script_runner = "@duckscript"
|
||||
|
||||
|
||||
[tasks.test-build]
|
||||
condition = { env_set = [ "FLUTTER_FLOWY_SDK_PATH"] }
|
||||
script = [
|
||||
|
||||
@@ -37,6 +37,10 @@ lib/generated_plugin_registrant.dart
|
||||
# Language related generated files
|
||||
lib/generated/
|
||||
|
||||
# Freezed generated files
|
||||
*.g.dart
|
||||
*.freezed.dart
|
||||
|
||||
# Symbolication related
|
||||
app.*.symbols
|
||||
|
||||
@@ -59,4 +63,5 @@ windows/flutter/dart_ffi/
|
||||
**/**/*.lib
|
||||
**/**/*.dll
|
||||
**/**/*.so
|
||||
**/**/Brewfile.lock.json
|
||||
**/**/Brewfile.lock.json
|
||||
**/.sandbox
|
||||
@@ -5,40 +5,44 @@
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "app_flowy",
|
||||
// This task builds the Rust and Dart code of AppFlowy.
|
||||
"name": "Build",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/lib/main.dart",
|
||||
"type": "dart",
|
||||
"preLaunchTask": "build_flowy_sdk",
|
||||
"env":{
|
||||
"RUST_LOG":"info",
|
||||
"type": "dart",
|
||||
"env": {
|
||||
"RUST_LOG": "debug"
|
||||
},
|
||||
"cwd": "${workspaceRoot}"
|
||||
},
|
||||
{
|
||||
"name": "app_flowy(trace)",
|
||||
// This task only build the Dart code of AppFlowy.
|
||||
"name": "Build (Dart)",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/lib/main.dart",
|
||||
"type": "dart",
|
||||
"preLaunchTask": "build_flowy_sdk",
|
||||
"env":{
|
||||
"RUST_LOG":"trace",
|
||||
"env": {
|
||||
"RUST_LOG": "debug"
|
||||
},
|
||||
"cwd": "${workspaceRoot}"
|
||||
},
|
||||
{
|
||||
"name": "app_flowy (profile mode)",
|
||||
"name": "Build (trace log)",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/lib/main.dart",
|
||||
"type": "dart",
|
||||
"preLaunchTask": "build_flowy_sdk",
|
||||
"env": {
|
||||
"RUST_LOG": "trace"
|
||||
},
|
||||
"cwd": "${workspaceRoot}"
|
||||
},
|
||||
{
|
||||
"name": "Build (profile mode)",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"flutterMode": "profile"
|
||||
},
|
||||
{
|
||||
"name": "Generate Language Files",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/lib/main.dart",
|
||||
"type": "dart",
|
||||
"preLaunchTask": "Generate Language Files",
|
||||
"cwd": "${workspaceRoot}"
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -50,6 +50,40 @@
|
||||
// "$rustc"
|
||||
// ],
|
||||
},
|
||||
{
|
||||
"label": "Code Gen",
|
||||
"type": "shell",
|
||||
"dependsOn": [
|
||||
"Flutter Pub",
|
||||
"Flutter Package Get",
|
||||
"Generate Language Files",
|
||||
"Generate Freezed Files"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true,
|
||||
},
|
||||
"dependsOrder": "sequence",
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "new"
|
||||
},
|
||||
},
|
||||
{
|
||||
"label": "Flutter Pub",
|
||||
"type": "shell",
|
||||
"command": "flutter pub get",
|
||||
},
|
||||
{
|
||||
"label": "Flutter Package Get",
|
||||
"type": "shell",
|
||||
"command": "flutter packages pub get",
|
||||
},
|
||||
{
|
||||
"label": "Generate Freezed Files",
|
||||
"type": "shell",
|
||||
"command": "flutter pub run build_runner build --delete-conflicting-outputs",
|
||||
},
|
||||
{
|
||||
"label": "Generate Language Files",
|
||||
"type": "shell",
|
||||
@@ -87,10 +121,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true,
|
||||
},
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/../"
|
||||
},
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
# Release Notes
|
||||
|
||||
## Version 0.0.0 - 2022-22-14
|
||||
* 😁 Replace Me.
|
||||
@@ -36,3 +36,6 @@ linter:
|
||||
|
||||
# Additional information about this file can be found at
|
||||
# https://dart.dev/guides/language/analysis-options
|
||||
|
||||
errors:
|
||||
invalid_annotation_target: ignore
|
||||
@@ -1,3 +0,0 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.2304 4.2561H10.0184L8.02638 7.9401H8.00238L5.99838 4.2561H4.78638L7.06638 8.2401H5.43438V8.9601H7.47438L7.48638 8.9841V9.8241H5.43438V10.5321H7.48638V12.5001H8.53038V10.5321H10.4984V9.8241H8.53038V8.9841L8.54238 8.9601H10.4984V8.2401H8.95038L11.2304 4.2561Z" fill="#333333"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 392 B |
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="16px" viewBox="0 0 16 16" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(12.941176%,12.941176%,12.941176%);fill-opacity:1;" d="M 8 1.332031 C 11.683594 1.332031 14.667969 4.316406 14.667969 8 C 14.667969 11.683594 11.683594 14.667969 8 14.667969 C 4.316406 14.667969 1.332031 11.683594 1.332031 8 C 1.332031 4.316406 4.316406 1.332031 8 1.332031 Z M 8 2.332031 C 4.871094 2.332031 2.332031 4.871094 2.332031 8 C 2.332031 11.128906 4.871094 13.667969 8 13.667969 C 11.128906 13.667969 13.667969 11.128906 13.667969 8 C 13.667969 4.871094 11.128906 2.332031 8 2.332031 Z M 5.640625 9.855469 C 6.207031 10.574219 7.066406 11 8 11 C 8.929688 11 9.789062 10.574219 10.355469 9.859375 C 10.527344 9.640625 10.84375 9.605469 11.058594 9.777344 C 11.277344 9.949219 11.3125 10.261719 11.140625 10.476562 C 10.386719 11.433594 9.238281 12 8 12 C 6.757812 12 5.609375 11.429688 4.855469 10.476562 C 4.683594 10.257812 4.722656 9.945312 4.9375 9.773438 C 5.15625 9.601562 5.46875 9.640625 5.640625 9.855469 Z M 6 5.835938 C 6.460938 5.835938 6.832031 6.207031 6.832031 6.667969 C 6.832031 7.125 6.460938 7.5 6 7.5 C 5.539062 7.5 5.167969 7.125 5.167969 6.667969 C 5.167969 6.207031 5.539062 5.835938 6 5.835938 Z M 10 5.835938 C 10.460938 5.835938 10.832031 6.207031 10.832031 6.667969 C 10.832031 7.125 10.460938 7.5 10 7.5 C 9.539062 7.5 9.167969 7.125 9.167969 6.667969 C 9.167969 6.207031 9.539062 5.835938 10 5.835938 Z M 10 5.835938 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="16px" viewBox="0 0 16 16" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(12.941176%,12.941176%,12.941176%);fill-opacity:1;" d="M 11.667969 8 C 13.691406 8 15.332031 9.640625 15.332031 11.667969 C 15.332031 13.691406 13.691406 15.332031 11.667969 15.332031 C 9.640625 15.332031 8 13.691406 8 11.667969 C 8 9.640625 9.640625 8 11.667969 8 Z M 8 1.332031 C 11.683594 1.332031 14.667969 4.316406 14.667969 8 C 14.667969 8.175781 14.660156 8.351562 14.648438 8.523438 C 14.355469 8.246094 14.023438 8.007812 13.664062 7.820312 C 13.570312 4.773438 11.070312 2.332031 8 2.332031 C 4.871094 2.332031 2.332031 4.871094 2.332031 8 C 2.332031 11.070312 4.773438 13.570312 7.820312 13.664062 C 8.007812 14.027344 8.246094 14.355469 8.523438 14.648438 C 8.351562 14.660156 8.175781 14.667969 8 14.667969 C 4.316406 14.667969 1.332031 11.683594 1.332031 8 C 1.332031 4.316406 4.316406 1.332031 8 1.332031 Z M 11.667969 9.332031 L 11.605469 9.339844 C 11.46875 9.363281 11.363281 9.46875 11.339844 9.605469 L 11.332031 9.667969 L 11.332031 11.332031 L 9.664062 11.332031 L 9.605469 11.339844 C 9.46875 11.363281 9.363281 11.46875 9.335938 11.605469 L 9.332031 11.667969 L 9.335938 11.726562 C 9.363281 11.863281 9.46875 11.96875 9.605469 11.996094 L 9.664062 12 L 11.332031 12 L 11.335938 13.667969 L 11.339844 13.730469 C 11.363281 13.863281 11.472656 13.972656 11.609375 13.996094 L 11.667969 14.003906 L 11.726562 13.996094 C 11.863281 13.972656 11.96875 13.863281 11.996094 13.730469 L 12 13.667969 L 12 12 L 13.667969 12 L 13.730469 11.996094 C 13.867188 11.96875 13.972656 11.863281 13.996094 11.726562 L 14.003906 11.667969 L 13.996094 11.605469 C 13.972656 11.46875 13.867188 11.363281 13.730469 11.339844 L 13.667969 11.332031 L 12 11.332031 L 12 9.667969 L 11.996094 9.605469 C 11.96875 9.46875 11.863281 9.363281 11.726562 9.339844 Z M 5.640625 9.855469 C 6.082031 10.414062 6.703125 10.796875 7.394531 10.941406 C 7.355469 11.175781 7.332031 11.417969 7.332031 11.667969 C 7.332031 11.761719 7.335938 11.855469 7.34375 11.945312 C 6.359375 11.785156 5.472656 11.261719 4.855469 10.476562 C 4.683594 10.257812 4.722656 9.945312 4.9375 9.773438 C 5.15625 9.601562 5.46875 9.640625 5.640625 9.855469 Z M 6 5.835938 C 6.460938 5.835938 6.832031 6.207031 6.832031 6.667969 C 6.832031 7.125 6.460938 7.5 6 7.5 C 5.539062 7.5 5.167969 7.125 5.167969 6.667969 C 5.167969 6.207031 5.539062 5.835938 6 5.835938 Z M 10 5.835938 C 10.460938 5.835938 10.832031 6.207031 10.832031 6.667969 C 10.832031 7.125 10.460938 7.5 10 7.5 C 9.539062 7.5 9.167969 7.125 9.167969 6.667969 C 9.167969 6.207031 9.539062 5.835938 10 5.835938 Z M 10 5.835938 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="10" height="8" viewBox="0 0 10 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1 5.2L2.84615 7L9 1" stroke="#00BCF0" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 198 B |
@@ -0,0 +1,6 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3 4.3999H4.11111H13" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M5.77775 4.4V3.2C5.77775 2.88174 5.89481 2.57652 6.10319 2.35147C6.31156 2.12643 6.59418 2 6.88886 2H9.11108C9.40577 2 9.68838 2.12643 9.89676 2.35147C10.1051 2.57652 10.2222 2.88174 10.2222 3.2V4.4M11.8889 4.4V12.8C11.8889 13.1183 11.7718 13.4235 11.5634 13.6485C11.3551 13.8736 11.0724 14 10.7778 14H5.2222C4.92751 14 4.64489 13.8736 4.43652 13.6485C4.22815 13.4235 4.11108 13.1183 4.11108 12.8V4.4H11.8889Z" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6.88892 7.3999V10.9999" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M9.11108 7.3999V10.9999" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 886 B |
@@ -0,0 +1,4 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="8" cy="6" r="1" fill="#333333"/>
|
||||
<circle cx="8" cy="10" r="1" fill="#333333"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 194 B |
@@ -0,0 +1,4 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.9743 6.33301H7.35889C6.79245 6.33301 6.33325 6.7922 6.33325 7.35865V11.974C6.33325 12.5405 6.79245 12.9997 7.35889 12.9997H11.9743C12.5407 12.9997 12.9999 12.5405 12.9999 11.974V7.35865C12.9999 6.7922 12.5407 6.33301 11.9743 6.33301Z" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M4.53846 9.66667H4.02564C3.75362 9.66667 3.49275 9.55861 3.3004 9.36626C3.10806 9.17392 3 8.91304 3 8.64103V4.02564C3 3.75362 3.10806 3.49275 3.3004 3.3004C3.49275 3.10806 3.75362 3 4.02564 3H8.64103C8.91304 3 9.17392 3.10806 9.36626 3.3004C9.55861 3.49275 9.66667 3.75362 9.66667 4.02564V4.53846" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 790 B |
@@ -0,0 +1,6 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6 13H3V10" stroke="#00BCF0" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M10 3H13V6" stroke="#00BCF0" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M3 13L7 9" stroke="#00BCF0" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M13 3L9 7" stroke="#00BCF0" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 449 B |
@@ -0,0 +1,4 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.5 8L8.11538 9.5L13.5 4.5" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M13 8.5V11.8889C13 12.1836 12.8829 12.4662 12.6746 12.6746C12.4662 12.8829 12.1836 13 11.8889 13H4.11111C3.81643 13 3.53381 12.8829 3.32544 12.6746C3.11706 12.4662 3 12.1836 3 11.8889V4.11111C3 3.81643 3.11706 3.53381 3.32544 3.32544C3.53381 3.11706 3.81643 3 4.11111 3H10.2222" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 561 B |
@@ -0,0 +1,4 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.5 8L8.11538 9.5L13.5 4.5" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M13.5 8C13.5 11.0376 11.0376 13.5 8 13.5C4.96243 13.5 2.5 11.0376 2.5 8C2.5 4.96243 4.96243 2.5 8 2.5C8.81896 2.5 9.59612 2.679 10.2945 3" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 421 B |
@@ -0,0 +1,6 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.8889 3.5H4.11111C3.49746 3.5 3 3.94772 3 4.5V11.5C3 12.0523 3.49746 12.5 4.11111 12.5H11.8889C12.5025 12.5 13 12.0523 13 11.5V4.5C13 3.94772 12.5025 3.5 11.8889 3.5Z" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M10 2.5V4.58181" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6 2.5V4.58181" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M3 6.5H13" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 618 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.9083 10.9011C10.4173 11.2751 9.83813 11.4814 9.09532 11.4814C7.93705 11.4814 6.82914 10.8367 6.45144 9.2765H10.027V8.50287H6.32554C6.31295 8.34814 6.31295 8.19341 6.31295 8.02579C6.31295 7.84527 6.32554 7.67765 6.33813 7.51003H10.027V6.73639H6.45144C6.81655 5.25358 7.82374 4.50573 9.09532 4.50573C9.72482 4.50573 10.304 4.69914 10.8201 5.06017L11.4371 4.24785C10.7194 3.73209 9.91367 3.5 9.09532 3.5C7.10612 3.5 5.72122 4.69914 5.31835 6.73639H4.5V7.51003H5.21763C5.20504 7.67765 5.20504 7.84527 5.20504 8.02579C5.20504 8.19341 5.20504 8.34814 5.21763 8.50287H4.5V9.2765H5.31835C5.7464 11.5716 7.40827 12.5 9.09532 12.5C10.0773 12.5 10.8705 12.1777 11.5 11.7264L10.9083 10.9011Z" fill="#333333"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 814 B |
@@ -0,0 +1,8 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.5 4L12.5 4" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6.5 8H12.5" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6.5 12H12.5" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<circle cx="4" cy="4" r="0.5" fill="#333333"/>
|
||||
<circle cx="4" cy="8" r="0.5" fill="#333333"/>
|
||||
<circle cx="4" cy="12" r="0.5" fill="#333333"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 512 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.201 6.4H3.001V12H2.081V7.384L0.953 7.704L0.729 6.92L2.201 6.4ZM3.91156 12V11.1L6.35156 8.61C6.9449 8.01667 7.24156 7.50333 7.24156 7.07C7.24156 6.73 7.13823 6.46667 6.93156 6.28C6.73156 6.08667 6.4749 5.99 6.16156 5.99C5.5749 5.99 5.14156 6.28 4.86156 6.86L3.89156 6.29C4.11156 5.82333 4.42156 5.47 4.82156 5.23C5.22156 4.99 5.6649 4.87 6.15156 4.87C6.7649 4.87 7.29156 5.06333 7.73156 5.45C8.17156 5.83667 8.39156 6.36333 8.39156 7.03C8.39156 7.74333 7.9949 8.50333 7.20156 9.31L5.62156 10.89H8.52156V12H3.91156ZM12.9025 7.032C13.5105 7.176 14.0025 7.46 14.3785 7.884C14.7625 8.3 14.9545 8.824 14.9545 9.456C14.9545 10.296 14.6705 10.956 14.1025 11.436C13.5345 11.916 12.8385 12.156 12.0145 12.156C11.3745 12.156 10.7985 12.008 10.2865 11.712C9.78253 11.416 9.41853 10.984 9.19453 10.416L10.3705 9.732C10.6185 10.452 11.1665 10.812 12.0145 10.812C12.4945 10.812 12.8745 10.692 13.1545 10.452C13.4345 10.204 13.5745 9.872 13.5745 9.456C13.5745 9.04 13.4345 8.712 13.1545 8.472C12.8745 8.232 12.4945 8.112 12.0145 8.112H11.7025L11.1505 7.284L12.9625 4.896H9.44653V3.6H14.6065V4.776L12.9025 7.032Z" fill="#333333"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.201 6.4H3.001V12H2.081V7.384L0.953 7.704L0.729 6.92L2.201 6.4ZM3.91156 12V11.1L6.35156 8.61C6.9449 8.01667 7.24156 7.50333 7.24156 7.07C7.24156 6.73 7.13823 6.46667 6.93156 6.28C6.73156 6.08667 6.4749 5.99 6.16156 5.99C5.5749 5.99 5.14156 6.28 4.86156 6.86L3.89156 6.29C4.11156 5.82333 4.42156 5.47 4.82156 5.23C5.22156 4.99 5.6649 4.87 6.15156 4.87C6.7649 4.87 7.29156 5.06333 7.73156 5.45C8.17156 5.83667 8.39156 6.36333 8.39156 7.03C8.39156 7.74333 7.9949 8.50333 7.20156 9.31L5.62156 10.89H8.52156V12H3.91156ZM12.9025 7.032C13.5105 7.176 14.0025 7.46 14.3785 7.884C14.7625 8.3 14.9545 8.824 14.9545 9.456C14.9545 10.296 14.6705 10.956 14.1025 11.436C13.5345 11.916 12.8385 12.156 12.0145 12.156C11.3745 12.156 10.7985 12.008 10.2865 11.712C9.78253 11.416 9.41853 10.984 9.19453 10.416L10.3705 9.732C10.6185 10.452 11.1665 10.812 12.0145 10.812C12.4945 10.812 12.8745 10.692 13.1545 10.452C13.4345 10.204 13.5745 9.872 13.5745 9.456C13.5745 9.04 13.4345 8.712 13.1545 8.472C12.8745 8.232 12.4945 8.112 12.0145 8.112H11.7025L11.1505 7.284L12.9625 4.896H9.44653V3.6H14.6065V4.776L12.9025 7.032Z" fill="#333333"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.78787 8.78787L6.51213 7.51213C6.32314 7.32314 6.45699 7 6.72426 7H9.27574C9.54301 7 9.67686 7.32314 9.48787 7.51213L8.21213 8.78787C8.09497 8.90503 7.90503 8.90503 7.78787 8.78787Z" fill="#333333"/>
|
||||
<path d="M8 13C10.7614 13 13 10.7614 13 8C13 5.23858 10.7614 3 8 3C5.23858 3 3 5.23858 3 8C3 10.7614 5.23858 13 8 13Z" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 499 B |
@@ -0,0 +1,4 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.15625 11.8359L6.43768 9.85414H2.46662L1.74805 11.8359H0.5L3.7903 3H5.11399L8.4043 11.8359H7.15625ZM2.87003 8.75596H6.03427L4.44584 4.40112L2.87003 8.75596Z" fill="#333333"/>
|
||||
<path d="M14.4032 5.52454H15.5V11.8359H14.4032V10.7504C13.8569 11.5835 13.0627 12 12.0206 12C11.1381 12 10.386 11.6802 9.76403 11.0407C9.14211 10.3927 8.83114 9.60589 8.83114 8.68022C8.83114 7.75456 9.14211 6.97195 9.76403 6.3324C10.386 5.68443 11.1381 5.36045 12.0206 5.36045C13.0627 5.36045 13.8569 5.777 14.4032 6.6101V5.52454ZM12.1593 10.9397C12.798 10.9397 13.3317 10.7251 13.7603 10.2959C14.1889 9.85835 14.4032 9.31978 14.4032 8.68022C14.4032 8.04067 14.1889 7.50631 13.7603 7.07714C13.3317 6.63955 12.798 6.42076 12.1593 6.42076C11.5289 6.42076 10.9995 6.63955 10.5708 7.07714C10.1422 7.50631 9.92791 8.04067 9.92791 8.68022C9.92791 9.31978 10.1422 9.85835 10.5708 10.2959C10.9995 10.7251 11.5289 10.9397 12.1593 10.9397Z" fill="#333333"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M13 7.688L8.27223 12.1469C7.69304 12.6931 6.90749 13 6.0884 13C5.26931 13 4.48376 12.6931 3.90457 12.1469C3.32538 11.6006 3 10.8598 3 10.0873C3 9.31474 3.32538 8.57387 3.90457 8.02763L8.63234 3.56875C9.01847 3.20459 9.54216 3 10.0882 3C10.6343 3 11.158 3.20459 11.5441 3.56875C11.9302 3.93291 12.1472 4.42683 12.1472 4.94183C12.1472 5.45684 11.9302 5.95075 11.5441 6.31491L6.8112 10.7738C6.61814 10.9559 6.35629 11.0582 6.08326 11.0582C5.81022 11.0582 5.54838 10.9559 5.35531 10.7738C5.16225 10.5917 5.05379 10.3448 5.05379 10.0873C5.05379 9.82975 5.16225 9.58279 5.35531 9.40071L9.72297 5.28632" stroke="#333333" stroke-width="0.9989" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 797 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.716 9.828C10.716 8.292 9.6 7.896 8.124 7.416C7.128 7.092 6.396 6.828 6.396 6.072C6.396 5.376 6.984 4.968 7.824 4.968C8.412 4.968 9.216 5.22 9.84 5.676L10.44 4.944C9.9 4.512 9.096 4.176 8.352 4.056V2.508H7.572V4.008C6.12 4.092 5.304 4.98 5.304 6.132C5.304 7.56 6.516 7.98 7.824 8.388C8.928 8.748 9.612 9.036 9.612 9.9C9.612 10.644 8.964 11.088 8.076 11.088C7.308 11.088 6.444 10.752 5.772 10.092L5.136 10.836C5.844 11.532 6.684 11.904 7.572 12.012V13.476H8.352V12.024C9.84 11.928 10.716 11.052 10.716 9.828Z" fill="#333333"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 641 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.2301 4.25586H10.0181L8.02613 7.93986H8.00213L5.99813 4.25586H4.78613L7.06613 8.23986H5.43413V8.95986H7.47413L7.48613 8.98386V9.82386H5.43413V10.5319H7.48613V12.4999H8.53013V10.5319H10.4981V9.82386H8.53013V8.98386L8.54213 8.95986H10.4981V8.23986H8.95013L11.2301 4.25586Z" fill="#333333"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 404 B |
@@ -0,0 +1,4 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.12265 11.5847C5.92255 12.1165 6.88538 12.5 8.00024 12.5C10.4842 12.5 12.2135 10.596 13.0675 9.39083C13.6624 8.55146 13.6624 7.44854 13.0675 6.60917C12.7341 6.13867 12.2673 5.56168 11.6743 5.03305L10.9661 5.74127C11.4908 6.20089 11.9225 6.72296 12.2516 7.18736C12.601 7.68035 12.601 8.31965 12.2516 8.81264C11.4276 9.97552 9.9599 11.5 8.00024 11.5C7.19618 11.5 6.47495 11.2434 5.84702 10.8603L5.12265 11.5847ZM5.03441 10.2587L4.32618 10.967C3.73316 10.4383 3.26636 9.86133 2.93294 9.39083C2.33811 8.55146 2.33811 7.44854 2.93294 6.60917C3.78701 5.40397 5.51627 3.5 8.00024 3.5C9.1151 3.5 10.0779 3.88354 10.8778 4.4153L10.1535 5.13966C9.52554 4.75665 8.80431 4.5 8.00024 4.5C6.04059 4.5 4.57293 6.02448 3.74884 7.18736C3.39948 7.68035 3.39948 8.31965 3.74884 8.81264C4.07794 9.27704 4.50968 9.79911 5.03441 10.2587ZM6.99269 9.71466C7.28548 9.8954 7.62952 10 8.00036 10C9.09422 10 9.95491 9.08996 9.95491 8C9.95491 7.64165 9.86187 7.30275 9.69811 7.00924L8.93118 7.77618C8.94668 7.84779 8.95491 7.92265 8.95491 8C8.95491 8.5669 8.51315 9 8.00036 9C7.91225 9 7.82623 8.98721 7.7442 8.96316L6.99269 9.71466ZM7.06951 8.22363L6.30253 8.99061C6.13882 8.69713 6.04582 8.35829 6.04582 8C6.04582 6.91005 6.9065 6 8.00036 6C8.37114 6 8.71513 6.10456 9.00789 6.28525L8.25635 7.03679C8.17436 7.01277 8.08841 7 8.00036 7C7.48757 7 7.04582 7.4331 7.04582 8C7.04582 8.07728 7.05403 8.15208 7.06951 8.22363Z" fill="#333333"/>
|
||||
<path d="M11.667 3.33398L3.33366 11.6673" stroke="#333333" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,5 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3 11.7778L3 4" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M9.5 4.5L6 8L9.5 11.5" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6 8L13 8" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 378 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9.39568 7.6963L6.91032 5.56599C6.65085 5.34358 6.25 5.52795 6.25 5.86969L6.25 10.1303C6.25 10.4721 6.65085 10.6564 6.91032 10.434L9.39568 8.3037C9.58192 8.14406 9.58192 7.85594 9.39568 7.6963Z" fill="#333333"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 324 B |
@@ -0,0 +1,5 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M13 11.7778L13 4" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6.5 4.5L10 8L6.5 11.5" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M10 8L3 8" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 381 B |
@@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.5221 3.21932C11.4366 2.6913 12.5634 2.6913 13.4779 3.21932L18.8653 6.32972C19.7799 6.85774 20.3433 7.83356 20.3433 8.88959V15.1104C20.3433 16.1664 19.7799 17.1423 18.8653 17.6703L13.4779 20.7807C12.5634 21.3087 11.4366 21.3087 10.5221 20.7807L5.13468 17.6703C4.22012 17.1423 3.65673 16.1664 3.65673 15.1104V8.88959C3.65673 7.83356 4.22012 6.85774 5.13467 6.32972L10.5221 3.21932Z" stroke="#333333" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="12" r="3.75" stroke="#333333" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 606 B |
@@ -0,0 +1,4 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="2.5" y="3" width="4" height="10" rx="1" stroke="#333333"/>
|
||||
<rect x="9.5" y="7" width="4" height="6" rx="1" stroke="#333333"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 238 B |
@@ -0,0 +1,145 @@
|
||||
{
|
||||
"appName": "AppFlowy",
|
||||
"defaultUsername": "Jo",
|
||||
"welcomeText": "Benvingut a @:appName",
|
||||
"githubStarText": "Preferit a Github",
|
||||
"subscribeNewsletterText": "Subscriu-me al butlletí",
|
||||
"letsGoButtonText": "Endavant",
|
||||
"title": "Títol",
|
||||
"signUp": {
|
||||
"buttonText": "Registra't",
|
||||
"title": "Registra't a @:appName",
|
||||
"getStartedText": "Comencem",
|
||||
"emptyPasswordError": "La contrasenya no pot ser buida",
|
||||
"repeatPasswordEmptyError": "La contrasenya repetida no pot ser buida",
|
||||
"unmatchedPasswordError": "Les contrasenyes no concorden",
|
||||
"alreadyHaveAnAccount": "Ja tens un compte?",
|
||||
"emailHint": "Correu electrònic",
|
||||
"passwordHint": "Contrasenya",
|
||||
"repeatPasswordHint": "Repeteix la contrasenya"
|
||||
},
|
||||
"signIn": {
|
||||
"loginTitle": "Inicia sessió a @:appName",
|
||||
"loginButtonText": "Inicia sessió",
|
||||
"buttonText": "Inicia sessió",
|
||||
"forgotPassword": "Has oblidat la contrasenya?",
|
||||
"emailHint": "Correu electrònic",
|
||||
"passwordHint": "Contrasenya",
|
||||
"dontHaveAnAccount": "No tens un compte?",
|
||||
"repeatPasswordEmptyError": "La contrasenya repetida no pot ser buida",
|
||||
"unmatchedPasswordError": "Les contrasenyes no concorden"
|
||||
},
|
||||
"workspace": {
|
||||
"create": "Crear un espai de treball",
|
||||
"hint": "espai de treball",
|
||||
"notFoundError": "No s'ha trobat l'espai de treball"
|
||||
},
|
||||
"shareAction": {
|
||||
"buttonText": "Compartir",
|
||||
"workInProgress": "Pròximament",
|
||||
"markdown": "Markdown",
|
||||
"copyLink": "Copiar l'enllaç"
|
||||
},
|
||||
"disclosureAction": {
|
||||
"rename": "Canviar el nom",
|
||||
"delete": "Eliminar",
|
||||
"duplicate": "Duplicar"
|
||||
},
|
||||
"blankPageTitle": "Pàgina en blanc",
|
||||
"newPageText": "Nova pàgina",
|
||||
"trash": {
|
||||
"text": "Paperera",
|
||||
"restoreAll": "Recuperar-ho tot",
|
||||
"deleteAll": "Eliminar-ho tot",
|
||||
"pageHeader": {
|
||||
"fileName": "Nom del fitxer",
|
||||
"lastModified": "Última modificació",
|
||||
"created": "Creat"
|
||||
}
|
||||
},
|
||||
"deletePagePrompt": {
|
||||
"text": "Aquest pàgina es troba a la paperera",
|
||||
"restore": "Recuperar-la",
|
||||
"deletePermanent": "Elimina-la"
|
||||
},
|
||||
"dialogCreatePageNameHint": "Nom de la pàgina",
|
||||
"questionBubble": {
|
||||
"whatsNew": "Què hi ha de nou?",
|
||||
"help": "Ajuda i Suport",
|
||||
"debug": {
|
||||
"name": "Informació de depuració",
|
||||
"success": "S'ha copiat la informació de depuració!",
|
||||
"fail": "No es pot copiar la informació de depuració"
|
||||
}
|
||||
},
|
||||
"menuAppHeader": {
|
||||
"addPageTooltip": "Afegeix ràpidament una pàgina dins",
|
||||
"defaultNewPageName": "Sense títol",
|
||||
"renameDialog": "Canviar el nom"
|
||||
},
|
||||
"toolbar": {
|
||||
"undo": "Desfer",
|
||||
"redo": "Refer",
|
||||
"bold": "Negreta",
|
||||
"italic": "Cursiva",
|
||||
"underline": "Text subratllar",
|
||||
"strike": "Ratllat",
|
||||
"numList": "Llista numerada",
|
||||
"bulletList": "Llista de punts",
|
||||
"checkList": "Llista de comprovació",
|
||||
"inlineCode": "Inserir codi",
|
||||
"quote": "Bloc citat",
|
||||
"header": "Capçalera",
|
||||
"highlight": "Subratllar"
|
||||
},
|
||||
"tooltip": {
|
||||
"lightMode": "Canviar a mode clar",
|
||||
"darkMode": "Canviar a mode fosc"
|
||||
},
|
||||
"contactsPage": {
|
||||
"title": "Contactes",
|
||||
"whatsHappening": "Que passa aquesta setmana?",
|
||||
"addContact": "Afegir un contacte",
|
||||
"editContact": "Editar un contacte"
|
||||
},
|
||||
"button": {
|
||||
"OK": "OK",
|
||||
"Cancel": "Cancel·lar",
|
||||
"signIn": "Iniciar sessió",
|
||||
"signOut": "Tancar sessió",
|
||||
"complete": "Completar",
|
||||
"save": "Guardar"
|
||||
},
|
||||
"label": {
|
||||
"welcome": "Benvingut!",
|
||||
"firstName": "Nom",
|
||||
"middleName": "Segon Nom",
|
||||
"lastName": "Cognom",
|
||||
"stepX": "Pas {X}"
|
||||
},
|
||||
"oAuth": {
|
||||
"err": {
|
||||
"failedTitle": "No s'ha pogut connectar al teu compte.",
|
||||
"failedMsg": "Assegureu-vos que heu completat el procés d'inici de sessió al vostre navegador."
|
||||
},
|
||||
"google": {
|
||||
"title": "Iniciar sessió amb Google",
|
||||
"instruction1": "Per importar els vostres contactes de Google, haureu d'autoritzar aquesta aplicació mitjançant el vostre navegador web.",
|
||||
"instruction2": "Copia aquest codi clicant la icona o seleccionant el text:",
|
||||
"instruction3": "Navega al següent enllaç amb el teu navegador i insereix el codi anterior:",
|
||||
"instruction4": "Pressiona el botó d'avall una vegada hagis completat el registre:"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Configuració",
|
||||
"menu": {
|
||||
"appearance": "Aparença",
|
||||
"language": "Idioma",
|
||||
"open": "Obrir la configuració"
|
||||
},
|
||||
"appearance": {
|
||||
"lightLabel": "Mode Clar",
|
||||
"darkLabel": "Mode Fosc"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"appName": "AppFlowy",
|
||||
"defaultUsername": "Ich",
|
||||
"welcomeText": "Willkommen bei @:appName",
|
||||
"githubStarText": "GitHub Star vergeben",
|
||||
"subscribeNewsletterText": "Abonniere den Newsletter",
|
||||
"letsGoButtonText": "Los geht's",
|
||||
"title": "Titel",
|
||||
"signUp": {
|
||||
"buttonText": "Registrieren",
|
||||
"title": "Registriere dich bei @:appName",
|
||||
"getStartedText": "Erste Schritte",
|
||||
"emptyPasswordError": "Passwort darf nicht leer sein",
|
||||
"repeatPasswordEmptyError": "Passwortwiederholung darf nicht leer sein",
|
||||
"unmatchedPasswordError": "Passwörter stimmen nicht überein",
|
||||
"alreadyHaveAnAccount": "Bereits registriert?",
|
||||
"emailHint": "E-Mail",
|
||||
"passwordHint": "Passwort",
|
||||
"repeatPasswordHint": "Wiederhole Passwort"
|
||||
},
|
||||
"signIn": {
|
||||
"loginTitle": "Bei @:appName einloggen",
|
||||
"loginButtonText": "Anmelden",
|
||||
"buttonText": "Anmelden",
|
||||
"forgotPassword": "Passwort vergessen?",
|
||||
"emailHint": "E-Mail",
|
||||
"passwordHint": "Passwort",
|
||||
"dontHaveAnAccount": "Du besitzt noch kein Konto?",
|
||||
"repeatPasswordEmptyError": "Passwortwiederholung darf nicht leer sein",
|
||||
"unmatchedPasswordError": "Passwörter stimmen nicht überein"
|
||||
},
|
||||
"workspace": {
|
||||
"create": "Arbeitsbereich erstellen",
|
||||
"hint": "Arbeitsbereich",
|
||||
"notFoundError": "Arbeitsbereich nicht gefunden"
|
||||
},
|
||||
"shareAction": {
|
||||
"buttonText": "Teilen",
|
||||
"workInProgress": "Demnächst verfügbar",
|
||||
"markdown": "Markdown",
|
||||
"copyLink": "Link kopieren"
|
||||
},
|
||||
"disclosureAction": {
|
||||
"rename": "Umbenennen",
|
||||
"delete": "Löschen",
|
||||
"duplicate": "Duplizieren"
|
||||
},
|
||||
"blankPageTitle": "Leere Seite",
|
||||
"newPageText": "Neue Seite",
|
||||
"trash": {
|
||||
"text": "Papierkorb",
|
||||
"restoreAll": "Alles wiederherstellen",
|
||||
"deleteAll": "Alles löschen",
|
||||
"pageHeader": {
|
||||
"fileName": "Dateiname",
|
||||
"lastModified": "Letzte Änderung",
|
||||
"created": "Erstellt"
|
||||
}
|
||||
},
|
||||
"deletePagePrompt": {
|
||||
"text": "Diese Seite ist im Papierkorb",
|
||||
"restore": "Seite wiederherstellen",
|
||||
"deletePermanent": "Dauerhaft löschen"
|
||||
},
|
||||
"dialogCreatePageNameHint": "Seitenname",
|
||||
"questionBubble": {
|
||||
"whatsNew": "Was gibt es Neues?",
|
||||
"help": "Hilfe & Support",
|
||||
"debug": {
|
||||
"name": "Debug-Informationen",
|
||||
"success": "Debug-Informationen in die Zwischenablage kopiert!",
|
||||
"fail": "Debug-Informationen können nicht in die Zwischenablage kopiert werden"
|
||||
}
|
||||
},
|
||||
"menuAppHeader": {
|
||||
"addPageTooltip": "Schnell eine Seite innerhalb hinzufügen",
|
||||
"defaultNewPageName": "Unbenannt",
|
||||
"renameDialog": "Umbenennen"
|
||||
},
|
||||
"toolbar": {
|
||||
"undo": "Rückgängig",
|
||||
"redo": "Wiederherstellen",
|
||||
"bold": "Fett",
|
||||
"italic": "Kursiv",
|
||||
"underline": "Unterstreichen",
|
||||
"strike": "Durchstreichen",
|
||||
"numList": "Nummerierte Liste",
|
||||
"bulletList": "Aufzählung",
|
||||
"checkList": "Checkliste",
|
||||
"inlineCode": "Inline-Code",
|
||||
"quote": "Zitat",
|
||||
"header": "Überschrift",
|
||||
"highlight": "Hervorhebung"
|
||||
},
|
||||
"tooltip": {
|
||||
"lightMode": "In den hellen Modus wechseln",
|
||||
"darkMode": "In den dunklen Modus wechseln"
|
||||
},
|
||||
"contactsPage": {
|
||||
"title": "Kontakte",
|
||||
"whatsHappening": "Was geschieht diese Woche?",
|
||||
"addContact": "Kontakt hinzufügen",
|
||||
"editContact": "Kontakt bearbeiten"
|
||||
},
|
||||
"button": {
|
||||
"OK": "OK",
|
||||
"Cancel": "Abbrechen",
|
||||
"signIn": "Anmelden",
|
||||
"signOut": "Abmelden",
|
||||
"complete": "Fertig",
|
||||
"save": "Speichern"
|
||||
},
|
||||
"label": {
|
||||
"welcome": "Willkommen!",
|
||||
"firstName": "Vorname",
|
||||
"middleName": "Zweiter Vorname",
|
||||
"lastName": "Nachname",
|
||||
"stepX": "Schritt {X}"
|
||||
},
|
||||
"oAuth": {
|
||||
"err": {
|
||||
"failedTitle": "Keine Verbindung zu Ihrem Konto möglich.",
|
||||
"failedMsg": "Bitte vergewissern Sie sich, dass Sie den Anmeldevorgang in Ihrem Browser abgeschlossen haben."
|
||||
},
|
||||
"google": {
|
||||
"title": "GOOGLE ANMELDUNG",
|
||||
"instruction1": "Um Ihre Google-Kontakte zu importieren, müssen Sie diese Anwendung über Ihren Webbrowser autorisieren.",
|
||||
"instruction2": "Kopieren Sie diesen Code in Ihre Zwischenablage, indem Sie auf das Symbol klicken oder den Text auswählen:",
|
||||
"instruction3": "Rufen Sie den folgenden Link in Ihrem Webbrowser auf, und geben Sie den obigen Code ein:",
|
||||
"instruction4": "Klicken Sie unten auf die Schaltfläche, wenn Sie die Anmeldung abgeschlossen haben:"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Einstellungen",
|
||||
"menu": {
|
||||
"appearance": "Aussehen",
|
||||
"language": "Sprache",
|
||||
"open": "Einstellungen öffnen"
|
||||
},
|
||||
"appearance": {
|
||||
"lightLabel": "Heller Modus",
|
||||
"darkLabel": "Dunkler Modus"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,5 +141,67 @@
|
||||
"lightLabel": "Light Mode",
|
||||
"darkLabel": "Dark Mode"
|
||||
}
|
||||
},
|
||||
"grid": {
|
||||
"settings": {
|
||||
"filter": "Filter",
|
||||
"sortBy": "Sort by",
|
||||
"Properties": "Properties"
|
||||
},
|
||||
"field": {
|
||||
"hide": "Hide",
|
||||
"insertLeft": "Insert Left",
|
||||
"insertRight": "Insert Right",
|
||||
"duplicate": "Duplicate",
|
||||
"delete": "Delete",
|
||||
"textFieldName": "Text",
|
||||
"checkboxFieldName": "Checkbox",
|
||||
"dateFieldName": "Date",
|
||||
"numberFieldName": "Numbers",
|
||||
"singleSelectFieldName": "Select",
|
||||
"multiSelectFieldName": "Multiselect",
|
||||
"urlFieldName": "URL",
|
||||
"numberFormat": " Number format",
|
||||
"dateFormat": " Date format",
|
||||
"includeTime": " Include time",
|
||||
"dateFormatFriendly": "Month Day,Year",
|
||||
"dateFormatISO": "Year-Month-Day",
|
||||
"dateFormatLocal": "Month/Month/Day",
|
||||
"dateFormatUS": "Month/Month/Day",
|
||||
"timeFormat": " Time format",
|
||||
"invalidTimeFormat": "Invalid format",
|
||||
"timeFormatTwelveHour": "12 hour",
|
||||
"timeFormatTwentyFourHour": "24 hour",
|
||||
"addSelectOption": "Add an option",
|
||||
"optionTitle": "Options",
|
||||
"addOption": "Add option",
|
||||
"editProperty": "Edit property"
|
||||
},
|
||||
"row": {
|
||||
"duplicate": "Duplicate",
|
||||
"delete": "Delete",
|
||||
"textPlaceholder": "Empty",
|
||||
"copyProperty": "Copied property to clipboard"
|
||||
},
|
||||
"selectOption": {
|
||||
"create": "Create",
|
||||
"purpleColor": "Purple",
|
||||
"pinkColor": "Pink",
|
||||
"lightPinkColor": "Light Pink",
|
||||
"orangeColor": "Orange",
|
||||
"yellowColor": "Yellow",
|
||||
"limeColor": "Lime",
|
||||
"greenColor": "Green",
|
||||
"aquaColor": "Aqua",
|
||||
"blueColor": "Blue",
|
||||
"deleteTag": "Delete tag",
|
||||
"colorPannelTitle": "Colors",
|
||||
"pannelTitle": "Select an option or create one",
|
||||
"searchOption": "Search for an option"
|
||||
},
|
||||
"date": {
|
||||
"timeHintTextInTwelveHour": "12:00 AM",
|
||||
"timeHintTextInTwentyFourHour": "12:00"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,75 +1,75 @@
|
||||
{
|
||||
"appName": "AppFlowy",
|
||||
"defaultUsername": "Moi",
|
||||
"welcomeText": "Bienvenu à @:appName",
|
||||
"githubStarText": "Favorier sur GitHub",
|
||||
"welcomeText": "Bienvenue sur @:appName",
|
||||
"githubStarText": "Favoriser sur GitHub",
|
||||
"subscribeNewsletterText": "Abonnez-vous à notre courriel",
|
||||
"letsGoButtonText": "Allons-y",
|
||||
"title": "Titre",
|
||||
"signUp": {
|
||||
"buttonText": "S'abonner",
|
||||
"title": "S'abonner à @:appName",
|
||||
"buttonText": "S'inscrire",
|
||||
"title": "S'inscrire à @:appName",
|
||||
"getStartedText": "Commencer",
|
||||
"emptyPasswordError": "Mot de passe ne doit pas être vide",
|
||||
"emptyPasswordError": "Vous n'avez pas saisi votre mot de passe",
|
||||
"repeatPasswordEmptyError": "Mot de passe ne doit pas être vide",
|
||||
"unmatchedPasswordError": "Les mots de pass ne concordent pas",
|
||||
"unmatchedPasswordError": "Les deux mots de passe ne sont pas identiques",
|
||||
"alreadyHaveAnAccount": "Avez-vous déjà un compte?",
|
||||
"emailHint": "courriel",
|
||||
"passwordHint": "Mot de passe",
|
||||
"repeatPasswordHint": "Resaisir le mot de passe"
|
||||
"repeatPasswordHint": "Ressaisir votre mot de passe"
|
||||
},
|
||||
"signIn": {
|
||||
"loginTitle": "Se connecter à @:appName",
|
||||
"loginTitle": "Connexion à @:appName",
|
||||
"loginButtonText": "Connexion",
|
||||
"buttonText": "Connexion",
|
||||
"buttonText": "Se connecter",
|
||||
"forgotPassword": "Mot de passe oublié?",
|
||||
"emailHint": "courriel",
|
||||
"passwordHint": "Mot de passe",
|
||||
"dontHaveAnAccount": "Vous n'avez pas de compte?",
|
||||
"repeatPasswordEmptyError": "Mot de passe ne doit pas être vide",
|
||||
"unmatchedPasswordError": "Les mots de passe ne concordent pas"
|
||||
"unmatchedPasswordError": "Les deux mots de passe ne sont pas identiques"
|
||||
},
|
||||
"workspace": {
|
||||
"create": "Créer une espace de travail",
|
||||
"hint": "espace de travail",
|
||||
"notFoundError": "Espace de travail non trouvé"
|
||||
"create": "Créer un espace de travail",
|
||||
"hint": "Espace de travail",
|
||||
"notFoundError": "Espace de travail introuvable"
|
||||
},
|
||||
"shareAction": {
|
||||
"buttonText": "Partager",
|
||||
"workInProgress": "Bientôt disponible",
|
||||
"markdown": "Markdown",
|
||||
"copyLink": "Copier le liens"
|
||||
"copyLink": "Copier le lien"
|
||||
},
|
||||
"disclosureAction": {
|
||||
"rename": "Renommer",
|
||||
"delete": "Supprimer",
|
||||
"duplicate": "Dupliquer"
|
||||
},
|
||||
"blankPageTitle": "Page vide",
|
||||
"blankPageTitle": "Page vierge",
|
||||
"newPageText": "Nouvelle page",
|
||||
"trash": {
|
||||
"text": "Poubelle",
|
||||
"text": "Corbeille",
|
||||
"restoreAll": "Tout récupérer",
|
||||
"deleteAll": "Tout supprimer",
|
||||
"pageHeader": {
|
||||
"fileName": "Nom de fichier",
|
||||
"lastModified": "Dernière modification",
|
||||
"created": "Crée"
|
||||
"created": "Créé"
|
||||
}
|
||||
},
|
||||
"deletePagePrompt": {
|
||||
"text": "Cette page est dans la poubelle",
|
||||
"text": "Cette page est dans la corbeille",
|
||||
"restore": "Récupérer la page",
|
||||
"deletePermanent": "Supprimer en permanence"
|
||||
"deletePermanent": "Supprimer définitivement"
|
||||
},
|
||||
"dialogCreatePageNameHint": "Nom de la page",
|
||||
"questionBubble": {
|
||||
"whatsNew": "Quoi de neuf?",
|
||||
"help": "Aide & Support Technique",
|
||||
"whatsNew": "Nouveautés",
|
||||
"help": "Aide et Support Technique",
|
||||
"debug": {
|
||||
"name": "Info du système",
|
||||
"name": "Infos du système",
|
||||
"success": "Info copié!",
|
||||
"fail": "Incapable de copié l'info"
|
||||
"fail": "Impossible de copier l'info"
|
||||
}
|
||||
},
|
||||
"menuAppHeader": {
|
||||
@@ -79,67 +79,67 @@
|
||||
},
|
||||
"toolbar": {
|
||||
"undo": "Annuler",
|
||||
"redo": "Refaire",
|
||||
"redo": "Rétablir",
|
||||
"bold": "Gras",
|
||||
"italic": "Italique",
|
||||
"underline": "Souligné",
|
||||
"underline": "Souligner",
|
||||
"strike": "Barré",
|
||||
"numList": "Liste numérotée",
|
||||
"bulletList": "Liste à puces",
|
||||
"checkList": "Liste de contrôle",
|
||||
"inlineCode": "Code en ligne",
|
||||
"quote": "Citation",
|
||||
"header": "en-tête",
|
||||
"header": "En-tête",
|
||||
"highlight": "Surligner"
|
||||
},
|
||||
"tooltip": {
|
||||
"lightMode": "Aller en mode claire",
|
||||
"darkMode": "Aller en mode foncé"
|
||||
"lightMode": "Passer en mode clair",
|
||||
"darkMode": "Passer en mode sombre"
|
||||
},
|
||||
"contactsPage": {
|
||||
"title": "Contacts",
|
||||
"whatsHappening": "Quoi de neuf?",
|
||||
"addContact": "Ajouter Contact",
|
||||
"editContact": "Éditer Contact"
|
||||
"addContact": "Ajouter un contact",
|
||||
"editContact": "Modifier le contact"
|
||||
},
|
||||
"button": {
|
||||
"OK": "OK",
|
||||
"Cancel": "Annuler",
|
||||
"signIn": "Connecter",
|
||||
"signOut": "Déconnecter",
|
||||
"complete": "Complêt",
|
||||
"signIn": "Se connecter",
|
||||
"signOut": "Se déconnecter",
|
||||
"complete": "Achevé",
|
||||
"save": "Sauvegarder"
|
||||
},
|
||||
"label": {
|
||||
"welcome": "Bienvenu!",
|
||||
"welcome": "Bienvenue!",
|
||||
"firstName": "Prénom",
|
||||
"middleName": "Nom",
|
||||
"middleName": "Deuxième nom",
|
||||
"lastName": "Nom de famille",
|
||||
"stepX": "Étape {X}"
|
||||
},
|
||||
"oAuth": {
|
||||
"err": {
|
||||
"failedTitle": "Incapable de connecter à votre compte.",
|
||||
"failedTitle": "Incapable de se connecter à votre compte.",
|
||||
"failedMsg": "SVP vous assurrez d'avoir complèté le processus d'enregistrement dans votre fureteur."
|
||||
},
|
||||
"google": {
|
||||
"title": "S'identifier avec Google",
|
||||
"instruction1": "Pour importer vos contacts Google, vous devez autoriser cette application à l'aide de votre navigateur Web.",
|
||||
"instruction2": "Copiez ce code dans votre presse-papiers en cliquant sur l'icône ou en sélectionnant le texte :",
|
||||
"instruction3": "Accédez au lien suivant dans votre navigateur Web et saisissez le code ci-dessus :",
|
||||
"instruction4": "Appuyez sur le bouton ci-dessous lorsque vous avez terminé votre inscription :"
|
||||
"instruction2": "Copiez ce code dans votre presse-papiers en cliquant sur l'icône ou en sélectionnant le texte:",
|
||||
"instruction3": "Accédez au lien suivant dans votre navigateur Web et saisissez le code ci-dessus:",
|
||||
"instruction4": "Appuyez sur le bouton ci-dessous lorsque vous avez terminé votre inscription:"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Réglages",
|
||||
"title": "Paramètres",
|
||||
"menu": {
|
||||
"appearance": "Apparence",
|
||||
"language": "Langue",
|
||||
"open": "ouvrir les paramètres"
|
||||
"open": "Ouvrir les paramètres"
|
||||
},
|
||||
"appearance": {
|
||||
"lightLabel": "Mode claire",
|
||||
"darkLabel": "Mode foncé"
|
||||
"lightLabel": "Mode clair",
|
||||
"darkLabel": "Mode sombre"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
{
|
||||
"appName": "AppFlowy",
|
||||
"defaultUsername": "Moi",
|
||||
"welcomeText": "Bienvenue sur @:appName",
|
||||
"githubStarText": "Favoriser sur GitHub",
|
||||
"subscribeNewsletterText": "S'inscrire à la Newsletter",
|
||||
"letsGoButtonText": "Allons-y",
|
||||
"title": "Titre",
|
||||
"signUp": {
|
||||
"buttonText": "S'inscrire",
|
||||
"title": "Inscrivez-vous sur @:appName",
|
||||
"getStartedText": "Commencer",
|
||||
"emptyPasswordError": "Vous n'avez pas saisi votre mot de passe",
|
||||
"repeatPasswordEmptyError": "Vous n'avez pas ressaisi votre mot de passe",
|
||||
"unmatchedPasswordError": "Les deux mots de passe ne sont pas identiques",
|
||||
"alreadyHaveAnAccount": "Avez-vous déjà un compte ?",
|
||||
"emailHint": "Email",
|
||||
"passwordHint": "Mot de passe",
|
||||
"repeatPasswordHint": "Ressaisir votre mot de passe"
|
||||
},
|
||||
"signIn": {
|
||||
"loginTitle": "Connexion à @:appName",
|
||||
"loginButtonText": "Connexion",
|
||||
"buttonText": "Se connecter",
|
||||
"forgotPassword": "Mot de passe oublié ?",
|
||||
"emailHint": "Email",
|
||||
"passwordHint": "Mot de passe",
|
||||
"dontHaveAnAccount": "Vous n'avez pas encore créé votre compte ?",
|
||||
"repeatPasswordEmptyError": "Vous n'avez pas ressaisi votre mot de passe",
|
||||
"unmatchedPasswordError": "Les deux mots de passe ne sont pas identiques"
|
||||
},
|
||||
"workspace": {
|
||||
"create": "Créer un espace de travail",
|
||||
"hint": "Espace de travail",
|
||||
"notFoundError": "Espace de travail introuvable"
|
||||
},
|
||||
"shareAction": {
|
||||
"buttonText": "Partager",
|
||||
"workInProgress": "Bientôt disponible",
|
||||
"markdown": "Markdown",
|
||||
"copyLink": "Copier le lien"
|
||||
},
|
||||
"disclosureAction": {
|
||||
"rename": "Renommer",
|
||||
"delete": "Supprimer",
|
||||
"duplicate": "Dupliquer"
|
||||
},
|
||||
"blankPageTitle": "Page vierge",
|
||||
"newPageText": "Nouvelle page",
|
||||
"trash": {
|
||||
"text": "Corbeille",
|
||||
"restoreAll": "Restaurer tout",
|
||||
"deleteAll": "Supprimer tout",
|
||||
"pageHeader": {
|
||||
"fileName": "Nom de fichier",
|
||||
"lastModified": "Dernière modification",
|
||||
"created": "Créé"
|
||||
}
|
||||
},
|
||||
"deletePagePrompt": {
|
||||
"text": "Cette page a été supprimée, vous pouvez la retrouver dans la corbeille",
|
||||
"restore": "Restaurer la page",
|
||||
"deletePermanent": "Supprimer définitivement"
|
||||
},
|
||||
"dialogCreatePageNameHint": "Nom de la page",
|
||||
"questionBubble": {
|
||||
"whatsNew": "Nouveautés",
|
||||
"help": "Aide et Support",
|
||||
"debug": {
|
||||
"name": "Informations de Débogage",
|
||||
"success": "Informations de Débogage copiées dans le presse-papiers!",
|
||||
"fail": "Impossible de copier les informations de Débogage dans le presse-papiers"
|
||||
}
|
||||
},
|
||||
"menuAppHeader": {
|
||||
"addPageTooltip": "Ajoutez rapidement une page à l'intérieur",
|
||||
"defaultNewPageName": "Sans-titre",
|
||||
"renameDialog": "Renommer"
|
||||
},
|
||||
"toolbar": {
|
||||
"undo": "Annuler",
|
||||
"redo": "Rétablir",
|
||||
"bold": "Gras",
|
||||
"italic": "Italique",
|
||||
"underline": "Souligner",
|
||||
"strike": "Barré",
|
||||
"numList": "Liste numérotée",
|
||||
"bulletList": "Liste à puces",
|
||||
"checkList": "To-Do List",
|
||||
"inlineCode": "Code",
|
||||
"quote": "Bloc de citation",
|
||||
"header": "En-tête",
|
||||
"highlight": "Surligner"
|
||||
},
|
||||
"tooltip": {
|
||||
"lightMode": "Passer en mode clair",
|
||||
"darkMode": "Passer en mode sombre"
|
||||
},
|
||||
"contactsPage": {
|
||||
"title": "Contacts",
|
||||
"whatsHappening": "Que se passe-t-il cette semaine ?",
|
||||
"addContact": "Ajouter un contact",
|
||||
"editContact": "Modifier le contact"
|
||||
},
|
||||
"button": {
|
||||
"OK": "OK",
|
||||
"Cancel": "Annuler",
|
||||
"signIn": "Se connecter",
|
||||
"signOut": "Se déconnecter",
|
||||
"complete": "Achevé",
|
||||
"save": "Enregistrer"
|
||||
},
|
||||
"label": {
|
||||
"welcome": "Bienvenue !",
|
||||
"firstName": "Prénom",
|
||||
"middleName": "Deuxième prénom",
|
||||
"lastName": "Nom",
|
||||
"stepX": "Étape {X}"
|
||||
},
|
||||
"oAuth": {
|
||||
"err": {
|
||||
"failedTitle": "Impossible de se connecter à votre compte.",
|
||||
"failedMsg": "Assurez-vous d'avoir terminé le processus de connexion dans votre navigateur."
|
||||
},
|
||||
"google": {
|
||||
"title": "CONNEXION GOOGLE",
|
||||
"instruction1": "Pour importer vos contacts Google, vous devez autoriser cette application à l'aide de votre navigateur web.",
|
||||
"instruction2": "Copiez ce code dans votre presse-papiers en cliquant sur l'icône ou en sélectionnant le texte:",
|
||||
"instruction3": "Accédez au lien suivant dans votre navigateur web et saisissez le code ci-dessus:",
|
||||
"instruction4": "Appuyez sur le bouton ci-dessous lorsque vous avez terminé votre inscription:"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Paramètres",
|
||||
"menu": {
|
||||
"appearance": "Apparence",
|
||||
"language": "Langue",
|
||||
"open": "Ouvrir les paramètres"
|
||||
},
|
||||
"appearance": {
|
||||
"lightLabel": "Mode clair",
|
||||
"darkLabel": "Mode sombre"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
{
|
||||
"appName": "AppFlowy",
|
||||
"defaultUsername": "Én",
|
||||
"welcomeText": "Üdvözöl az @:appName",
|
||||
"githubStarText": "GitHub csillagozás",
|
||||
"subscribeNewsletterText": "Iratkozz fel a hírlevelünkre",
|
||||
"letsGoButtonText": "Vágjunk bele",
|
||||
"title": "Cím",
|
||||
"signUp": {
|
||||
"buttonText": "Regisztráció",
|
||||
"title": "Regisztrálj az @:appName -ra",
|
||||
"getStartedText": "Kezdés",
|
||||
"emptyPasswordError": "A jelszó nem lehet üres",
|
||||
"repeatPasswordEmptyError": "A jelszó megerősítése nem lehet üres",
|
||||
"unmatchedPasswordError": "A jelszavak nem egyeznek",
|
||||
"alreadyHaveAnAccount": "Rendelkezel már fiókkal?",
|
||||
"emailHint": "Email",
|
||||
"passwordHint": "Jelszó",
|
||||
"repeatPasswordHint": "Jelszó megerősítése"
|
||||
},
|
||||
"signIn": {
|
||||
"loginTitle": "Bejelentkezés az @:appName -ba",
|
||||
"loginButtonText": "Belépés",
|
||||
"buttonText": "Bejelentkezés",
|
||||
"forgotPassword": "Elfelejtett jelszó?",
|
||||
"emailHint": "Email",
|
||||
"passwordHint": "Jelszó",
|
||||
"dontHaveAnAccount": "Még nincs fiókod?",
|
||||
"repeatPasswordEmptyError": "A jelszó megerősítése nem lehet üres",
|
||||
"unmatchedPasswordError": "A jelszavak nem egyeznek"
|
||||
},
|
||||
"workspace": {
|
||||
"create": "Új munkaterület létrehozása",
|
||||
"hint": "munkaterület",
|
||||
"notFoundError": "munkaterület nem található"
|
||||
},
|
||||
"shareAction": {
|
||||
"buttonText": "Megosztás",
|
||||
"workInProgress": "Hamarosan érkezik...",
|
||||
"markdown": "Markdown",
|
||||
"copyLink": "Link másolása"
|
||||
},
|
||||
"disclosureAction": {
|
||||
"rename": "Átnevezés",
|
||||
"delete": "Törlés",
|
||||
"duplicate": "Duplikálás"
|
||||
},
|
||||
"blankPageTitle": "Üres oldal",
|
||||
"newPageText": "Új oldal",
|
||||
"trash": {
|
||||
"text": "Kuka",
|
||||
"restoreAll": "Összes visszaállítása",
|
||||
"deleteAll": "Összes törlése",
|
||||
"pageHeader": {
|
||||
"fileName": "Fájlnév",
|
||||
"lastModified": "Utoljára módosítva",
|
||||
"created": "Létrehozva"
|
||||
}
|
||||
},
|
||||
"deletePagePrompt": {
|
||||
"text": "Ez az oldal a kukában van",
|
||||
"restore": "Oldal visszaállítása",
|
||||
"deletePermanent": "Végleges törlés"
|
||||
},
|
||||
"dialogCreatePageNameHint": "Oldalnév",
|
||||
"questionBubble": {
|
||||
"whatsNew": "Újdonságok",
|
||||
"help": "Segítség & Támogatás",
|
||||
"debug": {
|
||||
"name": "Debug Információ",
|
||||
"success": "Debug információ a vágólapra másolva",
|
||||
"fail": "A Debug információ nem másolható a vágólapra"
|
||||
}
|
||||
},
|
||||
"menuAppHeader": {
|
||||
"addPageTooltip": "Belső oldal hozzáadása",
|
||||
"defaultNewPageName": "Névtelen",
|
||||
"renameDialog": "Átnevezés"
|
||||
},
|
||||
"toolbar": {
|
||||
"undo": "Vissza",
|
||||
"redo": "Előre",
|
||||
"bold": "Félkövér",
|
||||
"italic": "Dőlt",
|
||||
"underline": "Aláhúzott",
|
||||
"strike": "Áthúzott",
|
||||
"numList": "Számozott lista",
|
||||
"bulletList": "Felsorolás",
|
||||
"checkList": "Ellenőrző lista",
|
||||
"inlineCode": "Inline kód",
|
||||
"quote": "Idézet",
|
||||
"header": "Címsor",
|
||||
"highlight": "Kiemelés"
|
||||
},
|
||||
"tooltip": {
|
||||
"lightMode": "Világos mód",
|
||||
"darkMode": "Éjjeli mód"
|
||||
},
|
||||
"contactsPage": {
|
||||
"title": "Kontaktok",
|
||||
"whatsHappening": "Heti újdonságok",
|
||||
"addContact": "Új Kontakt",
|
||||
"editContact": "Kontakt Szerkesztése"
|
||||
},
|
||||
"button": {
|
||||
"OK": "OK",
|
||||
"Cancel": "Mégse",
|
||||
"signIn": "Bejelentkezés",
|
||||
"signOut": "Kijelentkezés",
|
||||
"complete": "Kész",
|
||||
"save": "Mentés"
|
||||
},
|
||||
"label": {
|
||||
"welcome": "Üdvözlünk!",
|
||||
"firstName": "Keresztnév",
|
||||
"middleName": "Középső név",
|
||||
"lastName": "Vezetéknév",
|
||||
"stepX": "{X}. lépés"
|
||||
},
|
||||
"oAuth": {
|
||||
"err": {
|
||||
"failedTitle": "Sikertelen bejelentkezés.",
|
||||
"failedMsg": "Kérjük győződj meg róla, hogy elvégezted a bejelentkezési folyamatot a böngésződben"
|
||||
},
|
||||
"google": {
|
||||
"title": "Bejelentkezés Google-al",
|
||||
"instruction1": "Ahhoz, hogy hozzáférj a Google Kontaktjaidhoz, kérjük hatalmazd fel ezt az alkalmazást a böngésződben.",
|
||||
"instruction2": "Másold ezt a kódot a vágólapra az ikonra kattintással vagy a szöveg kijelölésével:",
|
||||
"instruction3": "Nyisd meg ezt a linket a böngésződben, és írjd be a fenti kódot:",
|
||||
"instruction4": "Nyomd meg az alábbi gombot, ha elvégezted a registrációt:"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Beállítások",
|
||||
"menu": {
|
||||
"appearance": "Megjelenés",
|
||||
"language": "Nyelv",
|
||||
"open": "Beállítások megnyitása"
|
||||
},
|
||||
"appearance": {
|
||||
"lightLabel": "Világos mód",
|
||||
"darkLabel": "Éjjeli mód"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"appName": "AppFlowy",
|
||||
"defaultUsername": "Me",
|
||||
"welcomeText": "Bem vindo @:appName",
|
||||
"githubStarText": "Star on GitHub",
|
||||
"subscribeNewsletterText": "Se inscreva na Newsletter",
|
||||
"letsGoButtonText": "Vamos lá",
|
||||
"title": "Título",
|
||||
"signUp": {
|
||||
"buttonText": "Inscreve-se",
|
||||
"title": "Inscrever-se @:appName",
|
||||
"getStartedText": "Começar",
|
||||
"emptyPasswordError": "Senha não pode ser em branco.",
|
||||
"repeatPasswordEmptyError": "Confirmar a senha não pode ser em branco.",
|
||||
"unmatchedPasswordError": "As senhas não conferem.",
|
||||
"alreadyHaveAnAccount": "Já possui uma conta?",
|
||||
"emailHint": "Email",
|
||||
"passwordHint": "Senha",
|
||||
"repeatPasswordHint": "Confirme a senha"
|
||||
},
|
||||
"signIn": {
|
||||
"loginTitle": "Login to @:appName",
|
||||
"loginButtonText": "Login",
|
||||
"buttonText": "Entre",
|
||||
"forgotPassword": "Esqueceu a senha?",
|
||||
"emailHint": "Email",
|
||||
"passwordHint": "Senha",
|
||||
"dontHaveAnAccount": "Não possui uma conta?",
|
||||
"repeatPasswordEmptyError": "Confirmar a senha não pode ser em branco.",
|
||||
"unmatchedPasswordError": "As senhas não conferem."
|
||||
},
|
||||
"workspace": {
|
||||
"create": "Crie uma área de trabalho",
|
||||
"hint": "área de trabalho",
|
||||
"notFoundError": "Área de trabalho não encontrada"
|
||||
},
|
||||
"shareAction": {
|
||||
"buttonText": "Compartilhar",
|
||||
"workInProgress": "Em breve",
|
||||
"markdown": "Markdown",
|
||||
"copyLink": "Copiar o link"
|
||||
},
|
||||
"disclosureAction": {
|
||||
"rename": "Renomear",
|
||||
"delete": "Deletar",
|
||||
"duplicate": "Duplicar"
|
||||
},
|
||||
"blankPageTitle": "Página em branco",
|
||||
"newPageText": "Nova página",
|
||||
"trash": {
|
||||
"text": "Lixeira",
|
||||
"restoreAll": "Restaurar todos",
|
||||
"deleteAll": "Deletar todos",
|
||||
"pageHeader": {
|
||||
"fileName": "Nome do arquivo",
|
||||
"lastModified": "Última modificação",
|
||||
"created": "Criado"
|
||||
}
|
||||
},
|
||||
"deletePagePrompt": {
|
||||
"text": "Está página está na lixeira",
|
||||
"restore": "Restaurar a oágina",
|
||||
"deletePermanent": "Deletar permanentemente"
|
||||
},
|
||||
"dialogCreatePageNameHint": "Nome da página",
|
||||
"questionBubble": {
|
||||
"whatsNew": "O que há de novo?",
|
||||
"help": "Ajuda & Suporte",
|
||||
"debug": {
|
||||
"name": "Informação de debug",
|
||||
"success": "Copiar informação de debug para o clipboard!",
|
||||
"fail": "Falha em copiar a informação de debug para o clipboard"
|
||||
}
|
||||
},
|
||||
"menuAppHeader": {
|
||||
"addPageTooltip": "Adicione uma nova página.",
|
||||
"defaultNewPageName": "Sem título",
|
||||
"renameDialog": "Renomear"
|
||||
},
|
||||
"toolbar": {
|
||||
"undo": "Desfazer",
|
||||
"redo": "Refazer",
|
||||
"bold": "Negrito",
|
||||
"italic": "Itálico",
|
||||
"underline": "Sublinhado",
|
||||
"strike": "Tachado",
|
||||
"numList": "Lista numerada",
|
||||
"bulletList": "Lista com marcadores",
|
||||
"checkList": "Check List",
|
||||
"inlineCode": "Embutir código",
|
||||
"quote": "Citação em bloco",
|
||||
"header": "Cabeçalho",
|
||||
"highlight": "Realçar"
|
||||
},
|
||||
"tooltip": {
|
||||
"lightMode": "Mudar para o modo Claro.",
|
||||
"darkMode": "Mudar para o modo Escuro."
|
||||
},
|
||||
"contactsPage": {
|
||||
"title": "Contatos",
|
||||
"whatsHappening": "O que está acontecendo essa semana?",
|
||||
"addContact": "Adicionar um contato",
|
||||
"editContact": "Editar um contato"
|
||||
},
|
||||
"button": {
|
||||
"OK": "OK",
|
||||
"Cancel": "Canelar",
|
||||
"signIn": "Entrar",
|
||||
"signOut": "Sair",
|
||||
"complete": "Completar",
|
||||
"save": "Salvar"
|
||||
},
|
||||
"label": {
|
||||
"welcome": "Bem vindo!",
|
||||
"firstName": "Primeiro Nome",
|
||||
"middleName": "Nome do Meio",
|
||||
"lastName": "Último Nome",
|
||||
"stepX": "Passo {X}"
|
||||
},
|
||||
"oAuth": {
|
||||
"err": {
|
||||
"failedTitle": "Erro ao conectar a sua conta.",
|
||||
"failedMsg": "Verifique se você concluiu o processo de login em seu navegador."
|
||||
},
|
||||
"google": {
|
||||
"title": "GOOGLE SIGN-IN",
|
||||
"instruction1": "Para importar seus Contatos do Google, você precisará autorizar este aplicativo usando seu navegador web.",
|
||||
"instruction2": "Copie este código para sua área de transferência clicando no ícone ou selecionando o texto:",
|
||||
"instruction3": "Navegue até o link a seguir em seu navegador e digite o código acima:",
|
||||
"instruction4": "Pressione o botão abaixo ao concluir a inscrição:"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Configurações",
|
||||
"menu": {
|
||||
"appearance": "Aparência",
|
||||
"language": "Idioma",
|
||||
"open": "Abrir as Configurações"
|
||||
},
|
||||
"appearance": {
|
||||
"lightLabel": "Modo Claro",
|
||||
"darkLabel": "Modo Escuro"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
{
|
||||
"appName": "AppFlowy",
|
||||
"defaultUsername": "Ben",
|
||||
"welcomeText": "@:appName'e Hoş Geldiniz!",
|
||||
"githubStarText": "GitHub Yıldızı!",
|
||||
"subscribeNewsletterText": "Bültene Abone Ol",
|
||||
"letsGoButtonText": "Hadi başlayalım.",
|
||||
"title": "Başlık",
|
||||
"signUp": {
|
||||
"buttonText": "Kayıt Ol",
|
||||
"title": "@:appName'e kaydolun.",
|
||||
"getStartedText": "başlayalım",
|
||||
"emptyPasswordError": "Parola boş olamaz",
|
||||
"repeatPasswordEmptyError": "Parola (tekrar) boş olamaz",
|
||||
"unmatchedPasswordError": "Parolalar eşleşmiyor",
|
||||
"alreadyHaveAnAccount": "Zaten hesabınız var mı?",
|
||||
"emailHint": "E-Posta",
|
||||
"passwordHint": "Parola",
|
||||
"repeatPasswordHint": "Tekrar parola"
|
||||
},
|
||||
"signIn": {
|
||||
"loginTitle": "@:appName oturum aç",
|
||||
"loginButtonText": "Giriş",
|
||||
"buttonText": "Oturum Aç",
|
||||
"forgotPassword": "Parolanızı mı Unuttunuz?",
|
||||
"emailHint": "E-Posta",
|
||||
"passwordHint": "Parola",
|
||||
"dontHaveAnAccount": "Hesabınız yok mu?",
|
||||
"repeatPasswordEmptyError": "Parola (tekrar) boş olamaz",
|
||||
"unmatchedPasswordError": "Parolalar eşleşmiyor"
|
||||
},
|
||||
"workspace": {
|
||||
"create": "Çalışma alanı oluştur",
|
||||
"hint": "Çalışma alanı",
|
||||
"notFoundError": "Çalışma alanı bulunamadı"
|
||||
},
|
||||
"shareAction": {
|
||||
"buttonText": "Paylaş",
|
||||
"workInProgress": "Yakında",
|
||||
"markdown": "Markdown",
|
||||
"copyLink": "Link'i Kopyala"
|
||||
},
|
||||
"disclosureAction": {
|
||||
"rename": "Yeniden adlandır",
|
||||
"delete": "Sil",
|
||||
"duplicate": "Çoğalt"
|
||||
},
|
||||
"blankPageTitle": "Boş sayfa",
|
||||
"newPageText": "Yeni sayfa",
|
||||
"trash": {
|
||||
"text": "Çöp",
|
||||
"restoreAll": "Geri Yükle",
|
||||
"deleteAll": "Sil",
|
||||
"pageHeader": {
|
||||
"fileName": "Dosya adı",
|
||||
"lastModified": "Son Değiştirme",
|
||||
"created": "Oluşturuldu"
|
||||
}
|
||||
},
|
||||
"deletePagePrompt": {
|
||||
"text": "Bu sayfa Çöp Kutusu'nda",
|
||||
"restore": "Sayfayı geri yükle",
|
||||
"deletePermanent": "Kalıcı olarak sil"
|
||||
},
|
||||
"dialogCreatePageNameHint": "Sayfa adı",
|
||||
"questionBubble": {
|
||||
"whatsNew": "Yeni ne var?",
|
||||
"help": "Yardım & Destek",
|
||||
"debug": {
|
||||
"name": "Hata Ayıklama",
|
||||
"success": "Hata ayıklama bilgileri panoya kopyalandı!",
|
||||
"fail": "Hata ayıklama bilgileri panoya kopyalanamıyor"
|
||||
}
|
||||
},
|
||||
"menuAppHeader": {
|
||||
"addPageTooltip": "Yeni bir sayfa ekleyin",
|
||||
"defaultNewPageName": "Başlıksız",
|
||||
"renameDialog": "Yeniden adlandır"
|
||||
},
|
||||
"toolbar": {
|
||||
"undo": "Geri",
|
||||
"redo": "İleri",
|
||||
"bold": "Kalın",
|
||||
"italic": "İtalik",
|
||||
"underline": "Altı Çizili",
|
||||
"strike": "Üstü Çizili",
|
||||
"numList": "Numaralı Liste",
|
||||
"bulletList": "Madde İşaretli Liste",
|
||||
"checkList": "Yapılacaklar Listesi",
|
||||
"inlineCode": "Kod",
|
||||
"quote": "Alıntı",
|
||||
"header": "Başlık",
|
||||
"highlight": "Vurgu"
|
||||
},
|
||||
"tooltip": {
|
||||
"lightMode": "Aydınlık Mod'a Geç",
|
||||
"darkMode": "Karanlık Mod'a Geç"
|
||||
},
|
||||
"contactsPage": {
|
||||
"title": "İletişim",
|
||||
"whatsHappening": "Bu hafta neler var?",
|
||||
"addContact": "Kişi Ekle",
|
||||
"editContact": "Kişiyi Düzenle"
|
||||
},
|
||||
"button": {
|
||||
"OK": "TAMAM",
|
||||
"Cancel": "İptal",
|
||||
"signIn": "Oturum Aç",
|
||||
"signOut": "Oturum Kapat",
|
||||
"complete": "Tamamlandı",
|
||||
"save": "Kaydet"
|
||||
},
|
||||
"label": {
|
||||
"welcome": "Merhaba!",
|
||||
"firstName": "Ad",
|
||||
"middleName": "İkinci Ad",
|
||||
"lastName": "Soyad",
|
||||
"stepX": "Aşama {X}"
|
||||
},
|
||||
"oAuth": {
|
||||
"err": {
|
||||
"failedTitle": "Hesabınıza bağlanılamıyor.",
|
||||
"failedMsg": "Lütfen, tarayıcınızda oturum açma işlemini tamamladığınızdan emin olun."
|
||||
},
|
||||
"google": {
|
||||
"title": "GOOGLE OTURUM AÇMA",
|
||||
"instruction1": "Google Kişilerinizi içe aktarmak için web tarayıcınızı kullanarak bu uygulamaya izin vermeniz gerekir.",
|
||||
"instruction2": "Simgeyi tıklayarak veya metni seçerek bu kodu panonuza kopyalayın:",
|
||||
"instruction3": "Web tarayıcınızda aşağıdaki bağlantıyı açın ve yukarıdaki kodu girin:",
|
||||
"instruction4": "Kayıt işlemini tamamladığınızda aşağıdaki düğmeye basın:"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Ayarlar",
|
||||
"menu": {
|
||||
"appearance": "Görünüm",
|
||||
"language": "Dil",
|
||||
"open": "Ayarları Aç"
|
||||
},
|
||||
"appearance": {
|
||||
"lightLabel": "Aydınlık Mod",
|
||||
"darkLabel": "Karanlık Mod"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
class CocoaWindowChannel {
|
||||
CocoaWindowChannel._();
|
||||
|
||||
final MethodChannel _channel = const MethodChannel("flutter/cocoaWindow");
|
||||
|
||||
static final CocoaWindowChannel instance = CocoaWindowChannel._();
|
||||
|
||||
Future<void> setWindowPosition(Offset offset) async {
|
||||
await _channel.invokeMethod("setWindowPosition", [offset.dx, offset.dy]);
|
||||
}
|
||||
|
||||
Future<List<double>> getWindowPosition() async {
|
||||
final raw = await _channel.invokeMethod("getWindowPosition");
|
||||
final arr = raw as List<dynamic>;
|
||||
final List<double> result = arr.map((s) => s as double).toList();
|
||||
return result;
|
||||
}
|
||||
|
||||
Future<void> zoom() async {
|
||||
await _channel.invokeMethod("zoom");
|
||||
}
|
||||
}
|
||||
|
||||
class MoveWindowDetector extends StatefulWidget {
|
||||
const MoveWindowDetector({Key? key, this.child}) : super(key: key);
|
||||
|
||||
final Widget? child;
|
||||
|
||||
@override
|
||||
_MoveWindowDetectorState createState() => _MoveWindowDetectorState();
|
||||
}
|
||||
|
||||
class _MoveWindowDetectorState extends State<MoveWindowDetector> {
|
||||
double winX = 0;
|
||||
double winY = 0;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (!Platform.isMacOS) {
|
||||
return widget.child ?? Container();
|
||||
}
|
||||
return GestureDetector(
|
||||
// https://stackoverflow.com/questions/52965799/flutter-gesturedetector-not-working-with-containers-in-stack
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onDoubleTap: () async {
|
||||
await CocoaWindowChannel.instance.zoom();
|
||||
},
|
||||
onPanStart: (DragStartDetails details) {
|
||||
winX = details.globalPosition.dx;
|
||||
winY = details.globalPosition.dy;
|
||||
},
|
||||
onPanUpdate: (DragUpdateDetails details) async {
|
||||
final windowPos = await CocoaWindowChannel.instance.getWindowPosition();
|
||||
final double dx = windowPos[0];
|
||||
final double dy = windowPos[1];
|
||||
final deltaX = details.globalPosition.dx - winX;
|
||||
final deltaY = details.globalPosition.dy - winY;
|
||||
await CocoaWindowChannel.instance.setWindowPosition(Offset(dx + deltaX, dy - deltaY));
|
||||
},
|
||||
child: widget.child,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
import 'package:flowy_log/flowy_log.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-net/network_state.pb.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class NetworkMonitor {
|
||||
class NetworkListener {
|
||||
final Connectivity _connectivity = Connectivity();
|
||||
late StreamSubscription<ConnectivityResult> _connectivitySubscription;
|
||||
|
||||
NetworkMonitor() {
|
||||
NetworkListener() {
|
||||
_connectivitySubscription = _connectivity.onConnectivityChanged.listen(_updateConnectionStatus);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
import 'package:flowy_sdk/protobuf/dart-notify/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
|
||||
import 'package:flowy_sdk/rust_stream.dart';
|
||||
|
||||
// User
|
||||
typedef UserNotificationCallback = void Function(UserNotification, Either<Uint8List, FlowyError>);
|
||||
|
||||
class UserNotificationParser extends NotificationParser<UserNotification, FlowyError> {
|
||||
@@ -17,10 +21,11 @@ class UserNotificationParser extends NotificationParser<UserNotification, FlowyE
|
||||
);
|
||||
}
|
||||
|
||||
typedef NotificationCallback = void Function(FolderNotification, Either<Uint8List, FlowyError>);
|
||||
// Folder
|
||||
typedef FolderNotificationCallback = void Function(FolderNotification, Either<Uint8List, FlowyError>);
|
||||
|
||||
class FolderNotificationParser extends NotificationParser<FolderNotification, FlowyError> {
|
||||
FolderNotificationParser({String? id, required NotificationCallback callback})
|
||||
FolderNotificationParser({String? id, required FolderNotificationCallback callback})
|
||||
: super(
|
||||
id: id,
|
||||
callback: callback,
|
||||
@@ -29,6 +34,36 @@ class FolderNotificationParser extends NotificationParser<FolderNotification, Fl
|
||||
);
|
||||
}
|
||||
|
||||
// Grid
|
||||
typedef GridNotificationCallback = void Function(GridNotification, Either<Uint8List, FlowyError>);
|
||||
|
||||
class GridNotificationParser extends NotificationParser<GridNotification, FlowyError> {
|
||||
GridNotificationParser({String? id, required GridNotificationCallback callback})
|
||||
: super(
|
||||
id: id,
|
||||
callback: callback,
|
||||
tyParser: (ty) => GridNotification.valueOf(ty),
|
||||
errorParser: (bytes) => FlowyError.fromBuffer(bytes),
|
||||
);
|
||||
}
|
||||
|
||||
typedef GridNotificationHandler = Function(GridNotification ty, Either<Uint8List, FlowyError> result);
|
||||
|
||||
class GridNotificationListener {
|
||||
StreamSubscription<SubscribeObject>? _subscription;
|
||||
GridNotificationParser? _parser;
|
||||
|
||||
GridNotificationListener({required String objectId, required GridNotificationHandler handler})
|
||||
: _parser = GridNotificationParser(id: objectId, callback: handler) {
|
||||
_subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable));
|
||||
}
|
||||
|
||||
Future<void> stop() async {
|
||||
_parser = null;
|
||||
await _subscription?.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
class NotificationParser<T, E> {
|
||||
String? id;
|
||||
void Function(T, Either<Uint8List, E>) callback;
|
||||
@@ -14,5 +14,5 @@ void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
await EasyLocalization.ensureInitialized();
|
||||
|
||||
System.run(FlowyApp());
|
||||
await FlowyRunner.run(FlowyApp());
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
library flowy_plugin;
|
||||
|
||||
import 'package:app_flowy/plugin/plugin.dart';
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
|
||||
import 'package:flowy_infra/notifier.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
export "./src/sandbox.dart";
|
||||
|
||||
enum DefaultPlugin {
|
||||
quill,
|
||||
blank,
|
||||
trash,
|
||||
grid,
|
||||
}
|
||||
|
||||
extension FlowyDefaultPluginExt on DefaultPlugin {
|
||||
int type() {
|
||||
switch (this) {
|
||||
case DefaultPlugin.quill:
|
||||
return 0;
|
||||
case DefaultPlugin.blank:
|
||||
return 1;
|
||||
case DefaultPlugin.trash:
|
||||
return 2;
|
||||
case DefaultPlugin.grid:
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef PluginType = int;
|
||||
typedef PluginDataType = ViewDataType;
|
||||
typedef PluginId = String;
|
||||
|
||||
abstract class Plugin {
|
||||
PluginId get id;
|
||||
|
||||
PluginDisplay get display;
|
||||
|
||||
PluginType get ty;
|
||||
|
||||
void dispose() {}
|
||||
}
|
||||
|
||||
abstract class PluginBuilder {
|
||||
Plugin build(dynamic data);
|
||||
|
||||
String get menuName;
|
||||
|
||||
PluginType get pluginType;
|
||||
|
||||
ViewDataType get dataType => ViewDataType.TextBlock;
|
||||
}
|
||||
|
||||
abstract class PluginConfig {
|
||||
// Return false will disable the user to create it. For example, a trash plugin shouldn't be created by the user,
|
||||
bool get creatable => true;
|
||||
}
|
||||
|
||||
abstract class PluginDisplay<T> with NavigationItem {
|
||||
List<NavigationItem> get navigationItems;
|
||||
|
||||
PublishNotifier<T>? get notifier => null;
|
||||
|
||||
Widget buildWidget();
|
||||
}
|
||||
|
||||
void registerPlugin({required PluginBuilder builder, PluginConfig? config}) {
|
||||
getIt<PluginSandbox>().registerPlugin(builder.pluginType, builder, config: config);
|
||||
}
|
||||
|
||||
Plugin makePlugin({required PluginType pluginType, dynamic data}) {
|
||||
final plugin = getIt<PluginSandbox>().buildPlugin(pluginType, data);
|
||||
return plugin;
|
||||
}
|
||||
|
||||
List<PluginBuilder> pluginBuilders() {
|
||||
final pluginBuilders = getIt<PluginSandbox>().builders;
|
||||
final pluginConfigs = getIt<PluginSandbox>().pluginConfigs;
|
||||
return pluginBuilders.where(
|
||||
(builder) {
|
||||
final config = pluginConfigs[builder.pluginType]?.creatable;
|
||||
return config ?? true;
|
||||
},
|
||||
).toList();
|
||||
}
|
||||
|
||||
enum FlowyPluginException {
|
||||
invalidData,
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
class PluginRunner {}
|
||||
@@ -0,0 +1,46 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import '../plugin.dart';
|
||||
import 'runner.dart';
|
||||
|
||||
class PluginSandbox {
|
||||
final LinkedHashMap<PluginType, PluginBuilder> _pluginBuilders = LinkedHashMap();
|
||||
final Map<PluginType, PluginConfig> _pluginConfigs = <PluginType, PluginConfig>{};
|
||||
late PluginRunner pluginRunner;
|
||||
|
||||
PluginSandbox() {
|
||||
pluginRunner = PluginRunner();
|
||||
}
|
||||
|
||||
int indexOf(PluginType pluginType) {
|
||||
final index = _pluginBuilders.keys.toList().indexWhere((ty) => ty == pluginType);
|
||||
if (index == -1) {
|
||||
throw PlatformException(code: '-1', message: "Can't find the flowy plugin type: $pluginType");
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
Plugin buildPlugin(PluginType pluginType, dynamic data) {
|
||||
final plugin = _pluginBuilders[pluginType]!.build(data);
|
||||
return plugin;
|
||||
}
|
||||
|
||||
void registerPlugin(PluginType pluginType, PluginBuilder builder, {PluginConfig? config}) {
|
||||
if (_pluginBuilders.containsKey(pluginType)) {
|
||||
throw PlatformException(code: '-1', message: "$pluginType was registered before");
|
||||
}
|
||||
_pluginBuilders[pluginType] = builder;
|
||||
|
||||
if (config != null) {
|
||||
_pluginConfigs[pluginType] = config;
|
||||
}
|
||||
}
|
||||
|
||||
List<int> get supportPluginTypes => _pluginBuilders.keys.toList();
|
||||
|
||||
List<PluginBuilder> get builders => _pluginBuilders.values.toList();
|
||||
|
||||
Map<PluginType, PluginConfig> get pluginConfigs => _pluginConfigs;
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
import 'package:app_flowy/core/network_monitor.dart';
|
||||
import 'package:app_flowy/user/application/user_listener.dart';
|
||||
import 'package:app_flowy/user/application/user_service.dart';
|
||||
import 'package:app_flowy/workspace/application/app/prelude.dart';
|
||||
import 'package:app_flowy/workspace/application/doc/prelude.dart';
|
||||
import 'package:app_flowy/workspace/application/grid/prelude.dart';
|
||||
import 'package:app_flowy/workspace/application/trash/prelude.dart';
|
||||
import 'package:app_flowy/workspace/application/workspace/prelude.dart';
|
||||
import 'package:app_flowy/workspace/application/edit_pannel/edit_pannel_bloc.dart';
|
||||
import 'package:app_flowy/workspace/application/view/prelude.dart';
|
||||
import 'package:app_flowy/workspace/application/menu/prelude.dart';
|
||||
import 'package:app_flowy/user/application/prelude.dart';
|
||||
import 'package:app_flowy/user/presentation/router.dart';
|
||||
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
|
||||
import 'package:app_flowy/workspace/presentation/home/menu/menu.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
|
||||
class DependencyResolver {
|
||||
static Future<void> resolve(GetIt getIt) async {
|
||||
_resolveUserDeps(getIt);
|
||||
|
||||
_resolveHomeDeps(getIt);
|
||||
|
||||
_resolveFolderDeps(getIt);
|
||||
|
||||
_resolveDocDeps(getIt);
|
||||
|
||||
_resolveGridDeps(getIt);
|
||||
}
|
||||
}
|
||||
|
||||
void _resolveUserDeps(GetIt getIt) {
|
||||
getIt.registerFactory<AuthService>(() => AuthService());
|
||||
getIt.registerFactory<AuthRouter>(() => AuthRouter());
|
||||
|
||||
getIt.registerFactory<SignInBloc>(() => SignInBloc(getIt<AuthService>()));
|
||||
getIt.registerFactory<SignUpBloc>(() => SignUpBloc(getIt<AuthService>()));
|
||||
|
||||
getIt.registerFactory<SplashRoute>(() => SplashRoute());
|
||||
getIt.registerFactory<EditPannelBloc>(() => EditPannelBloc());
|
||||
getIt.registerFactory<SplashBloc>(() => SplashBloc());
|
||||
getIt.registerLazySingleton<NetworkListener>(() => NetworkListener());
|
||||
}
|
||||
|
||||
void _resolveHomeDeps(GetIt getIt) {
|
||||
getIt.registerSingleton(FToast());
|
||||
|
||||
getIt.registerSingleton(MenuSharedState());
|
||||
|
||||
getIt.registerFactoryParam<UserListener, UserProfile, void>(
|
||||
(user, _) => UserListener(user: user),
|
||||
);
|
||||
|
||||
//
|
||||
getIt.registerLazySingleton<HomeStackManager>(() => HomeStackManager());
|
||||
|
||||
getIt.registerFactoryParam<WelcomeBloc, UserProfile, void>(
|
||||
(user, _) => WelcomeBloc(
|
||||
userService: UserService(),
|
||||
userListener: getIt<UserListener>(param1: user),
|
||||
),
|
||||
);
|
||||
|
||||
// share
|
||||
getIt.registerLazySingleton<ShareService>(() => ShareService());
|
||||
getIt.registerFactoryParam<DocShareBloc, View, void>(
|
||||
(view, _) => DocShareBloc(view: view, service: getIt<ShareService>()));
|
||||
}
|
||||
|
||||
void _resolveFolderDeps(GetIt getIt) {
|
||||
//workspace
|
||||
getIt.registerFactoryParam<WorkspaceListener, UserProfile, String>((user, workspaceId) =>
|
||||
WorkspaceListener(service: WorkspaceListenerService(user: user, workspaceId: workspaceId)));
|
||||
|
||||
// View
|
||||
getIt.registerFactoryParam<ViewListener, View, void>(
|
||||
(view, _) => ViewListener(view: view),
|
||||
);
|
||||
|
||||
getIt.registerFactoryParam<ViewBloc, View, void>(
|
||||
(view, _) => ViewBloc(
|
||||
view: view,
|
||||
service: ViewService(),
|
||||
listener: getIt<ViewListener>(param1: view),
|
||||
),
|
||||
);
|
||||
|
||||
//Menu
|
||||
getIt.registerFactoryParam<MenuBloc, UserProfile, String>(
|
||||
(user, workspaceId) => MenuBloc(
|
||||
workspaceId: workspaceId,
|
||||
listener: getIt<WorkspaceListener>(param1: user, param2: workspaceId),
|
||||
),
|
||||
);
|
||||
|
||||
getIt.registerFactoryParam<MenuUserBloc, UserProfile, void>(
|
||||
(user, _) => MenuUserBloc(
|
||||
user,
|
||||
UserService(),
|
||||
getIt<UserListener>(param1: user),
|
||||
),
|
||||
);
|
||||
|
||||
// App
|
||||
getIt.registerFactoryParam<AppBloc, App, void>(
|
||||
(app, _) => AppBloc(
|
||||
app: app,
|
||||
appService: AppService(appId: app.id),
|
||||
appListener: AppListener(appId: app.id),
|
||||
),
|
||||
);
|
||||
|
||||
// trash
|
||||
getIt.registerLazySingleton<TrashService>(() => TrashService());
|
||||
getIt.registerLazySingleton<TrashListener>(() => TrashListener());
|
||||
getIt.registerFactory<TrashBloc>(
|
||||
() => TrashBloc(
|
||||
service: getIt<TrashService>(),
|
||||
listener: getIt<TrashListener>(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _resolveDocDeps(GetIt getIt) {
|
||||
// Doc
|
||||
getIt.registerFactoryParam<DocumentBloc, View, void>(
|
||||
(view, _) => DocumentBloc(
|
||||
view: view,
|
||||
service: DocumentService(),
|
||||
listener: getIt<ViewListener>(param1: view),
|
||||
trashService: getIt<TrashService>(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _resolveGridDeps(GetIt getIt) {
|
||||
// Grid
|
||||
getIt.registerFactoryParam<GridBloc, View, void>(
|
||||
(view, _) => GridBloc(view: view),
|
||||
);
|
||||
|
||||
getIt.registerFactoryParam<GridHeaderBloc, String, GridFieldCache>(
|
||||
(gridId, fieldCache) => GridHeaderBloc(
|
||||
gridId: gridId,
|
||||
fieldCache: fieldCache,
|
||||
),
|
||||
);
|
||||
|
||||
getIt.registerFactoryParam<FieldActionSheetBloc, GridFieldCellContext, void>(
|
||||
(data, _) => FieldActionSheetBloc(
|
||||
field: data.field,
|
||||
fieldService: FieldService(gridId: data.gridId, fieldId: data.field.id),
|
||||
),
|
||||
);
|
||||
|
||||
getIt.registerFactoryParam<TextCellBloc, GridCellContext, void>(
|
||||
(context, _) => TextCellBloc(
|
||||
cellContext: context,
|
||||
),
|
||||
);
|
||||
|
||||
getIt.registerFactoryParam<SelectOptionCellBloc, GridSelectOptionCellContext, void>(
|
||||
(context, _) => SelectOptionCellBloc(
|
||||
cellContext: context,
|
||||
),
|
||||
);
|
||||
|
||||
getIt.registerFactoryParam<NumberCellBloc, GridCellContext, void>(
|
||||
(context, _) => NumberCellBloc(
|
||||
cellContext: context,
|
||||
),
|
||||
);
|
||||
|
||||
getIt.registerFactoryParam<DateCellBloc, GridDateCellContext, void>(
|
||||
(context, _) => DateCellBloc(
|
||||
cellContext: context,
|
||||
),
|
||||
);
|
||||
|
||||
getIt.registerFactoryParam<CheckboxCellBloc, GridCellContext, void>(
|
||||
(cellData, _) => CheckboxCellBloc(
|
||||
service: CellService(),
|
||||
cellContext: cellData,
|
||||
),
|
||||
);
|
||||
|
||||
getIt.registerFactoryParam<GridPropertyBloc, String, GridFieldCache>(
|
||||
(gridId, cache) => GridPropertyBloc(gridId: gridId, fieldCache: cache),
|
||||
);
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
|
||||
class LaunchContext {
|
||||
GetIt getIt;
|
||||
IntegrationEnv env;
|
||||
LaunchContext(this.getIt, this.env);
|
||||
}
|
||||
|
||||
enum LaunchTaskType {
|
||||
dataProcessing,
|
||||
appLauncher,
|
||||
}
|
||||
|
||||
/// The interface of an app launch task, which will trigger
|
||||
/// some nonresident indispensable task in app launching task.
|
||||
abstract class LaunchTask {
|
||||
LaunchTaskType get type => LaunchTaskType.dataProcessing;
|
||||
Future<void> initialize(LaunchContext context);
|
||||
}
|
||||
|
||||
class AppLauncher {
|
||||
List<LaunchTask> tasks;
|
||||
IntegrationEnv env;
|
||||
GetIt getIt;
|
||||
|
||||
AppLauncher(this.env, this.getIt) : tasks = List.from([]);
|
||||
|
||||
void addTask(LaunchTask task) {
|
||||
tasks.add(task);
|
||||
}
|
||||
|
||||
void launch() async {
|
||||
final context = LaunchContext(getIt, env);
|
||||
for (var task in tasks) {
|
||||
await task.initialize(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
//test git hooks
|
||||
@@ -1,13 +1,13 @@
|
||||
import 'package:app_flowy/startup/launcher.dart';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:app_flowy/plugin/plugin.dart';
|
||||
import 'package:app_flowy/startup/tasks/prelude.dart';
|
||||
import 'package:app_flowy/startup/deps_resolver.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:app_flowy/workspace/infrastructure/deps_resolver.dart';
|
||||
import 'package:app_flowy/user/infrastructure/deps_resolver.dart';
|
||||
import 'package:flowy_sdk/flowy_sdk.dart';
|
||||
|
||||
import 'tasks/init_platform_service.dart';
|
||||
|
||||
// [[diagram: flowy startup flow]]
|
||||
// ┌──────────┐
|
||||
// │ FlowyApp │
|
||||
@@ -26,44 +26,101 @@ import 'tasks/init_platform_service.dart';
|
||||
//
|
||||
// 3.build MeterialApp
|
||||
final getIt = GetIt.instance;
|
||||
enum IntegrationEnv {
|
||||
dev,
|
||||
pro,
|
||||
}
|
||||
|
||||
abstract class EntryPoint {
|
||||
Widget create();
|
||||
}
|
||||
|
||||
class System {
|
||||
static void run(EntryPoint f) {
|
||||
class FlowyRunner {
|
||||
static Future<void> run(EntryPoint f) async {
|
||||
// Specify the env
|
||||
const env = IntegrationEnv.dev;
|
||||
|
||||
// Config the deps graph
|
||||
getIt.registerFactory<EntryPoint>(() => f);
|
||||
|
||||
resolveDependencies(env);
|
||||
final env = integrationEnv();
|
||||
initGetIt(getIt, env, f);
|
||||
|
||||
// add task
|
||||
getIt<AppLauncher>().addTask(InitRustSDKTask());
|
||||
getIt<AppLauncher>().addTask(AppWidgetTask());
|
||||
getIt<AppLauncher>().addTask(InitPlatformService());
|
||||
|
||||
if (!env.isTest()) {
|
||||
getIt<AppLauncher>().addTask(PluginLoadTask());
|
||||
getIt<AppLauncher>().addTask(InitAppWidgetTask());
|
||||
getIt<AppLauncher>().addTask(InitPlatformServiceTask());
|
||||
}
|
||||
|
||||
// execute the tasks
|
||||
getIt<AppLauncher>().launch();
|
||||
}
|
||||
}
|
||||
|
||||
void resolveDependencies(IntegrationEnv env) => initGetIt(getIt, env);
|
||||
|
||||
Future<void> initGetIt(
|
||||
GetIt getIt,
|
||||
IntegrationEnv env,
|
||||
IntegrationMode env,
|
||||
EntryPoint f,
|
||||
) async {
|
||||
getIt.registerFactory<EntryPoint>(() => f);
|
||||
getIt.registerLazySingleton<FlowySDK>(() => const FlowySDK());
|
||||
getIt.registerLazySingleton<AppLauncher>(() => AppLauncher(env, getIt));
|
||||
getIt.registerSingleton<PluginSandbox>(PluginSandbox());
|
||||
|
||||
await UserDepsResolver.resolve(getIt);
|
||||
await HomeDepsResolver.resolve(getIt);
|
||||
await DependencyResolver.resolve(getIt);
|
||||
}
|
||||
|
||||
class LaunchContext {
|
||||
GetIt getIt;
|
||||
IntegrationMode env;
|
||||
LaunchContext(this.getIt, this.env);
|
||||
}
|
||||
|
||||
enum LaunchTaskType {
|
||||
dataProcessing,
|
||||
appLauncher,
|
||||
}
|
||||
|
||||
/// The interface of an app launch task, which will trigger
|
||||
/// some nonresident indispensable task in app launching task.
|
||||
abstract class LaunchTask {
|
||||
LaunchTaskType get type => LaunchTaskType.dataProcessing;
|
||||
Future<void> initialize(LaunchContext context);
|
||||
}
|
||||
|
||||
class AppLauncher {
|
||||
List<LaunchTask> tasks;
|
||||
IntegrationMode env;
|
||||
GetIt getIt;
|
||||
|
||||
AppLauncher(this.env, this.getIt) : tasks = List.from([]);
|
||||
|
||||
void addTask(LaunchTask task) {
|
||||
tasks.add(task);
|
||||
}
|
||||
|
||||
Future<void> launch() async {
|
||||
final context = LaunchContext(getIt, env);
|
||||
for (var task in tasks) {
|
||||
await task.initialize(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum IntegrationMode {
|
||||
develop,
|
||||
release,
|
||||
test,
|
||||
}
|
||||
|
||||
extension IntegrationEnvExt on IntegrationMode {
|
||||
bool isTest() {
|
||||
return this == IntegrationMode.test;
|
||||
}
|
||||
}
|
||||
|
||||
IntegrationMode integrationEnv() {
|
||||
if (Platform.environment.containsKey('FLUTTER_TEST')) {
|
||||
return IntegrationMode.test;
|
||||
}
|
||||
|
||||
if (kReleaseMode) {
|
||||
return IntegrationMode.release;
|
||||
}
|
||||
|
||||
return IntegrationMode.develop;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/user/infrastructure/repos/user_setting_repo.dart';
|
||||
import 'package:app_flowy/user/application/user_settings_service.dart';
|
||||
import 'package:app_flowy/workspace/application/appearance.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
@@ -7,18 +7,17 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:window_size/window_size.dart';
|
||||
import 'package:app_flowy/startup/launcher.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:flowy_log/flowy_log.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
|
||||
class AppWidgetTask extends LaunchTask {
|
||||
class InitAppWidgetTask extends LaunchTask {
|
||||
@override
|
||||
LaunchTaskType get type => LaunchTaskType.appLauncher;
|
||||
|
||||
@override
|
||||
Future<void> initialize(LaunchContext context) async {
|
||||
final widget = context.getIt<EntryPoint>().create();
|
||||
final setting = await UserSettingReppsitory().getAppearanceSettings();
|
||||
final setting = await UserSettingsService().getAppearanceSettings();
|
||||
final settingModel = AppearanceSettingModel(setting);
|
||||
final app = ApplicationWidget(
|
||||
child: widget,
|
||||
@@ -30,11 +29,17 @@ class AppWidgetTask extends LaunchTask {
|
||||
EasyLocalization(
|
||||
supportedLocales: const [
|
||||
// In alphabetical order
|
||||
Locale('ca', 'ES'),
|
||||
Locale('de', 'DE'),
|
||||
Locale('en'),
|
||||
Locale('es', 'VE'),
|
||||
Locale('fr', 'FR'),
|
||||
Locale('fr', 'CA'),
|
||||
Locale('hu', 'HU'),
|
||||
Locale('it', 'IT'),
|
||||
Locale('pt', 'BR'),
|
||||
Locale('ru', 'RU'),
|
||||
Locale('tr', 'TR'),
|
||||
Locale('zh', 'CN'),
|
||||
],
|
||||
path: 'assets/translations',
|
||||
@@ -62,40 +67,42 @@ class ApplicationWidget extends StatelessWidget {
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => ChangeNotifierProvider.value(
|
||||
value: settingModel,
|
||||
builder: (context, _) {
|
||||
const ratio = 1.73;
|
||||
const minWidth = 600.0;
|
||||
setWindowMinSize(const Size(minWidth, minWidth / ratio));
|
||||
settingModel.readLocaleWhenAppLaunch(context);
|
||||
AppTheme theme = context.select<AppearanceSettingModel, AppTheme>(
|
||||
(value) => value.theme,
|
||||
);
|
||||
Locale locale = context.select<AppearanceSettingModel, Locale>(
|
||||
(value) => value.locale,
|
||||
);
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider.value(
|
||||
value: settingModel,
|
||||
builder: (context, _) {
|
||||
const ratio = 1.73;
|
||||
const minWidth = 600.0;
|
||||
setWindowMinSize(const Size(minWidth, minWidth / ratio));
|
||||
settingModel.readLocaleWhenAppLaunch(context);
|
||||
AppTheme theme = context.select<AppearanceSettingModel, AppTheme>(
|
||||
(value) => value.theme,
|
||||
);
|
||||
Locale locale = context.select<AppearanceSettingModel, Locale>(
|
||||
(value) => value.locale,
|
||||
);
|
||||
|
||||
return MultiProvider(
|
||||
providers: [
|
||||
Provider.value(value: theme),
|
||||
Provider.value(value: locale),
|
||||
],
|
||||
builder: (context, _) {
|
||||
return MaterialApp(
|
||||
builder: overlayManagerBuilder(),
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: theme.themeData,
|
||||
localizationsDelegates: context.localizationDelegates,
|
||||
supportedLocales: context.supportedLocales,
|
||||
locale: locale,
|
||||
navigatorKey: AppGlobals.rootNavKey,
|
||||
home: child,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
return MultiProvider(
|
||||
providers: [
|
||||
Provider.value(value: theme),
|
||||
Provider.value(value: locale),
|
||||
],
|
||||
builder: (context, _) {
|
||||
return MaterialApp(
|
||||
builder: overlayManagerBuilder(),
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: theme.themeData,
|
||||
localizationsDelegates: context.localizationDelegates,
|
||||
supportedLocales: context.supportedLocales,
|
||||
locale: locale,
|
||||
navigatorKey: AppGlobals.rootNavKey,
|
||||
home: child,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AppGlobals {
|
||||
@@ -108,7 +115,7 @@ class ApplicationBlocObserver extends BlocObserver {
|
||||
// ignore: unnecessary_overrides
|
||||
void onTransition(Bloc bloc, Transition transition) {
|
||||
// Log.debug("[current]: ${transition.currentState} \n\n[next]: ${transition.nextState}");
|
||||
//Log.debug("${transition.nextState}");
|
||||
// Log.debug("${transition.nextState}");
|
||||
super.onTransition(bloc, transition);
|
||||
}
|
||||
|
||||
@@ -118,9 +125,9 @@ class ApplicationBlocObserver extends BlocObserver {
|
||||
super.onError(bloc, error, stackTrace);
|
||||
}
|
||||
|
||||
@override
|
||||
void onEvent(Bloc bloc, Object? event) {
|
||||
Log.debug("$event");
|
||||
super.onEvent(bloc, event);
|
||||
}
|
||||
// @override
|
||||
// void onEvent(Bloc bloc, Object? event) {
|
||||
// Log.debug("$event");
|
||||
// super.onEvent(bloc, event);
|
||||
// }
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import 'package:app_flowy/startup/launcher.dart';
|
||||
import 'package:app_flowy/user/infrastructure/network_monitor.dart';
|
||||
|
||||
import '../startup.dart';
|
||||
|
||||
class InitPlatformService extends LaunchTask {
|
||||
@override
|
||||
LaunchTaskType get type => LaunchTaskType.dataProcessing;
|
||||
|
||||
@override
|
||||
Future<void> initialize(LaunchContext context) async {
|
||||
getIt<NetworkMonitor>().start();
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
import 'dart:io';
|
||||
import 'package:app_flowy/startup/launcher.dart';
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:flowy_sdk/flowy_sdk.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class InitRustSDKTask extends LaunchTask {
|
||||
@override
|
||||
LaunchTaskType get type => LaunchTaskType.dataProcessing;
|
||||
|
||||
@override
|
||||
Future<void> initialize(LaunchContext context) async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
Directory directory = await getApplicationDocumentsDirectory();
|
||||
final documentPath = directory.path;
|
||||
|
||||
return Directory('$documentPath/flowy').create().then((Directory directory) async {
|
||||
switch (context.env) {
|
||||
case IntegrationEnv.dev:
|
||||
// await context.getIt<FlowySDK>().init(Directory('./temp/flowy_dev'));
|
||||
await context.getIt<FlowySDK>().init(directory);
|
||||
break;
|
||||
case IntegrationEnv.pro:
|
||||
await context.getIt<FlowySDK>().init(directory);
|
||||
break;
|
||||
default:
|
||||
assert(false, 'Unsupported env');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import 'package:app_flowy/plugin/plugin.dart';
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/presentation/plugins/blank/blank.dart';
|
||||
import 'package:app_flowy/workspace/presentation/plugins/doc/document.dart';
|
||||
import 'package:app_flowy/workspace/presentation/plugins/grid/grid.dart';
|
||||
import 'package:app_flowy/workspace/presentation/plugins/trash/trash.dart';
|
||||
|
||||
class PluginLoadTask extends LaunchTask {
|
||||
@override
|
||||
LaunchTaskType get type => LaunchTaskType.dataProcessing;
|
||||
|
||||
@override
|
||||
Future<void> initialize(LaunchContext context) async {
|
||||
registerPlugin(builder: BlankPluginBuilder(), config: BlankPluginConfig());
|
||||
registerPlugin(builder: TrashPluginBuilder(), config: TrashPluginConfig());
|
||||
registerPlugin(builder: DocumentPluginBuilder());
|
||||
registerPlugin(builder: GridPluginBuilder(), config: GridPluginConfig());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import 'package:app_flowy/core/network_monitor.dart';
|
||||
import '../startup.dart';
|
||||
|
||||
class InitPlatformServiceTask extends LaunchTask {
|
||||
@override
|
||||
LaunchTaskType get type => LaunchTaskType.dataProcessing;
|
||||
|
||||
@override
|
||||
Future<void> initialize(LaunchContext context) async {
|
||||
getIt<NetworkListener>().start();
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,4 @@
|
||||
export 'application_widget.dart';
|
||||
export 'init_sdk.dart';
|
||||
export 'app_widget.dart';
|
||||
export 'rust_sdk.dart';
|
||||
export 'platform_service.dart';
|
||||
export 'load_plugin.dart';
|
||||
@@ -0,0 +1,29 @@
|
||||
import 'dart:io';
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:flowy_sdk/flowy_sdk.dart';
|
||||
|
||||
class InitRustSDKTask extends LaunchTask {
|
||||
@override
|
||||
LaunchTaskType get type => LaunchTaskType.dataProcessing;
|
||||
|
||||
@override
|
||||
Future<void> initialize(LaunchContext context) async {
|
||||
await appFlowyDocumentDirectory().then((directory) async {
|
||||
await context.getIt<FlowySDK>().init(directory);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<Directory> appFlowyDocumentDirectory() async {
|
||||
Directory documentsDir = await getApplicationDocumentsDirectory();
|
||||
|
||||
switch (integrationEnv()) {
|
||||
case IntegrationMode.develop:
|
||||
return Directory('${documentsDir.path}/flowy_dev').create();
|
||||
case IntegrationMode.release:
|
||||
return Directory('${documentsDir.path}/flowy').create();
|
||||
case IntegrationMode.test:
|
||||
return Directory("${Directory.current.path}/.sandbox");
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart' show SignInRequest, SignUpRequest, UserProfile;
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart' show SignInPayload, SignUpPayload, UserProfile;
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
|
||||
class AuthRepository {
|
||||
class AuthService {
|
||||
Future<Either<UserProfile, FlowyError>> signIn({required String? email, required String? password}) {
|
||||
//
|
||||
final request = SignInRequest.create()
|
||||
final request = SignInPayload.create()
|
||||
..email = email ?? ''
|
||||
..password = password ?? '';
|
||||
|
||||
@@ -15,7 +15,7 @@ class AuthRepository {
|
||||
|
||||
Future<Either<UserProfile, FlowyError>> signUp(
|
||||
{required String? name, required String? password, required String? email}) {
|
||||
final request = SignUpRequest.create()
|
||||
final request = SignUpPayload.create()
|
||||
..email = email ?? ''
|
||||
..name = name ?? ''
|
||||
..password = password ?? '';
|
||||
@@ -0,0 +1,4 @@
|
||||
export './auth_service.dart';
|
||||
export './sign_in_bloc.dart';
|
||||
export './sign_up_bloc.dart';
|
||||
export './splash_bloc.dart';
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:app_flowy/user/infrastructure/repos/auth_repo.dart';
|
||||
import 'package:app_flowy/user/application/auth_service.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart' show UserProfile, ErrorCode;
|
||||
@@ -8,8 +8,8 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
part 'sign_in_bloc.freezed.dart';
|
||||
|
||||
class SignInBloc extends Bloc<SignInEvent, SignInState> {
|
||||
final AuthRepository authRepo;
|
||||
SignInBloc(this.authRepo) : super(SignInState.initial()) {
|
||||
final AuthService authService;
|
||||
SignInBloc(this.authService) : super(SignInState.initial()) {
|
||||
on<SignInEvent>((event, emit) async {
|
||||
await event.map(
|
||||
signedInWithUserEmailAndPassword: (e) async {
|
||||
@@ -31,7 +31,7 @@ class SignInBloc extends Bloc<SignInEvent, SignInState> {
|
||||
Future<void> _performActionOnSignIn(SignInState state, Emitter<SignInState> emit) async {
|
||||
emit(state.copyWith(isSubmitting: true, emailError: none(), passwordError: none(), successOrFail: none()));
|
||||
|
||||
final result = await authRepo.signIn(
|
||||
final result = await authService.signIn(
|
||||
email: state.email,
|
||||
password: state.password,
|
||||
);
|
||||
@@ -54,14 +54,14 @@ class SignInBloc extends Bloc<SignInEvent, SignInState> {
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class SignInEvent with _$SignInEvent {
|
||||
class SignInEvent with _$SignInEvent {
|
||||
const factory SignInEvent.signedInWithUserEmailAndPassword() = SignedInWithUserEmailAndPassword;
|
||||
const factory SignInEvent.emailChanged(String email) = EmailChanged;
|
||||
const factory SignInEvent.passwordChanged(String password) = PasswordChanged;
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class SignInState with _$SignInState {
|
||||
class SignInState with _$SignInState {
|
||||
const factory SignInState({
|
||||
String? email,
|
||||
String? password,
|
||||
|
||||
@@ -1,771 +0,0 @@
|
||||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
|
||||
|
||||
part of 'sign_in_bloc.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
final _privateConstructorUsedError = UnsupportedError(
|
||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
|
||||
|
||||
/// @nodoc
|
||||
class _$SignInEventTearOff {
|
||||
const _$SignInEventTearOff();
|
||||
|
||||
SignedInWithUserEmailAndPassword signedInWithUserEmailAndPassword() {
|
||||
return const SignedInWithUserEmailAndPassword();
|
||||
}
|
||||
|
||||
EmailChanged emailChanged(String email) {
|
||||
return EmailChanged(
|
||||
email,
|
||||
);
|
||||
}
|
||||
|
||||
PasswordChanged passwordChanged(String password) {
|
||||
return PasswordChanged(
|
||||
password,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
const $SignInEvent = _$SignInEventTearOff();
|
||||
|
||||
/// @nodoc
|
||||
mixin _$SignInEvent {
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() signedInWithUserEmailAndPassword,
|
||||
required TResult Function(String email) emailChanged,
|
||||
required TResult Function(String password) passwordChanged,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult Function()? signedInWithUserEmailAndPassword,
|
||||
TResult Function(String email)? emailChanged,
|
||||
TResult Function(String password)? passwordChanged,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? signedInWithUserEmailAndPassword,
|
||||
TResult Function(String email)? emailChanged,
|
||||
TResult Function(String password)? passwordChanged,
|
||||
required TResult orElse(),
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(SignedInWithUserEmailAndPassword value)
|
||||
signedInWithUserEmailAndPassword,
|
||||
required TResult Function(EmailChanged value) emailChanged,
|
||||
required TResult Function(PasswordChanged value) passwordChanged,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult Function(SignedInWithUserEmailAndPassword value)?
|
||||
signedInWithUserEmailAndPassword,
|
||||
TResult Function(EmailChanged value)? emailChanged,
|
||||
TResult Function(PasswordChanged value)? passwordChanged,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(SignedInWithUserEmailAndPassword value)?
|
||||
signedInWithUserEmailAndPassword,
|
||||
TResult Function(EmailChanged value)? emailChanged,
|
||||
TResult Function(PasswordChanged value)? passwordChanged,
|
||||
required TResult orElse(),
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $SignInEventCopyWith<$Res> {
|
||||
factory $SignInEventCopyWith(
|
||||
SignInEvent value, $Res Function(SignInEvent) then) =
|
||||
_$SignInEventCopyWithImpl<$Res>;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$SignInEventCopyWithImpl<$Res> implements $SignInEventCopyWith<$Res> {
|
||||
_$SignInEventCopyWithImpl(this._value, this._then);
|
||||
|
||||
final SignInEvent _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function(SignInEvent) _then;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $SignedInWithUserEmailAndPasswordCopyWith<$Res> {
|
||||
factory $SignedInWithUserEmailAndPasswordCopyWith(
|
||||
SignedInWithUserEmailAndPassword value,
|
||||
$Res Function(SignedInWithUserEmailAndPassword) then) =
|
||||
_$SignedInWithUserEmailAndPasswordCopyWithImpl<$Res>;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$SignedInWithUserEmailAndPasswordCopyWithImpl<$Res>
|
||||
extends _$SignInEventCopyWithImpl<$Res>
|
||||
implements $SignedInWithUserEmailAndPasswordCopyWith<$Res> {
|
||||
_$SignedInWithUserEmailAndPasswordCopyWithImpl(
|
||||
SignedInWithUserEmailAndPassword _value,
|
||||
$Res Function(SignedInWithUserEmailAndPassword) _then)
|
||||
: super(_value, (v) => _then(v as SignedInWithUserEmailAndPassword));
|
||||
|
||||
@override
|
||||
SignedInWithUserEmailAndPassword get _value =>
|
||||
super._value as SignedInWithUserEmailAndPassword;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$SignedInWithUserEmailAndPassword
|
||||
implements SignedInWithUserEmailAndPassword {
|
||||
const _$SignedInWithUserEmailAndPassword();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SignInEvent.signedInWithUserEmailAndPassword()';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(dynamic other) {
|
||||
return identical(this, other) ||
|
||||
(other is SignedInWithUserEmailAndPassword);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => runtimeType.hashCode;
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() signedInWithUserEmailAndPassword,
|
||||
required TResult Function(String email) emailChanged,
|
||||
required TResult Function(String password) passwordChanged,
|
||||
}) {
|
||||
return signedInWithUserEmailAndPassword();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult Function()? signedInWithUserEmailAndPassword,
|
||||
TResult Function(String email)? emailChanged,
|
||||
TResult Function(String password)? passwordChanged,
|
||||
}) {
|
||||
return signedInWithUserEmailAndPassword?.call();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? signedInWithUserEmailAndPassword,
|
||||
TResult Function(String email)? emailChanged,
|
||||
TResult Function(String password)? passwordChanged,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (signedInWithUserEmailAndPassword != null) {
|
||||
return signedInWithUserEmailAndPassword();
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(SignedInWithUserEmailAndPassword value)
|
||||
signedInWithUserEmailAndPassword,
|
||||
required TResult Function(EmailChanged value) emailChanged,
|
||||
required TResult Function(PasswordChanged value) passwordChanged,
|
||||
}) {
|
||||
return signedInWithUserEmailAndPassword(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult Function(SignedInWithUserEmailAndPassword value)?
|
||||
signedInWithUserEmailAndPassword,
|
||||
TResult Function(EmailChanged value)? emailChanged,
|
||||
TResult Function(PasswordChanged value)? passwordChanged,
|
||||
}) {
|
||||
return signedInWithUserEmailAndPassword?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(SignedInWithUserEmailAndPassword value)?
|
||||
signedInWithUserEmailAndPassword,
|
||||
TResult Function(EmailChanged value)? emailChanged,
|
||||
TResult Function(PasswordChanged value)? passwordChanged,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (signedInWithUserEmailAndPassword != null) {
|
||||
return signedInWithUserEmailAndPassword(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class SignedInWithUserEmailAndPassword implements SignInEvent {
|
||||
const factory SignedInWithUserEmailAndPassword() =
|
||||
_$SignedInWithUserEmailAndPassword;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $EmailChangedCopyWith<$Res> {
|
||||
factory $EmailChangedCopyWith(
|
||||
EmailChanged value, $Res Function(EmailChanged) then) =
|
||||
_$EmailChangedCopyWithImpl<$Res>;
|
||||
$Res call({String email});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$EmailChangedCopyWithImpl<$Res> extends _$SignInEventCopyWithImpl<$Res>
|
||||
implements $EmailChangedCopyWith<$Res> {
|
||||
_$EmailChangedCopyWithImpl(
|
||||
EmailChanged _value, $Res Function(EmailChanged) _then)
|
||||
: super(_value, (v) => _then(v as EmailChanged));
|
||||
|
||||
@override
|
||||
EmailChanged get _value => super._value as EmailChanged;
|
||||
|
||||
@override
|
||||
$Res call({
|
||||
Object? email = freezed,
|
||||
}) {
|
||||
return _then(EmailChanged(
|
||||
email == freezed
|
||||
? _value.email
|
||||
: email // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$EmailChanged implements EmailChanged {
|
||||
const _$EmailChanged(this.email);
|
||||
|
||||
@override
|
||||
final String email;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SignInEvent.emailChanged(email: $email)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(dynamic other) {
|
||||
return identical(this, other) ||
|
||||
(other is EmailChanged &&
|
||||
(identical(other.email, email) ||
|
||||
const DeepCollectionEquality().equals(other.email, email)));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
runtimeType.hashCode ^ const DeepCollectionEquality().hash(email);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
$EmailChangedCopyWith<EmailChanged> get copyWith =>
|
||||
_$EmailChangedCopyWithImpl<EmailChanged>(this, _$identity);
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() signedInWithUserEmailAndPassword,
|
||||
required TResult Function(String email) emailChanged,
|
||||
required TResult Function(String password) passwordChanged,
|
||||
}) {
|
||||
return emailChanged(email);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult Function()? signedInWithUserEmailAndPassword,
|
||||
TResult Function(String email)? emailChanged,
|
||||
TResult Function(String password)? passwordChanged,
|
||||
}) {
|
||||
return emailChanged?.call(email);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? signedInWithUserEmailAndPassword,
|
||||
TResult Function(String email)? emailChanged,
|
||||
TResult Function(String password)? passwordChanged,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (emailChanged != null) {
|
||||
return emailChanged(email);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(SignedInWithUserEmailAndPassword value)
|
||||
signedInWithUserEmailAndPassword,
|
||||
required TResult Function(EmailChanged value) emailChanged,
|
||||
required TResult Function(PasswordChanged value) passwordChanged,
|
||||
}) {
|
||||
return emailChanged(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult Function(SignedInWithUserEmailAndPassword value)?
|
||||
signedInWithUserEmailAndPassword,
|
||||
TResult Function(EmailChanged value)? emailChanged,
|
||||
TResult Function(PasswordChanged value)? passwordChanged,
|
||||
}) {
|
||||
return emailChanged?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(SignedInWithUserEmailAndPassword value)?
|
||||
signedInWithUserEmailAndPassword,
|
||||
TResult Function(EmailChanged value)? emailChanged,
|
||||
TResult Function(PasswordChanged value)? passwordChanged,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (emailChanged != null) {
|
||||
return emailChanged(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class EmailChanged implements SignInEvent {
|
||||
const factory EmailChanged(String email) = _$EmailChanged;
|
||||
|
||||
String get email => throw _privateConstructorUsedError;
|
||||
@JsonKey(ignore: true)
|
||||
$EmailChangedCopyWith<EmailChanged> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $PasswordChangedCopyWith<$Res> {
|
||||
factory $PasswordChangedCopyWith(
|
||||
PasswordChanged value, $Res Function(PasswordChanged) then) =
|
||||
_$PasswordChangedCopyWithImpl<$Res>;
|
||||
$Res call({String password});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$PasswordChangedCopyWithImpl<$Res>
|
||||
extends _$SignInEventCopyWithImpl<$Res>
|
||||
implements $PasswordChangedCopyWith<$Res> {
|
||||
_$PasswordChangedCopyWithImpl(
|
||||
PasswordChanged _value, $Res Function(PasswordChanged) _then)
|
||||
: super(_value, (v) => _then(v as PasswordChanged));
|
||||
|
||||
@override
|
||||
PasswordChanged get _value => super._value as PasswordChanged;
|
||||
|
||||
@override
|
||||
$Res call({
|
||||
Object? password = freezed,
|
||||
}) {
|
||||
return _then(PasswordChanged(
|
||||
password == freezed
|
||||
? _value.password
|
||||
: password // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$PasswordChanged implements PasswordChanged {
|
||||
const _$PasswordChanged(this.password);
|
||||
|
||||
@override
|
||||
final String password;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SignInEvent.passwordChanged(password: $password)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(dynamic other) {
|
||||
return identical(this, other) ||
|
||||
(other is PasswordChanged &&
|
||||
(identical(other.password, password) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.password, password)));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
runtimeType.hashCode ^ const DeepCollectionEquality().hash(password);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
$PasswordChangedCopyWith<PasswordChanged> get copyWith =>
|
||||
_$PasswordChangedCopyWithImpl<PasswordChanged>(this, _$identity);
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() signedInWithUserEmailAndPassword,
|
||||
required TResult Function(String email) emailChanged,
|
||||
required TResult Function(String password) passwordChanged,
|
||||
}) {
|
||||
return passwordChanged(password);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult Function()? signedInWithUserEmailAndPassword,
|
||||
TResult Function(String email)? emailChanged,
|
||||
TResult Function(String password)? passwordChanged,
|
||||
}) {
|
||||
return passwordChanged?.call(password);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? signedInWithUserEmailAndPassword,
|
||||
TResult Function(String email)? emailChanged,
|
||||
TResult Function(String password)? passwordChanged,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (passwordChanged != null) {
|
||||
return passwordChanged(password);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(SignedInWithUserEmailAndPassword value)
|
||||
signedInWithUserEmailAndPassword,
|
||||
required TResult Function(EmailChanged value) emailChanged,
|
||||
required TResult Function(PasswordChanged value) passwordChanged,
|
||||
}) {
|
||||
return passwordChanged(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult Function(SignedInWithUserEmailAndPassword value)?
|
||||
signedInWithUserEmailAndPassword,
|
||||
TResult Function(EmailChanged value)? emailChanged,
|
||||
TResult Function(PasswordChanged value)? passwordChanged,
|
||||
}) {
|
||||
return passwordChanged?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(SignedInWithUserEmailAndPassword value)?
|
||||
signedInWithUserEmailAndPassword,
|
||||
TResult Function(EmailChanged value)? emailChanged,
|
||||
TResult Function(PasswordChanged value)? passwordChanged,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (passwordChanged != null) {
|
||||
return passwordChanged(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class PasswordChanged implements SignInEvent {
|
||||
const factory PasswordChanged(String password) = _$PasswordChanged;
|
||||
|
||||
String get password => throw _privateConstructorUsedError;
|
||||
@JsonKey(ignore: true)
|
||||
$PasswordChangedCopyWith<PasswordChanged> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$SignInStateTearOff {
|
||||
const _$SignInStateTearOff();
|
||||
|
||||
_SignInState call(
|
||||
{String? email,
|
||||
String? password,
|
||||
required bool isSubmitting,
|
||||
required Option<String> passwordError,
|
||||
required Option<String> emailError,
|
||||
required Option<Either<UserProfile, FlowyError>> successOrFail}) {
|
||||
return _SignInState(
|
||||
email: email,
|
||||
password: password,
|
||||
isSubmitting: isSubmitting,
|
||||
passwordError: passwordError,
|
||||
emailError: emailError,
|
||||
successOrFail: successOrFail,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
const $SignInState = _$SignInStateTearOff();
|
||||
|
||||
/// @nodoc
|
||||
mixin _$SignInState {
|
||||
String? get email => throw _privateConstructorUsedError;
|
||||
String? get password => throw _privateConstructorUsedError;
|
||||
bool get isSubmitting => throw _privateConstructorUsedError;
|
||||
Option<String> get passwordError => throw _privateConstructorUsedError;
|
||||
Option<String> get emailError => throw _privateConstructorUsedError;
|
||||
Option<Either<UserProfile, FlowyError>> get successOrFail =>
|
||||
throw _privateConstructorUsedError;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
$SignInStateCopyWith<SignInState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $SignInStateCopyWith<$Res> {
|
||||
factory $SignInStateCopyWith(
|
||||
SignInState value, $Res Function(SignInState) then) =
|
||||
_$SignInStateCopyWithImpl<$Res>;
|
||||
$Res call(
|
||||
{String? email,
|
||||
String? password,
|
||||
bool isSubmitting,
|
||||
Option<String> passwordError,
|
||||
Option<String> emailError,
|
||||
Option<Either<UserProfile, FlowyError>> successOrFail});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$SignInStateCopyWithImpl<$Res> implements $SignInStateCopyWith<$Res> {
|
||||
_$SignInStateCopyWithImpl(this._value, this._then);
|
||||
|
||||
final SignInState _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function(SignInState) _then;
|
||||
|
||||
@override
|
||||
$Res call({
|
||||
Object? email = freezed,
|
||||
Object? password = freezed,
|
||||
Object? isSubmitting = freezed,
|
||||
Object? passwordError = freezed,
|
||||
Object? emailError = freezed,
|
||||
Object? successOrFail = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
email: email == freezed
|
||||
? _value.email
|
||||
: email // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
password: password == freezed
|
||||
? _value.password
|
||||
: password // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
isSubmitting: isSubmitting == freezed
|
||||
? _value.isSubmitting
|
||||
: isSubmitting // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
passwordError: passwordError == freezed
|
||||
? _value.passwordError
|
||||
: passwordError // ignore: cast_nullable_to_non_nullable
|
||||
as Option<String>,
|
||||
emailError: emailError == freezed
|
||||
? _value.emailError
|
||||
: emailError // ignore: cast_nullable_to_non_nullable
|
||||
as Option<String>,
|
||||
successOrFail: successOrFail == freezed
|
||||
? _value.successOrFail
|
||||
: successOrFail // ignore: cast_nullable_to_non_nullable
|
||||
as Option<Either<UserProfile, FlowyError>>,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$SignInStateCopyWith<$Res>
|
||||
implements $SignInStateCopyWith<$Res> {
|
||||
factory _$SignInStateCopyWith(
|
||||
_SignInState value, $Res Function(_SignInState) then) =
|
||||
__$SignInStateCopyWithImpl<$Res>;
|
||||
@override
|
||||
$Res call(
|
||||
{String? email,
|
||||
String? password,
|
||||
bool isSubmitting,
|
||||
Option<String> passwordError,
|
||||
Option<String> emailError,
|
||||
Option<Either<UserProfile, FlowyError>> successOrFail});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$SignInStateCopyWithImpl<$Res> extends _$SignInStateCopyWithImpl<$Res>
|
||||
implements _$SignInStateCopyWith<$Res> {
|
||||
__$SignInStateCopyWithImpl(
|
||||
_SignInState _value, $Res Function(_SignInState) _then)
|
||||
: super(_value, (v) => _then(v as _SignInState));
|
||||
|
||||
@override
|
||||
_SignInState get _value => super._value as _SignInState;
|
||||
|
||||
@override
|
||||
$Res call({
|
||||
Object? email = freezed,
|
||||
Object? password = freezed,
|
||||
Object? isSubmitting = freezed,
|
||||
Object? passwordError = freezed,
|
||||
Object? emailError = freezed,
|
||||
Object? successOrFail = freezed,
|
||||
}) {
|
||||
return _then(_SignInState(
|
||||
email: email == freezed
|
||||
? _value.email
|
||||
: email // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
password: password == freezed
|
||||
? _value.password
|
||||
: password // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
isSubmitting: isSubmitting == freezed
|
||||
? _value.isSubmitting
|
||||
: isSubmitting // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
passwordError: passwordError == freezed
|
||||
? _value.passwordError
|
||||
: passwordError // ignore: cast_nullable_to_non_nullable
|
||||
as Option<String>,
|
||||
emailError: emailError == freezed
|
||||
? _value.emailError
|
||||
: emailError // ignore: cast_nullable_to_non_nullable
|
||||
as Option<String>,
|
||||
successOrFail: successOrFail == freezed
|
||||
? _value.successOrFail
|
||||
: successOrFail // ignore: cast_nullable_to_non_nullable
|
||||
as Option<Either<UserProfile, FlowyError>>,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$_SignInState implements _SignInState {
|
||||
const _$_SignInState(
|
||||
{this.email,
|
||||
this.password,
|
||||
required this.isSubmitting,
|
||||
required this.passwordError,
|
||||
required this.emailError,
|
||||
required this.successOrFail});
|
||||
|
||||
@override
|
||||
final String? email;
|
||||
@override
|
||||
final String? password;
|
||||
@override
|
||||
final bool isSubmitting;
|
||||
@override
|
||||
final Option<String> passwordError;
|
||||
@override
|
||||
final Option<String> emailError;
|
||||
@override
|
||||
final Option<Either<UserProfile, FlowyError>> successOrFail;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SignInState(email: $email, password: $password, isSubmitting: $isSubmitting, passwordError: $passwordError, emailError: $emailError, successOrFail: $successOrFail)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(dynamic other) {
|
||||
return identical(this, other) ||
|
||||
(other is _SignInState &&
|
||||
(identical(other.email, email) ||
|
||||
const DeepCollectionEquality().equals(other.email, email)) &&
|
||||
(identical(other.password, password) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.password, password)) &&
|
||||
(identical(other.isSubmitting, isSubmitting) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.isSubmitting, isSubmitting)) &&
|
||||
(identical(other.passwordError, passwordError) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.passwordError, passwordError)) &&
|
||||
(identical(other.emailError, emailError) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.emailError, emailError)) &&
|
||||
(identical(other.successOrFail, successOrFail) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.successOrFail, successOrFail)));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
runtimeType.hashCode ^
|
||||
const DeepCollectionEquality().hash(email) ^
|
||||
const DeepCollectionEquality().hash(password) ^
|
||||
const DeepCollectionEquality().hash(isSubmitting) ^
|
||||
const DeepCollectionEquality().hash(passwordError) ^
|
||||
const DeepCollectionEquality().hash(emailError) ^
|
||||
const DeepCollectionEquality().hash(successOrFail);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
_$SignInStateCopyWith<_SignInState> get copyWith =>
|
||||
__$SignInStateCopyWithImpl<_SignInState>(this, _$identity);
|
||||
}
|
||||
|
||||
abstract class _SignInState implements SignInState {
|
||||
const factory _SignInState(
|
||||
{String? email,
|
||||
String? password,
|
||||
required bool isSubmitting,
|
||||
required Option<String> passwordError,
|
||||
required Option<String> emailError,
|
||||
required Option<Either<UserProfile, FlowyError>> successOrFail}) =
|
||||
_$_SignInState;
|
||||
|
||||
@override
|
||||
String? get email => throw _privateConstructorUsedError;
|
||||
@override
|
||||
String? get password => throw _privateConstructorUsedError;
|
||||
@override
|
||||
bool get isSubmitting => throw _privateConstructorUsedError;
|
||||
@override
|
||||
Option<String> get passwordError => throw _privateConstructorUsedError;
|
||||
@override
|
||||
Option<String> get emailError => throw _privateConstructorUsedError;
|
||||
@override
|
||||
Option<Either<UserProfile, FlowyError>> get successOrFail =>
|
||||
throw _privateConstructorUsedError;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$SignInStateCopyWith<_SignInState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:app_flowy/user/infrastructure/repos/auth_repo.dart';
|
||||
import 'package:app_flowy/user/application/auth_service.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart' show UserProfile, ErrorCode;
|
||||
@@ -10,16 +10,16 @@ import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||
part 'sign_up_bloc.freezed.dart';
|
||||
|
||||
class SignUpBloc extends Bloc<SignUpEvent, SignUpState> {
|
||||
final AuthRepository autoRepo;
|
||||
SignUpBloc(this.autoRepo) : super(SignUpState.initial()) {
|
||||
final AuthService authService;
|
||||
SignUpBloc(this.authService) : super(SignUpState.initial()) {
|
||||
on<SignUpEvent>((event, emit) async {
|
||||
await event.map(signUpWithUserEmailAndPassword: (e) async {
|
||||
await _performActionOnSignUp(emit);
|
||||
}, emailChanged: (EmailChanged value) async {
|
||||
}, emailChanged: (_EmailChanged value) async {
|
||||
emit(state.copyWith(email: value.email, emailError: none(), successOrFail: none()));
|
||||
}, passwordChanged: (PasswordChanged value) async {
|
||||
}, passwordChanged: (_PasswordChanged value) async {
|
||||
emit(state.copyWith(password: value.password, passwordError: none(), successOrFail: none()));
|
||||
}, repeatPasswordChanged: (RepeatPasswordChanged value) async {
|
||||
}, repeatPasswordChanged: (_RepeatPasswordChanged value) async {
|
||||
emit(state.copyWith(repeatedPassword: value.password, repeatPasswordError: none(), successOrFail: none()));
|
||||
});
|
||||
});
|
||||
@@ -62,7 +62,7 @@ class SignUpBloc extends Bloc<SignUpEvent, SignUpState> {
|
||||
repeatPasswordError: none(),
|
||||
));
|
||||
|
||||
final result = await autoRepo.signUp(
|
||||
final result = await authService.signUp(
|
||||
name: state.email,
|
||||
password: state.password,
|
||||
email: state.email,
|
||||
@@ -104,9 +104,9 @@ class SignUpBloc extends Bloc<SignUpEvent, SignUpState> {
|
||||
@freezed
|
||||
class SignUpEvent with _$SignUpEvent {
|
||||
const factory SignUpEvent.signUpWithUserEmailAndPassword() = SignUpWithUserEmailAndPassword;
|
||||
const factory SignUpEvent.emailChanged(String email) = EmailChanged;
|
||||
const factory SignUpEvent.passwordChanged(String password) = PasswordChanged;
|
||||
const factory SignUpEvent.repeatPasswordChanged(String password) = RepeatPasswordChanged;
|
||||
const factory SignUpEvent.emailChanged(String email) = _EmailChanged;
|
||||
const factory SignUpEvent.passwordChanged(String password) = _PasswordChanged;
|
||||
const factory SignUpEvent.repeatPasswordChanged(String password) = _RepeatPasswordChanged;
|
||||
}
|
||||
|
||||
@freezed
|
||||
|
||||
@@ -1,312 +0,0 @@
|
||||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
|
||||
|
||||
part of 'splash_bloc.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
final _privateConstructorUsedError = UnsupportedError(
|
||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
|
||||
|
||||
/// @nodoc
|
||||
class _$SplashEventTearOff {
|
||||
const _$SplashEventTearOff();
|
||||
|
||||
_GetUser getUser() {
|
||||
return const _GetUser();
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
const $SplashEvent = _$SplashEventTearOff();
|
||||
|
||||
/// @nodoc
|
||||
mixin _$SplashEvent {
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() getUser,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult Function()? getUser,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? getUser,
|
||||
required TResult orElse(),
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(_GetUser value) getUser,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult Function(_GetUser value)? getUser,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(_GetUser value)? getUser,
|
||||
required TResult orElse(),
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $SplashEventCopyWith<$Res> {
|
||||
factory $SplashEventCopyWith(
|
||||
SplashEvent value, $Res Function(SplashEvent) then) =
|
||||
_$SplashEventCopyWithImpl<$Res>;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$SplashEventCopyWithImpl<$Res> implements $SplashEventCopyWith<$Res> {
|
||||
_$SplashEventCopyWithImpl(this._value, this._then);
|
||||
|
||||
final SplashEvent _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function(SplashEvent) _then;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$GetUserCopyWith<$Res> {
|
||||
factory _$GetUserCopyWith(_GetUser value, $Res Function(_GetUser) then) =
|
||||
__$GetUserCopyWithImpl<$Res>;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$GetUserCopyWithImpl<$Res> extends _$SplashEventCopyWithImpl<$Res>
|
||||
implements _$GetUserCopyWith<$Res> {
|
||||
__$GetUserCopyWithImpl(_GetUser _value, $Res Function(_GetUser) _then)
|
||||
: super(_value, (v) => _then(v as _GetUser));
|
||||
|
||||
@override
|
||||
_GetUser get _value => super._value as _GetUser;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$_GetUser implements _GetUser {
|
||||
const _$_GetUser();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SplashEvent.getUser()';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(dynamic other) {
|
||||
return identical(this, other) || (other is _GetUser);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => runtimeType.hashCode;
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function() getUser,
|
||||
}) {
|
||||
return getUser();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult Function()? getUser,
|
||||
}) {
|
||||
return getUser?.call();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function()? getUser,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (getUser != null) {
|
||||
return getUser();
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(_GetUser value) getUser,
|
||||
}) {
|
||||
return getUser(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult Function(_GetUser value)? getUser,
|
||||
}) {
|
||||
return getUser?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(_GetUser value)? getUser,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (getUser != null) {
|
||||
return getUser(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _GetUser implements SplashEvent {
|
||||
const factory _GetUser() = _$_GetUser;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$SplashStateTearOff {
|
||||
const _$SplashStateTearOff();
|
||||
|
||||
_SplashState call({required AuthState auth}) {
|
||||
return _SplashState(
|
||||
auth: auth,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
const $SplashState = _$SplashStateTearOff();
|
||||
|
||||
/// @nodoc
|
||||
mixin _$SplashState {
|
||||
AuthState get auth => throw _privateConstructorUsedError;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
$SplashStateCopyWith<SplashState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $SplashStateCopyWith<$Res> {
|
||||
factory $SplashStateCopyWith(
|
||||
SplashState value, $Res Function(SplashState) then) =
|
||||
_$SplashStateCopyWithImpl<$Res>;
|
||||
$Res call({AuthState auth});
|
||||
|
||||
$AuthStateCopyWith<$Res> get auth;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$SplashStateCopyWithImpl<$Res> implements $SplashStateCopyWith<$Res> {
|
||||
_$SplashStateCopyWithImpl(this._value, this._then);
|
||||
|
||||
final SplashState _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function(SplashState) _then;
|
||||
|
||||
@override
|
||||
$Res call({
|
||||
Object? auth = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
auth: auth == freezed
|
||||
? _value.auth
|
||||
: auth // ignore: cast_nullable_to_non_nullable
|
||||
as AuthState,
|
||||
));
|
||||
}
|
||||
|
||||
@override
|
||||
$AuthStateCopyWith<$Res> get auth {
|
||||
return $AuthStateCopyWith<$Res>(_value.auth, (value) {
|
||||
return _then(_value.copyWith(auth: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$SplashStateCopyWith<$Res>
|
||||
implements $SplashStateCopyWith<$Res> {
|
||||
factory _$SplashStateCopyWith(
|
||||
_SplashState value, $Res Function(_SplashState) then) =
|
||||
__$SplashStateCopyWithImpl<$Res>;
|
||||
@override
|
||||
$Res call({AuthState auth});
|
||||
|
||||
@override
|
||||
$AuthStateCopyWith<$Res> get auth;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$SplashStateCopyWithImpl<$Res> extends _$SplashStateCopyWithImpl<$Res>
|
||||
implements _$SplashStateCopyWith<$Res> {
|
||||
__$SplashStateCopyWithImpl(
|
||||
_SplashState _value, $Res Function(_SplashState) _then)
|
||||
: super(_value, (v) => _then(v as _SplashState));
|
||||
|
||||
@override
|
||||
_SplashState get _value => super._value as _SplashState;
|
||||
|
||||
@override
|
||||
$Res call({
|
||||
Object? auth = freezed,
|
||||
}) {
|
||||
return _then(_SplashState(
|
||||
auth: auth == freezed
|
||||
? _value.auth
|
||||
: auth // ignore: cast_nullable_to_non_nullable
|
||||
as AuthState,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$_SplashState implements _SplashState {
|
||||
const _$_SplashState({required this.auth});
|
||||
|
||||
@override
|
||||
final AuthState auth;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SplashState(auth: $auth)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(dynamic other) {
|
||||
return identical(this, other) ||
|
||||
(other is _SplashState &&
|
||||
(identical(other.auth, auth) ||
|
||||
const DeepCollectionEquality().equals(other.auth, auth)));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
runtimeType.hashCode ^ const DeepCollectionEquality().hash(auth);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
_$SplashStateCopyWith<_SplashState> get copyWith =>
|
||||
__$SplashStateCopyWithImpl<_SplashState>(this, _$identity);
|
||||
}
|
||||
|
||||
abstract class _SplashState implements SplashState {
|
||||
const factory _SplashState({required AuthState auth}) = _$_SplashState;
|
||||
|
||||
@override
|
||||
AuthState get auth => throw _privateConstructorUsedError;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$SplashStateCopyWith<_SplashState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
import 'dart:async';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'dart:typed_data';
|
||||
import 'package:app_flowy/core/notification_helper.dart';
|
||||
import 'package:flowy_infra/notifier.dart';
|
||||
import 'package:flowy_sdk/protobuf/dart-notify/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-data-model/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/dart_notification.pb.dart' as user;
|
||||
import 'package:flowy_sdk/rust_stream.dart';
|
||||
|
||||
typedef UserProfileNotifyValue = Either<UserProfile, FlowyError>;
|
||||
typedef AuthNotifyValue = Either<Unit, FlowyError>;
|
||||
typedef WorkspaceListNotifyValue = Either<List<Workspace>, FlowyError>;
|
||||
typedef WorkspaceSettingNotifyValue = Either<CurrentWorkspaceSetting, FlowyError>;
|
||||
|
||||
class UserListener {
|
||||
StreamSubscription<SubscribeObject>? _subscription;
|
||||
final _profileNotifier = PublishNotifier<UserProfileNotifyValue>();
|
||||
final _authNotifier = PublishNotifier<AuthNotifyValue>();
|
||||
final _workspaceListNotifier = PublishNotifier<WorkspaceListNotifyValue>();
|
||||
final _workSettingNotifier = PublishNotifier<WorkspaceSettingNotifyValue>();
|
||||
|
||||
FolderNotificationParser? _workspaceParser;
|
||||
UserNotificationParser? _userParser;
|
||||
final UserProfile _user;
|
||||
UserListener({
|
||||
required UserProfile user,
|
||||
}) : _user = user;
|
||||
|
||||
void start({
|
||||
void Function(AuthNotifyValue)? onAuthChanged,
|
||||
void Function(UserProfileNotifyValue)? onProfileUpdated,
|
||||
void Function(WorkspaceListNotifyValue)? onWorkspaceListUpdated,
|
||||
void Function(WorkspaceSettingNotifyValue)? onWorkspaceSettingUpdated,
|
||||
}) {
|
||||
if (onAuthChanged != null) {
|
||||
_authNotifier.addListener(() {
|
||||
onAuthChanged(_authNotifier.currentValue!);
|
||||
});
|
||||
}
|
||||
|
||||
if (onProfileUpdated != null) {
|
||||
_profileNotifier.addListener(() {
|
||||
onProfileUpdated(_profileNotifier.currentValue!);
|
||||
});
|
||||
}
|
||||
|
||||
if (onWorkspaceListUpdated != null) {
|
||||
_workspaceListNotifier.addListener(() {
|
||||
onWorkspaceListUpdated(_workspaceListNotifier.currentValue!);
|
||||
});
|
||||
}
|
||||
|
||||
if (onWorkspaceSettingUpdated != null) {
|
||||
_workSettingNotifier.addListener(() {
|
||||
onWorkspaceSettingUpdated(_workSettingNotifier.currentValue!);
|
||||
});
|
||||
}
|
||||
|
||||
_workspaceParser = FolderNotificationParser(id: _user.token, callback: _notificationCallback);
|
||||
_userParser = UserNotificationParser(id: _user.token, callback: _userNotificationCallback);
|
||||
_subscription = RustStreamReceiver.listen((observable) {
|
||||
_workspaceParser?.parse(observable);
|
||||
_userParser?.parse(observable);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> stop() async {
|
||||
_workspaceParser = null;
|
||||
_userParser = null;
|
||||
await _subscription?.cancel();
|
||||
_profileNotifier.dispose();
|
||||
_authNotifier.dispose();
|
||||
_workspaceListNotifier.dispose();
|
||||
}
|
||||
|
||||
void _notificationCallback(FolderNotification ty, Either<Uint8List, FlowyError> result) {
|
||||
switch (ty) {
|
||||
case FolderNotification.UserCreateWorkspace:
|
||||
case FolderNotification.UserDeleteWorkspace:
|
||||
case FolderNotification.WorkspaceListUpdated:
|
||||
result.fold(
|
||||
(payload) => _workspaceListNotifier.value = left(RepeatedWorkspace.fromBuffer(payload).items),
|
||||
(error) => _workspaceListNotifier.value = right(error),
|
||||
);
|
||||
break;
|
||||
case FolderNotification.WorkspaceSetting:
|
||||
result.fold(
|
||||
(payload) => _workSettingNotifier.value = left(CurrentWorkspaceSetting.fromBuffer(payload)),
|
||||
(error) => _workSettingNotifier.value = right(error),
|
||||
);
|
||||
break;
|
||||
case FolderNotification.UserUnauthorized:
|
||||
result.fold(
|
||||
(_) {},
|
||||
(error) => _authNotifier.value = right(FlowyError.create()..code = ErrorCode.UserUnauthorized.value),
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void _userNotificationCallback(user.UserNotification ty, Either<Uint8List, FlowyError> result) {
|
||||
switch (ty) {
|
||||
case user.UserNotification.UserUnauthorized:
|
||||
result.fold(
|
||||
(payload) => _profileNotifier.value = left(UserProfile.fromBuffer(payload)),
|
||||
(error) => _profileNotifier.value = right(error),
|
||||
);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import 'dart:async';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart';
|
||||
|
||||
class UserService {
|
||||
Future<Either<UserProfile, FlowyError>> fetchUserProfile({required String userId}) {
|
||||
return UserEventGetUserProfile().send();
|
||||
}
|
||||
|
||||
Future<Either<Unit, FlowyError>> deleteWorkspace({required String workspaceId}) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
Future<Either<Unit, FlowyError>> signOut() {
|
||||
return UserEventSignOut().send();
|
||||
}
|
||||
|
||||
Future<Either<Unit, FlowyError>> initUser() async {
|
||||
return UserEventInitUser().send();
|
||||
}
|
||||
|
||||
Future<Either<List<Workspace>, FlowyError>> getWorkspaces() {
|
||||
final request = WorkspaceId.create();
|
||||
|
||||
return FolderEventReadWorkspaces(request).send().then((result) {
|
||||
return result.fold(
|
||||
(workspaces) => left(workspaces.items),
|
||||
(error) => right(error),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Future<Either<Workspace, FlowyError>> openWorkspace(String workspaceId) {
|
||||
final request = WorkspaceId.create()..value = workspaceId;
|
||||
return FolderEventOpenWorkspace(request).send().then((result) {
|
||||
return result.fold(
|
||||
(workspace) => left(workspace),
|
||||
(error) => right(error),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Future<Either<Workspace, FlowyError>> createWorkspace(String name, String desc) {
|
||||
final request = CreateWorkspacePayload.create()
|
||||
..name = name
|
||||
..desc = desc;
|
||||
return FolderEventCreateWorkspace(request).send().then((result) {
|
||||
return result.fold(
|
||||
(workspace) => left(workspace),
|
||||
(error) => right(error),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import 'package:flowy_sdk/flowy_sdk.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_setting.pb.dart';
|
||||
|
||||
class UserSettingReppsitory {
|
||||
class UserSettingsService {
|
||||
Future<AppearanceSettings> getAppearanceSettings() async {
|
||||
final result = await UserEventGetAppearanceSetting().send();
|
||||
|
||||
@@ -4,7 +4,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
part 'auth_state.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class AuthState with _$AuthState {
|
||||
class AuthState with _$AuthState {
|
||||
const factory AuthState.authenticated(UserProfile userProfile) = Authenticated;
|
||||
const factory AuthState.unauthenticated(FlowyError error) = Unauthenticated;
|
||||
const factory AuthState.initial() = _Initial;
|
||||
|
||||
@@ -1,487 +0,0 @@
|
||||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
|
||||
|
||||
part of 'auth_state.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
final _privateConstructorUsedError = UnsupportedError(
|
||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
|
||||
|
||||
/// @nodoc
|
||||
class _$AuthStateTearOff {
|
||||
const _$AuthStateTearOff();
|
||||
|
||||
Authenticated authenticated(UserProfile userProfile) {
|
||||
return Authenticated(
|
||||
userProfile,
|
||||
);
|
||||
}
|
||||
|
||||
Unauthenticated unauthenticated(FlowyError error) {
|
||||
return Unauthenticated(
|
||||
error,
|
||||
);
|
||||
}
|
||||
|
||||
_Initial initial() {
|
||||
return const _Initial();
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
const $AuthState = _$AuthStateTearOff();
|
||||
|
||||
/// @nodoc
|
||||
mixin _$AuthState {
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function(UserProfile userProfile) authenticated,
|
||||
required TResult Function(FlowyError error) unauthenticated,
|
||||
required TResult Function() initial,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult Function(UserProfile userProfile)? authenticated,
|
||||
TResult Function(FlowyError error)? unauthenticated,
|
||||
TResult Function()? initial,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function(UserProfile userProfile)? authenticated,
|
||||
TResult Function(FlowyError error)? unauthenticated,
|
||||
TResult Function()? initial,
|
||||
required TResult orElse(),
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(Authenticated value) authenticated,
|
||||
required TResult Function(Unauthenticated value) unauthenticated,
|
||||
required TResult Function(_Initial value) initial,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult Function(Authenticated value)? authenticated,
|
||||
TResult Function(Unauthenticated value)? unauthenticated,
|
||||
TResult Function(_Initial value)? initial,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(Authenticated value)? authenticated,
|
||||
TResult Function(Unauthenticated value)? unauthenticated,
|
||||
TResult Function(_Initial value)? initial,
|
||||
required TResult orElse(),
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $AuthStateCopyWith<$Res> {
|
||||
factory $AuthStateCopyWith(AuthState value, $Res Function(AuthState) then) =
|
||||
_$AuthStateCopyWithImpl<$Res>;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$AuthStateCopyWithImpl<$Res> implements $AuthStateCopyWith<$Res> {
|
||||
_$AuthStateCopyWithImpl(this._value, this._then);
|
||||
|
||||
final AuthState _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function(AuthState) _then;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $AuthenticatedCopyWith<$Res> {
|
||||
factory $AuthenticatedCopyWith(
|
||||
Authenticated value, $Res Function(Authenticated) then) =
|
||||
_$AuthenticatedCopyWithImpl<$Res>;
|
||||
$Res call({UserProfile userProfile});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$AuthenticatedCopyWithImpl<$Res> extends _$AuthStateCopyWithImpl<$Res>
|
||||
implements $AuthenticatedCopyWith<$Res> {
|
||||
_$AuthenticatedCopyWithImpl(
|
||||
Authenticated _value, $Res Function(Authenticated) _then)
|
||||
: super(_value, (v) => _then(v as Authenticated));
|
||||
|
||||
@override
|
||||
Authenticated get _value => super._value as Authenticated;
|
||||
|
||||
@override
|
||||
$Res call({
|
||||
Object? userProfile = freezed,
|
||||
}) {
|
||||
return _then(Authenticated(
|
||||
userProfile == freezed
|
||||
? _value.userProfile
|
||||
: userProfile // ignore: cast_nullable_to_non_nullable
|
||||
as UserProfile,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$Authenticated implements Authenticated {
|
||||
const _$Authenticated(this.userProfile);
|
||||
|
||||
@override
|
||||
final UserProfile userProfile;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AuthState.authenticated(userProfile: $userProfile)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(dynamic other) {
|
||||
return identical(this, other) ||
|
||||
(other is Authenticated &&
|
||||
(identical(other.userProfile, userProfile) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.userProfile, userProfile)));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
runtimeType.hashCode ^ const DeepCollectionEquality().hash(userProfile);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
$AuthenticatedCopyWith<Authenticated> get copyWith =>
|
||||
_$AuthenticatedCopyWithImpl<Authenticated>(this, _$identity);
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function(UserProfile userProfile) authenticated,
|
||||
required TResult Function(FlowyError error) unauthenticated,
|
||||
required TResult Function() initial,
|
||||
}) {
|
||||
return authenticated(userProfile);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult Function(UserProfile userProfile)? authenticated,
|
||||
TResult Function(FlowyError error)? unauthenticated,
|
||||
TResult Function()? initial,
|
||||
}) {
|
||||
return authenticated?.call(userProfile);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function(UserProfile userProfile)? authenticated,
|
||||
TResult Function(FlowyError error)? unauthenticated,
|
||||
TResult Function()? initial,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (authenticated != null) {
|
||||
return authenticated(userProfile);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(Authenticated value) authenticated,
|
||||
required TResult Function(Unauthenticated value) unauthenticated,
|
||||
required TResult Function(_Initial value) initial,
|
||||
}) {
|
||||
return authenticated(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult Function(Authenticated value)? authenticated,
|
||||
TResult Function(Unauthenticated value)? unauthenticated,
|
||||
TResult Function(_Initial value)? initial,
|
||||
}) {
|
||||
return authenticated?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(Authenticated value)? authenticated,
|
||||
TResult Function(Unauthenticated value)? unauthenticated,
|
||||
TResult Function(_Initial value)? initial,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (authenticated != null) {
|
||||
return authenticated(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Authenticated implements AuthState {
|
||||
const factory Authenticated(UserProfile userProfile) = _$Authenticated;
|
||||
|
||||
UserProfile get userProfile => throw _privateConstructorUsedError;
|
||||
@JsonKey(ignore: true)
|
||||
$AuthenticatedCopyWith<Authenticated> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $UnauthenticatedCopyWith<$Res> {
|
||||
factory $UnauthenticatedCopyWith(
|
||||
Unauthenticated value, $Res Function(Unauthenticated) then) =
|
||||
_$UnauthenticatedCopyWithImpl<$Res>;
|
||||
$Res call({FlowyError error});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$UnauthenticatedCopyWithImpl<$Res> extends _$AuthStateCopyWithImpl<$Res>
|
||||
implements $UnauthenticatedCopyWith<$Res> {
|
||||
_$UnauthenticatedCopyWithImpl(
|
||||
Unauthenticated _value, $Res Function(Unauthenticated) _then)
|
||||
: super(_value, (v) => _then(v as Unauthenticated));
|
||||
|
||||
@override
|
||||
Unauthenticated get _value => super._value as Unauthenticated;
|
||||
|
||||
@override
|
||||
$Res call({
|
||||
Object? error = freezed,
|
||||
}) {
|
||||
return _then(Unauthenticated(
|
||||
error == freezed
|
||||
? _value.error
|
||||
: error // ignore: cast_nullable_to_non_nullable
|
||||
as FlowyError,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$Unauthenticated implements Unauthenticated {
|
||||
const _$Unauthenticated(this.error);
|
||||
|
||||
@override
|
||||
final FlowyError error;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AuthState.unauthenticated(error: $error)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(dynamic other) {
|
||||
return identical(this, other) ||
|
||||
(other is Unauthenticated &&
|
||||
(identical(other.error, error) ||
|
||||
const DeepCollectionEquality().equals(other.error, error)));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
runtimeType.hashCode ^ const DeepCollectionEquality().hash(error);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
$UnauthenticatedCopyWith<Unauthenticated> get copyWith =>
|
||||
_$UnauthenticatedCopyWithImpl<Unauthenticated>(this, _$identity);
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function(UserProfile userProfile) authenticated,
|
||||
required TResult Function(FlowyError error) unauthenticated,
|
||||
required TResult Function() initial,
|
||||
}) {
|
||||
return unauthenticated(error);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult Function(UserProfile userProfile)? authenticated,
|
||||
TResult Function(FlowyError error)? unauthenticated,
|
||||
TResult Function()? initial,
|
||||
}) {
|
||||
return unauthenticated?.call(error);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function(UserProfile userProfile)? authenticated,
|
||||
TResult Function(FlowyError error)? unauthenticated,
|
||||
TResult Function()? initial,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (unauthenticated != null) {
|
||||
return unauthenticated(error);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(Authenticated value) authenticated,
|
||||
required TResult Function(Unauthenticated value) unauthenticated,
|
||||
required TResult Function(_Initial value) initial,
|
||||
}) {
|
||||
return unauthenticated(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult Function(Authenticated value)? authenticated,
|
||||
TResult Function(Unauthenticated value)? unauthenticated,
|
||||
TResult Function(_Initial value)? initial,
|
||||
}) {
|
||||
return unauthenticated?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(Authenticated value)? authenticated,
|
||||
TResult Function(Unauthenticated value)? unauthenticated,
|
||||
TResult Function(_Initial value)? initial,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (unauthenticated != null) {
|
||||
return unauthenticated(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Unauthenticated implements AuthState {
|
||||
const factory Unauthenticated(FlowyError error) = _$Unauthenticated;
|
||||
|
||||
FlowyError get error => throw _privateConstructorUsedError;
|
||||
@JsonKey(ignore: true)
|
||||
$UnauthenticatedCopyWith<Unauthenticated> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$InitialCopyWith<$Res> {
|
||||
factory _$InitialCopyWith(_Initial value, $Res Function(_Initial) then) =
|
||||
__$InitialCopyWithImpl<$Res>;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$InitialCopyWithImpl<$Res> extends _$AuthStateCopyWithImpl<$Res>
|
||||
implements _$InitialCopyWith<$Res> {
|
||||
__$InitialCopyWithImpl(_Initial _value, $Res Function(_Initial) _then)
|
||||
: super(_value, (v) => _then(v as _Initial));
|
||||
|
||||
@override
|
||||
_Initial get _value => super._value as _Initial;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$_Initial implements _Initial {
|
||||
const _$_Initial();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AuthState.initial()';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(dynamic other) {
|
||||
return identical(this, other) || (other is _Initial);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => runtimeType.hashCode;
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function(UserProfile userProfile) authenticated,
|
||||
required TResult Function(FlowyError error) unauthenticated,
|
||||
required TResult Function() initial,
|
||||
}) {
|
||||
return initial();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult Function(UserProfile userProfile)? authenticated,
|
||||
TResult Function(FlowyError error)? unauthenticated,
|
||||
TResult Function()? initial,
|
||||
}) {
|
||||
return initial?.call();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function(UserProfile userProfile)? authenticated,
|
||||
TResult Function(FlowyError error)? unauthenticated,
|
||||
TResult Function()? initial,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (initial != null) {
|
||||
return initial();
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(Authenticated value) authenticated,
|
||||
required TResult Function(Unauthenticated value) unauthenticated,
|
||||
required TResult Function(_Initial value) initial,
|
||||
}) {
|
||||
return initial(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult Function(Authenticated value)? authenticated,
|
||||
TResult Function(Unauthenticated value)? unauthenticated,
|
||||
TResult Function(_Initial value)? initial,
|
||||
}) {
|
||||
return initial?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(Authenticated value)? authenticated,
|
||||
TResult Function(Unauthenticated value)? unauthenticated,
|
||||
TResult Function(_Initial value)? initial,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (initial != null) {
|
||||
return initial(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _Initial implements AuthState {
|
||||
const factory _Initial() = _$_Initial;
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
import 'package:app_flowy/user/application/sign_in_bloc.dart';
|
||||
import 'package:app_flowy/user/application/sign_up_bloc.dart';
|
||||
import 'package:app_flowy/user/application/splash_bloc.dart';
|
||||
import 'package:app_flowy/user/infrastructure/repos/auth_repo.dart';
|
||||
import 'package:app_flowy/user/infrastructure/router.dart';
|
||||
import 'package:app_flowy/workspace/application/edit_pannel/edit_pannel_bloc.dart';
|
||||
import 'package:app_flowy/workspace/application/home/home_bloc.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
|
||||
import 'network_monitor.dart';
|
||||
|
||||
class UserDepsResolver {
|
||||
static Future<void> resolve(GetIt getIt) async {
|
||||
getIt.registerFactory<AuthRepository>(() => AuthRepository());
|
||||
|
||||
//Interface implementation
|
||||
getIt.registerFactory<AuthRouter>(() => AuthRouter());
|
||||
|
||||
//Bloc
|
||||
getIt.registerFactory<SignInBloc>(() => SignInBloc(getIt<AuthRepository>()));
|
||||
getIt.registerFactory<SignUpBloc>(() => SignUpBloc(getIt<AuthRepository>()));
|
||||
|
||||
getIt.registerFactory<SplashRoute>(() => SplashRoute());
|
||||
getIt.registerFactory<HomeBloc>(() => HomeBloc());
|
||||
getIt.registerFactory<EditPannelBloc>(() => EditPannelBloc());
|
||||
getIt.registerFactory<SplashBloc>(() => SplashBloc());
|
||||
getIt.registerLazySingleton<NetworkMonitor>(() => NetworkMonitor());
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/user/infrastructure/repos/auth_repo.dart';
|
||||
import 'package:app_flowy/user/application/auth_service.dart';
|
||||
import 'package:app_flowy/user/presentation/sign_in_screen.dart';
|
||||
import 'package:app_flowy/user/presentation/sign_up_screen.dart';
|
||||
import 'package:app_flowy/user/presentation/skip_log_in_screen.dart';
|
||||
import 'package:app_flowy/user/presentation/welcome_screen.dart';
|
||||
import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
|
||||
import 'package:app_flowy/workspace/presentation/home/home_screen.dart';
|
||||
import 'package:flowy_infra/time/duration.dart';
|
||||
import 'package:flowy_infra_ui/widget/route/animation.dart';
|
||||
@@ -38,9 +37,8 @@ class AuthRouter {
|
||||
}
|
||||
|
||||
class SplashRoute {
|
||||
Future<void> pushWelcomeScreen(BuildContext context, UserProfile user) async {
|
||||
final repo = UserRepo(user: user);
|
||||
final screen = WelcomeScreen(repo: repo);
|
||||
Future<void> pushWelcomeScreen(BuildContext context, UserProfile userProfile) async {
|
||||
final screen = WelcomeScreen(userProfile: userProfile);
|
||||
final workspaceId = await Navigator.of(context).push(
|
||||
PageRoutes.fade(
|
||||
() => screen,
|
||||
@@ -48,7 +46,7 @@ class SplashRoute {
|
||||
),
|
||||
);
|
||||
|
||||
pushHomeScreen(context, repo.user, workspaceId);
|
||||
pushHomeScreen(context, userProfile, workspaceId);
|
||||
}
|
||||
|
||||
void pushHomeScreen(BuildContext context, UserProfile userProfile, CurrentWorkspaceSetting workspaceSetting) {
|
||||
@@ -71,7 +69,7 @@ class SplashRoute {
|
||||
PageRoutes.fade(
|
||||
() => SkipLogInScreen(
|
||||
router: getIt<AuthRouter>(),
|
||||
authRepo: getIt<AuthRepository>(),
|
||||
authService: getIt<AuthService>(),
|
||||
),
|
||||
RouteDurations.slow.inMilliseconds * .001),
|
||||
);
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/user/application/sign_in_bloc.dart';
|
||||
import 'package:app_flowy/user/infrastructure/router.dart';
|
||||
import 'package:app_flowy/user/presentation/router.dart';
|
||||
import 'package:app_flowy/user/presentation/widgets/background.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
@@ -170,11 +170,11 @@ class PasswordTextField extends StatelessWidget {
|
||||
return RoundedInputField(
|
||||
obscureText: true,
|
||||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||||
obscureIcon: svg("home/hide"),
|
||||
obscureHideIcon: svg("home/show"),
|
||||
obscureIcon: svgWidget("home/hide"),
|
||||
obscureHideIcon: svgWidget("home/show"),
|
||||
hintText: LocaleKeys.signIn_passwordHint.tr(),
|
||||
normalBorderColor: theme.shader4,
|
||||
highlightBorderColor: theme.red,
|
||||
errorBorderColor: theme.red,
|
||||
cursorColor: theme.main1,
|
||||
errorText: context.read<SignInBloc>().state.passwordError.fold(() => "", (error) => error),
|
||||
onChanged: (value) => context.read<SignInBloc>().add(SignInEvent.passwordChanged(value)),
|
||||
@@ -199,7 +199,7 @@ class EmailTextField extends StatelessWidget {
|
||||
hintText: LocaleKeys.signIn_emailHint.tr(),
|
||||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||||
normalBorderColor: theme.shader4,
|
||||
highlightBorderColor: theme.red,
|
||||
errorBorderColor: theme.red,
|
||||
cursorColor: theme.main1,
|
||||
errorText: context.read<SignInBloc>().state.emailError.fold(() => "", (error) => error),
|
||||
onChanged: (value) => context.read<SignInBloc>().add(SignInEvent.emailChanged(value)),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/user/application/sign_up_bloc.dart';
|
||||
import 'package:app_flowy/user/infrastructure/router.dart';
|
||||
import 'package:app_flowy/user/presentation/router.dart';
|
||||
import 'package:app_flowy/user/presentation/widgets/background.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
@@ -134,12 +134,12 @@ class PasswordTextField extends StatelessWidget {
|
||||
builder: (context, state) {
|
||||
return RoundedInputField(
|
||||
obscureText: true,
|
||||
obscureIcon: svg("home/hide"),
|
||||
obscureHideIcon: svg("home/show"),
|
||||
obscureIcon: svgWidget("home/hide"),
|
||||
obscureHideIcon: svgWidget("home/show"),
|
||||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||||
hintText: LocaleKeys.signUp_passwordHint.tr(),
|
||||
normalBorderColor: theme.shader4,
|
||||
highlightBorderColor: theme.red,
|
||||
errorBorderColor: theme.red,
|
||||
cursorColor: theme.main1,
|
||||
errorText: context.read<SignUpBloc>().state.passwordError.fold(() => "", (error) => error),
|
||||
onChanged: (value) => context.read<SignUpBloc>().add(SignUpEvent.passwordChanged(value)),
|
||||
@@ -162,12 +162,12 @@ class RepeatPasswordTextField extends StatelessWidget {
|
||||
builder: (context, state) {
|
||||
return RoundedInputField(
|
||||
obscureText: true,
|
||||
obscureIcon: svg("home/hide"),
|
||||
obscureHideIcon: svg("home/show"),
|
||||
obscureIcon: svgWidget("home/hide"),
|
||||
obscureHideIcon: svgWidget("home/show"),
|
||||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||||
hintText: LocaleKeys.signUp_repeatPasswordHint.tr(),
|
||||
normalBorderColor: theme.shader4,
|
||||
highlightBorderColor: theme.red,
|
||||
errorBorderColor: theme.red,
|
||||
cursorColor: theme.main1,
|
||||
errorText: context.read<SignUpBloc>().state.repeatPasswordError.fold(() => "", (error) => error),
|
||||
onChanged: (value) => context.read<SignUpBloc>().add(SignUpEvent.repeatPasswordChanged(value)),
|
||||
@@ -192,7 +192,7 @@ class EmailTextField extends StatelessWidget {
|
||||
hintText: LocaleKeys.signUp_emailHint.tr(),
|
||||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
|
||||
normalBorderColor: theme.shader4,
|
||||
highlightBorderColor: theme.red,
|
||||
errorBorderColor: theme.red,
|
||||
cursorColor: theme.main1,
|
||||
errorText: context.read<SignUpBloc>().state.emailError.fold(() => "", (error) => error),
|
||||
onChanged: (value) => context.read<SignUpBloc>().add(SignUpEvent.emailChanged(value)),
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import 'package:app_flowy/user/infrastructure/router.dart';
|
||||
import 'package:app_flowy/user/infrastructure/repos/auth_repo.dart';
|
||||
import 'package:app_flowy/user/application/auth_service.dart';
|
||||
import 'package:app_flowy/user/application/user_listener.dart';
|
||||
import 'package:app_flowy/user/presentation/router.dart';
|
||||
import 'package:app_flowy/user/presentation/widgets/background.dart';
|
||||
import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra/uuid.dart';
|
||||
import 'package:flowy_infra_ui/widget/rounded_button.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flowy_log/flowy_log.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
@@ -21,12 +21,12 @@ import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||
|
||||
class SkipLogInScreen extends StatefulWidget {
|
||||
final AuthRouter router;
|
||||
final AuthRepository authRepo;
|
||||
final AuthService authService;
|
||||
|
||||
const SkipLogInScreen({
|
||||
Key? key,
|
||||
required this.router,
|
||||
required this.authRepo,
|
||||
required this.authService,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
@@ -88,8 +88,9 @@ class _SkipLogInScreenState extends State<SkipLogInScreen> {
|
||||
}
|
||||
|
||||
_launchURL(String url) async {
|
||||
if (await canLaunch(url)) {
|
||||
await launch(url);
|
||||
final uri = Uri.parse(url);
|
||||
if (await canLaunchUrl(uri)) {
|
||||
await launchUrl(uri);
|
||||
} else {
|
||||
throw 'Could not launch $url';
|
||||
}
|
||||
@@ -99,7 +100,7 @@ class _SkipLogInScreenState extends State<SkipLogInScreen> {
|
||||
const password = "AppFlowy123@";
|
||||
final uid = uuid();
|
||||
final userEmail = "$uid@appflowy.io";
|
||||
final result = await widget.authRepo.signUp(
|
||||
final result = await widget.authService.signUp(
|
||||
name: LocaleKeys.defaultUsername.tr(),
|
||||
password: password,
|
||||
email: userEmail,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/user/application/splash_bloc.dart';
|
||||
import 'package:app_flowy/user/domain/auth_state.dart';
|
||||
import 'package:app_flowy/user/infrastructure/router.dart';
|
||||
import 'package:flowy_log/flowy_log.dart';
|
||||
import 'package:app_flowy/user/presentation/router.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/error-code/error_code.pbenum.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
|
||||
@@ -6,22 +6,22 @@ import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||
import 'package:flowy_infra_ui/widget/error_page.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
|
||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||
|
||||
class WelcomeScreen extends StatelessWidget {
|
||||
final UserRepo repo;
|
||||
final UserProfile userProfile;
|
||||
const WelcomeScreen({
|
||||
Key? key,
|
||||
required this.repo,
|
||||
required this.userProfile,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (_) => getIt<WelcomeBloc>(param1: repo.user)..add(const WelcomeEvent.initial()),
|
||||
create: (_) => getIt<WelcomeBloc>(param1: userProfile)..add(const WelcomeEvent.initial()),
|
||||
child: BlocBuilder<WelcomeBloc, WelcomeState>(
|
||||
builder: (context, state) {
|
||||
return Scaffold(
|
||||
|
||||
@@ -44,7 +44,7 @@ class FlowyLogoTitle extends StatelessWidget {
|
||||
children: [
|
||||
SizedBox.fromSize(
|
||||
size: logoSize,
|
||||
child: svg("flowy_logo"),
|
||||
child: svgWidget("flowy_logo"),
|
||||
),
|
||||
const VSpace(30),
|
||||
Text(
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
import 'package:app_flowy/workspace/infrastructure/repos/app_repo.dart';
|
||||
import 'package:flowy_log/flowy_log.dart';
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:app_flowy/plugin/plugin.dart';
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/application/app/app_listener.dart';
|
||||
import 'package:app_flowy/workspace/application/app/app_service.dart';
|
||||
import 'package:app_flowy/workspace/presentation/home/menu/menu.dart';
|
||||
import 'package:expandable/expandable.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
@@ -10,64 +18,92 @@ import 'package:dartz/dartz.dart';
|
||||
part 'app_bloc.freezed.dart';
|
||||
|
||||
class AppBloc extends Bloc<AppEvent, AppState> {
|
||||
final AppRepository repo;
|
||||
final AppListener listener;
|
||||
AppBloc({required App app, required this.repo, required this.listener}) : super(AppState.initial(app)) {
|
||||
final App app;
|
||||
final AppService appService;
|
||||
final AppListener appListener;
|
||||
|
||||
AppBloc({required this.app, required this.appService, required this.appListener}) : super(AppState.initial(app)) {
|
||||
on<AppEvent>((event, emit) async {
|
||||
await event.map(initial: (e) async {
|
||||
listener.startListening(
|
||||
viewsChanged: _handleViewsChanged,
|
||||
appUpdated: (app) => add(AppEvent.appDidUpdate(app)),
|
||||
);
|
||||
await _fetchViews(emit);
|
||||
_startListening();
|
||||
await _loadViews(emit);
|
||||
}, createView: (CreateView value) async {
|
||||
final viewOrFailed = await repo.createView(name: value.name, desc: value.desc, viewType: value.viewType);
|
||||
viewOrFailed.fold(
|
||||
(view) => emit(state.copyWith(
|
||||
latestCreatedView: view,
|
||||
successOrFailure: left(unit),
|
||||
)),
|
||||
(error) {
|
||||
Log.error(error);
|
||||
emit(state.copyWith(successOrFailure: right(error)));
|
||||
},
|
||||
);
|
||||
}, didReceiveViews: (e) async {
|
||||
await handleDidReceiveViews(e.views, emit);
|
||||
await _createView(value, emit);
|
||||
}, didReceiveViewUpdated: (e) async {
|
||||
await _didReceiveViewUpdated(e.views, emit);
|
||||
}, delete: (e) async {
|
||||
final result = await repo.delete();
|
||||
result.fold(
|
||||
(unit) => emit(state.copyWith(successOrFailure: left(unit))),
|
||||
(error) => emit(state.copyWith(successOrFailure: right(error))),
|
||||
);
|
||||
await _deleteView(emit);
|
||||
}, rename: (e) async {
|
||||
final result = await repo.updateApp(name: e.newName);
|
||||
result.fold(
|
||||
(l) => emit(state.copyWith(successOrFailure: left(unit))),
|
||||
(error) => emit(state.copyWith(successOrFailure: right(error))),
|
||||
);
|
||||
await _renameView(e, emit);
|
||||
}, appDidUpdate: (e) async {
|
||||
emit(state.copyWith(app: e.app));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await listener.close();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
void _handleViewsChanged(Either<List<View>, FlowyError> result) {
|
||||
result.fold(
|
||||
(views) => add(AppEvent.didReceiveViews(views)),
|
||||
(error) {
|
||||
Log.error(error);
|
||||
void _startListening() {
|
||||
appListener.start(
|
||||
onViewsChanged: (result) {
|
||||
result.fold(
|
||||
(views) {
|
||||
if (!isClosed) {
|
||||
add(AppEvent.didReceiveViewUpdated(views));
|
||||
}
|
||||
},
|
||||
(error) => Log.error(error),
|
||||
);
|
||||
},
|
||||
onAppUpdated: (app) {
|
||||
if (!isClosed) {
|
||||
add(AppEvent.appDidUpdate(app));
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> handleDidReceiveViews(List<View> views, Emitter<AppState> emit) async {
|
||||
Future<void> _renameView(Rename e, Emitter<AppState> emit) async {
|
||||
final result = await appService.updateApp(appId: app.id, name: e.newName);
|
||||
result.fold(
|
||||
(l) => emit(state.copyWith(successOrFailure: left(unit))),
|
||||
(error) => emit(state.copyWith(successOrFailure: right(error))),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _deleteView(Emitter<AppState> emit) async {
|
||||
final result = await appService.delete(appId: app.id);
|
||||
result.fold(
|
||||
(unit) => emit(state.copyWith(successOrFailure: left(unit))),
|
||||
(error) => emit(state.copyWith(successOrFailure: right(error))),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _createView(CreateView value, Emitter<AppState> emit) async {
|
||||
final viewOrFailed = await appService.createView(
|
||||
appId: app.id,
|
||||
name: value.name,
|
||||
desc: value.desc,
|
||||
dataType: value.dataType,
|
||||
pluginType: value.pluginType,
|
||||
);
|
||||
viewOrFailed.fold(
|
||||
(view) => emit(state.copyWith(
|
||||
latestCreatedView: view,
|
||||
successOrFailure: left(unit),
|
||||
)),
|
||||
(error) {
|
||||
Log.error(error);
|
||||
emit(state.copyWith(successOrFailure: right(error)));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await appListener.stop();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
Future<void> _didReceiveViewUpdated(List<View> views, Emitter<AppState> emit) async {
|
||||
final latestCreatedView = state.latestCreatedView;
|
||||
AppState newState = state.copyWith(views: views);
|
||||
if (latestCreatedView != null) {
|
||||
@@ -80,10 +116,10 @@ class AppBloc extends Bloc<AppEvent, AppState> {
|
||||
emit(newState);
|
||||
}
|
||||
|
||||
Future<void> _fetchViews(Emitter<AppState> emit) async {
|
||||
final viewsOrFailed = await repo.getViews();
|
||||
Future<void> _loadViews(Emitter<AppState> emit) async {
|
||||
final viewsOrFailed = await appService.getViews(appId: app.id);
|
||||
viewsOrFailed.fold(
|
||||
(apps) => emit(state.copyWith(views: apps)),
|
||||
(views) => emit(state.copyWith(views: views)),
|
||||
(error) {
|
||||
Log.error(error);
|
||||
emit(state.copyWith(successOrFailure: right(error)));
|
||||
@@ -95,10 +131,15 @@ class AppBloc extends Bloc<AppEvent, AppState> {
|
||||
@freezed
|
||||
class AppEvent with _$AppEvent {
|
||||
const factory AppEvent.initial() = Initial;
|
||||
const factory AppEvent.createView(String name, String desc, ViewType viewType) = CreateView;
|
||||
const factory AppEvent.createView(
|
||||
String name,
|
||||
String desc,
|
||||
PluginDataType dataType,
|
||||
PluginType pluginType,
|
||||
) = CreateView;
|
||||
const factory AppEvent.delete() = Delete;
|
||||
const factory AppEvent.rename(String newName) = Rename;
|
||||
const factory AppEvent.didReceiveViews(List<View> views) = ReceiveViews;
|
||||
const factory AppEvent.didReceiveViewUpdated(List<View> views) = ReceiveViews;
|
||||
const factory AppEvent.appDidUpdate(App app) = AppDidUpdate;
|
||||
}
|
||||
|
||||
@@ -106,17 +147,102 @@ class AppEvent with _$AppEvent {
|
||||
class AppState with _$AppState {
|
||||
const factory AppState({
|
||||
required App app,
|
||||
required bool isLoading,
|
||||
required List<View>? views,
|
||||
required List<View> views,
|
||||
View? latestCreatedView,
|
||||
required Either<Unit, FlowyError> successOrFailure,
|
||||
}) = _AppState;
|
||||
|
||||
factory AppState.initial(App app) => AppState(
|
||||
app: app,
|
||||
isLoading: false,
|
||||
views: null,
|
||||
latestCreatedView: null,
|
||||
views: [],
|
||||
successOrFailure: left(unit),
|
||||
);
|
||||
}
|
||||
|
||||
class AppViewDataContext extends ChangeNotifier {
|
||||
final String appId;
|
||||
final ValueNotifier<List<View>> _viewsNotifier = ValueNotifier([]);
|
||||
final ValueNotifier<View?> _selectedViewNotifier = ValueNotifier(null);
|
||||
VoidCallback? _menuSharedStateListener;
|
||||
ExpandableController expandController = ExpandableController(initialExpanded: false);
|
||||
|
||||
AppViewDataContext({required this.appId}) {
|
||||
_setLatestView(getIt<MenuSharedState>().latestOpenView);
|
||||
_menuSharedStateListener = getIt<MenuSharedState>().addLatestViewListener((view) {
|
||||
_setLatestView(view);
|
||||
});
|
||||
}
|
||||
|
||||
VoidCallback addSelectedViewChangeListener(void Function(View?) callback) {
|
||||
listener() {
|
||||
callback(_selectedViewNotifier.value);
|
||||
}
|
||||
|
||||
_selectedViewNotifier.addListener(listener);
|
||||
return listener;
|
||||
}
|
||||
|
||||
void removeSelectedViewListener(VoidCallback listener) {
|
||||
_selectedViewNotifier.removeListener(listener);
|
||||
}
|
||||
|
||||
void _setLatestView(View? view) {
|
||||
view?.freeze();
|
||||
|
||||
if (_selectedViewNotifier.value != view) {
|
||||
_selectedViewNotifier.value = view;
|
||||
_expandIfNeed();
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
View? get selectedView => _selectedViewNotifier.value;
|
||||
|
||||
set views(List<View> views) {
|
||||
if (_viewsNotifier.value != views) {
|
||||
_viewsNotifier.value = views;
|
||||
_expandIfNeed();
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
UnmodifiableListView<View> get views => UnmodifiableListView(_viewsNotifier.value);
|
||||
|
||||
VoidCallback addViewsChangeListener(void Function(UnmodifiableListView<View>) callback) {
|
||||
listener() {
|
||||
callback(views);
|
||||
}
|
||||
|
||||
_viewsNotifier.addListener(listener);
|
||||
return listener;
|
||||
}
|
||||
|
||||
void removeViewsListener(VoidCallback listener) {
|
||||
_viewsNotifier.removeListener(listener);
|
||||
}
|
||||
|
||||
void _expandIfNeed() {
|
||||
if (_selectedViewNotifier.value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_viewsNotifier.value.contains(_selectedViewNotifier.value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (expandController.expanded == false) {
|
||||
// Workaround: Delay 150 milliseconds to make the smooth animation while expanding
|
||||
Future.delayed(const Duration(milliseconds: 150), () {
|
||||
expandController.expanded = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
if (_menuSharedStateListener != null) {
|
||||
getIt<MenuSharedState>().removeLatestViewListener(_menuSharedStateListener!);
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
@@ -1,67 +1,14 @@
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_log/flowy_log.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:app_flowy/core/notification_helper.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/dart-notify/subject.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
|
||||
import 'package:flowy_sdk/rust_stream.dart';
|
||||
import 'helper.dart';
|
||||
|
||||
class AppRepository {
|
||||
String appId;
|
||||
AppRepository({
|
||||
required this.appId,
|
||||
});
|
||||
|
||||
Future<Either<App, FlowyError>> getAppDesc() {
|
||||
final request = QueryAppRequest.create()..appIds.add(appId);
|
||||
|
||||
return FolderEventReadApp(request).send();
|
||||
}
|
||||
|
||||
Future<Either<View, FlowyError>> createView({
|
||||
required String name,
|
||||
required String desc,
|
||||
required ViewType viewType,
|
||||
}) {
|
||||
final request = CreateViewRequest.create()
|
||||
..belongToId = appId
|
||||
..name = name
|
||||
..desc = desc
|
||||
..viewType = viewType;
|
||||
|
||||
return FolderEventCreateView(request).send();
|
||||
}
|
||||
|
||||
Future<Either<List<View>, FlowyError>> getViews() {
|
||||
final request = QueryAppRequest.create()..appIds.add(appId);
|
||||
|
||||
return FolderEventReadApp(request).send().then((result) {
|
||||
return result.fold(
|
||||
(app) => left(app.belongings.items),
|
||||
(error) => right(error),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Future<Either<Unit, FlowyError>> delete() {
|
||||
final request = QueryAppRequest.create()..appIds.add(appId);
|
||||
return FolderEventDeleteApp(request).send();
|
||||
}
|
||||
|
||||
Future<Either<Unit, FlowyError>> updateApp({String? name}) {
|
||||
UpdateAppRequest request = UpdateAppRequest.create()..appId = appId;
|
||||
|
||||
if (name != null) {
|
||||
request.name = name;
|
||||
}
|
||||
return FolderEventUpdateApp(request).send();
|
||||
}
|
||||
}
|
||||
|
||||
typedef AppDidUpdateCallback = void Function(App app);
|
||||
typedef ViewsDidChangeCallback = void Function(Either<List<View>, FlowyError> viewsOrFailed);
|
||||
@@ -70,18 +17,18 @@ class AppListener {
|
||||
StreamSubscription<SubscribeObject>? _subscription;
|
||||
ViewsDidChangeCallback? _viewsChanged;
|
||||
AppDidUpdateCallback? _updated;
|
||||
late FolderNotificationParser _parser;
|
||||
FolderNotificationParser? _parser;
|
||||
String appId;
|
||||
|
||||
AppListener({
|
||||
required this.appId,
|
||||
});
|
||||
|
||||
void startListening({ViewsDidChangeCallback? viewsChanged, AppDidUpdateCallback? appUpdated}) {
|
||||
_viewsChanged = viewsChanged;
|
||||
_updated = appUpdated;
|
||||
void start({ViewsDidChangeCallback? onViewsChanged, AppDidUpdateCallback? onAppUpdated}) {
|
||||
_viewsChanged = onViewsChanged;
|
||||
_updated = onAppUpdated;
|
||||
_parser = FolderNotificationParser(id: appId, callback: _bservableCallback);
|
||||
_subscription = RustStreamReceiver.listen((observable) => _parser.parse(observable));
|
||||
_subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable));
|
||||
}
|
||||
|
||||
void _bservableCallback(FolderNotification ty, Either<Uint8List, FlowyError> result) {
|
||||
@@ -113,7 +60,8 @@ class AppListener {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> close() async {
|
||||
Future<void> stop() async {
|
||||
_parser = null;
|
||||
await _subscription?.cancel();
|
||||
_viewsChanged = null;
|
||||
_updated = null;
|
||||
@@ -0,0 +1,78 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
|
||||
|
||||
import 'package:app_flowy/plugin/plugin.dart';
|
||||
|
||||
class AppService {
|
||||
final String appId;
|
||||
AppService({
|
||||
required this.appId,
|
||||
});
|
||||
|
||||
Future<Either<App, FlowyError>> getAppDesc({required String appId}) {
|
||||
final payload = AppId.create()..value = appId;
|
||||
|
||||
return FolderEventReadApp(payload).send();
|
||||
}
|
||||
|
||||
Future<Either<View, FlowyError>> createView({
|
||||
required String appId,
|
||||
required String name,
|
||||
required String desc,
|
||||
required PluginDataType dataType,
|
||||
required PluginType pluginType,
|
||||
}) {
|
||||
final payload = CreateViewPayload.create()
|
||||
..belongToId = appId
|
||||
..name = name
|
||||
..desc = desc
|
||||
..dataType = dataType
|
||||
..pluginType = pluginType;
|
||||
|
||||
return FolderEventCreateView(payload).send();
|
||||
}
|
||||
|
||||
Future<Either<List<View>, FlowyError>> getViews({required String appId}) {
|
||||
final payload = AppId.create()..value = appId;
|
||||
|
||||
return FolderEventReadApp(payload).send().then((result) {
|
||||
return result.fold(
|
||||
(app) => left(app.belongings.items),
|
||||
(error) => right(error),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Future<Either<Unit, FlowyError>> delete({required String appId}) {
|
||||
final request = AppId.create()..value = appId;
|
||||
return FolderEventDeleteApp(request).send();
|
||||
}
|
||||
|
||||
Future<Either<Unit, FlowyError>> updateApp({required String appId, String? name}) {
|
||||
UpdateAppPayload payload = UpdateAppPayload.create()..appId = appId;
|
||||
|
||||
if (name != null) {
|
||||
payload.name = name;
|
||||
}
|
||||
return FolderEventUpdateApp(payload).send();
|
||||
}
|
||||
|
||||
Future<Either<Unit, FlowyError>> moveView({
|
||||
required String viewId,
|
||||
required int fromIndex,
|
||||
required int toIndex,
|
||||
}) {
|
||||
final payload = MoveFolderItemPayload.create()
|
||||
..itemId = viewId
|
||||
..from = fromIndex
|
||||
..to = toIndex
|
||||
..ty = MoveFolderItemType.MoveView;
|
||||
|
||||
return FolderEventMoveFolderItem(payload).send();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export 'app_bloc.dart';
|
||||
export 'app_listener.dart';
|
||||
export 'app_service.dart';
|
||||