Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
595f1f6ef8 | ||
|
|
c8e9adb81d | ||
|
|
6d3a7545a6 | ||
|
|
6739af2be1 | ||
|
|
c41a7aaacf | ||
|
|
d200c409d6 | ||
|
|
cd28dee7bd | ||
|
|
7e82a08b54 | ||
|
|
f0bd50b246 | ||
|
|
e571eb9881 | ||
|
|
c4f4bcf457 | ||
|
|
9500abb363 | ||
|
|
690a3746fa | ||
|
|
cd82c13753 | ||
|
|
032a648204 | ||
|
|
f64ee912d0 | ||
|
|
307556b7dd | ||
|
|
dd8b9dd43e | ||
|
|
6e41359fc5 | ||
|
|
b1cc4e485b | ||
|
|
239bf2fa70 | ||
|
|
a6baabbafc | ||
|
|
a954b5ffd8 | ||
|
|
36b88c602c | ||
|
|
190fae196f | ||
|
|
347698f68f | ||
|
|
db2e23172a | ||
|
|
dcb070909c | ||
|
|
332a677d20 | ||
|
|
75d394fb6e | ||
|
|
875b9d6cfc | ||
|
|
e9326d49c0 | ||
|
|
4ee6e297c6 | ||
|
|
c4ebccafd4 | ||
|
|
94bdefbf01 | ||
|
|
ba482a30a3 | ||
|
|
76416cfdba | ||
|
|
2557e4f3cc | ||
|
|
79c912219d | ||
|
|
89370b4a55 | ||
|
|
ecbc2601c4 | ||
|
|
f3753435e6 | ||
|
|
1eeb812a1c | ||
|
|
6dba118413 | ||
|
|
ee7fc5d77d | ||
|
|
e7533c149f | ||
|
|
bdec917a35 | ||
|
|
76a3daecaf | ||
|
|
ed1952d6a9 | ||
|
|
5a87229fe9 | ||
|
|
eac878d563 | ||
|
|
de08c01c4c | ||
|
|
7937fd1f3a | ||
|
|
eef5c2bf66 | ||
|
|
9c769cd7e5 | ||
|
|
eac58dc212 | ||
|
|
d3241cdecb | ||
|
|
857f645131 | ||
|
|
2521611d6a | ||
|
|
5facb61e23 | ||
|
|
2f6a4f8c7b | ||
|
|
84b8b92582 | ||
|
|
827d7c381e | ||
|
|
b0bf99da34 | ||
|
|
ca50e56474 | ||
|
|
36cf653d64 | ||
|
|
8ccd1ec72c | ||
|
|
7ba3020ab3 | ||
|
|
50694bb589 | ||
|
|
206ccb2c43 | ||
|
|
d2ccec79e4 | ||
|
|
69469e9989 | ||
|
|
c821b8c4fe | ||
|
|
93786bad44 | ||
|
|
f5bfcdcb98 | ||
|
|
d57b61b213 | ||
|
|
43a3a1e4b2 | ||
|
|
65f3296508 | ||
|
|
5cede74c89 | ||
|
|
54fcc4ac5b | ||
|
|
2ca911950c | ||
|
|
462b67def9 | ||
|
|
30a28b12d1 | ||
|
|
0b3c904984 | ||
|
|
1e16168a3d | ||
|
|
f5db384fc2 | ||
|
|
ce58737ec5 | ||
|
|
ca7b186325 | ||
|
|
d05b633b9b | ||
|
|
1cde5a0df6 | ||
|
|
df8409178b | ||
|
|
121ed5a06e | ||
|
|
29e80a0f32 | ||
|
|
a49b009980 | ||
|
|
9b55f5bc7f | ||
|
|
0371a28a42 | ||
|
|
ce51491cf6 | ||
|
|
c033d56978 | ||
|
|
a4a21c7e94 | ||
|
|
851296fa0e | ||
|
|
c3b183504f | ||
|
|
363bb3e45e | ||
|
|
acc93a603d | ||
|
|
8045042e78 | ||
|
|
1401ba5960 | ||
|
|
0730a0caf4 | ||
|
|
13260e1db8 | ||
|
|
4fa08fda02 | ||
|
|
2042394501 | ||
|
|
bbeae74ebd | ||
|
|
3aad1c5bcd | ||
|
|
f760e3d12a | ||
|
|
890285bb7b | ||
|
|
366e28752c | ||
|
|
6ecc3c9076 | ||
|
|
f5a9f2bf4d | ||
|
|
d68c847d59 | ||
|
|
9a1ea138fc | ||
|
|
b466b425a5 | ||
|
|
15aefaa956 | ||
|
|
e7bdce0997 | ||
|
|
44e48712a6 | ||
|
|
7d512578b2 | ||
|
|
0783f94cd6 | ||
|
|
eef34caf27 | ||
|
|
5ef9d55dca | ||
|
|
781fbf1b30 | ||
|
|
60ba775bed | ||
|
|
d862455342 | ||
|
|
d26606d3d3 | ||
|
|
6cece56ca7 | ||
|
|
2b096e967d | ||
|
|
7884fd1913 | ||
|
|
3f9b598493 | ||
|
|
d5b9063f78 | ||
|
|
b80b222527 | ||
|
|
c175947818 | ||
|
|
b7b8713cd9 | ||
|
|
81e09ae72e | ||
|
|
4e6643eca8 | ||
|
|
7586930ef0 | ||
|
|
e9a4efb67d | ||
|
|
eff06a1f74 | ||
|
|
775955df5c | ||
|
|
8cf6ab32f0 | ||
|
|
177cca60c4 | ||
|
|
649545cdf3 | ||
|
|
2a421034d9 | ||
|
|
ef49cb6577 | ||
|
|
6338ca1417 | ||
|
|
acb3c795d0 | ||
|
|
4405b597cd | ||
|
|
a7ce21e941 | ||
|
|
05bdd052ab | ||
|
|
d86431dfbc | ||
|
|
4837d7f7fe | ||
|
|
d765806337 | ||
|
|
fe5ce75ea8 | ||
|
|
99b2b2712b | ||
|
|
96af012471 | ||
|
|
7ad05feb5b | ||
|
|
69d3181a64 | ||
|
|
109ebaf989 | ||
|
|
1a13de2ee9 | ||
|
|
48d6967d3b | ||
|
|
7d55153475 | ||
|
|
d25830aece | ||
|
|
04eea26a55 | ||
|
|
25e94da7e7 | ||
|
|
2d7a373d77 | ||
|
|
1491fbfb0d | ||
|
|
0d776a9294 | ||
|
|
d4cef2e866 | ||
|
|
a070ed2441 | ||
|
|
5fa441cbf5 | ||
|
|
4ae679128f | ||
|
|
4d71b42a3d | ||
|
|
ff3ff9f888 | ||
|
|
147080ad27 | ||
|
|
bb4b987681 | ||
|
|
415f121720 | ||
|
|
9824d5980a | ||
|
|
5ff6405f7f | ||
|
|
a4e0c5754f | ||
|
|
5f94ba129e | ||
|
|
af07b53484 | ||
|
|
b43b522d97 | ||
|
|
0683483fd4 | ||
|
|
afab3d5374 | ||
|
|
066bba95f5 | ||
|
|
d004c94a2f | ||
|
|
c0ae803280 | ||
|
|
d7a67c0efb | ||
|
|
b307dd30d8 | ||
|
|
068245eec9 | ||
|
|
6b4d4fef15 | ||
|
|
64aa2ba7e4 | ||
|
|
8665a25b39 | ||
|
|
551e012147 | ||
|
|
7da759c662 | ||
|
|
8036d070ad | ||
|
|
a5ed145aa3 | ||
|
|
20b485bcfe | ||
|
|
38e3947b2d | ||
|
|
94f9349aba | ||
|
|
a9ea8fd159 | ||
|
|
1e6762b424 | ||
|
|
7c54b6d599 | ||
|
|
3e17613f54 | ||
|
|
9d61ca0278 | ||
|
|
3595de5e12 | ||
|
|
32ca864bf7 | ||
|
|
bfa9233bd4 | ||
|
|
c659cf4ff2 | ||
|
|
cac3acd553 | ||
|
|
771dd9979f | ||
|
|
929508df16 | ||
|
|
79b1515c3a | ||
|
|
7fb1b4f43f | ||
|
|
b3dd5fb8bd | ||
|
|
29a6eab1ce | ||
|
|
c475a5d960 | ||
|
|
414bb26e56 | ||
|
|
1fad713477 | ||
|
|
e18e031710 | ||
|
|
bddaac05ae | ||
|
|
3e5fae002b | ||
|
|
66835a5409 | ||
|
|
8afbf28430 | ||
|
|
0427402ba7 | ||
|
|
6973d66263 | ||
|
|
5fea801a88 | ||
|
|
8b81889bcf | ||
|
|
800094587b | ||
|
|
de75e028df | ||
|
|
9b3c1921e8 | ||
|
|
412f34c72a | ||
|
|
a7364e1f4a | ||
|
|
16467e9c13 | ||
|
|
b00d29d0cd | ||
|
|
acc951c5eb | ||
|
|
b9ecc7ceb6 | ||
|
|
6f83f41c2d | ||
|
|
8179419f8b | ||
|
|
4a1a143a66 | ||
|
|
21bbf87089 | ||
|
|
19d9e7717c | ||
|
|
d190850f03 | ||
|
|
68de83c611 | ||
|
|
729b8571b5 | ||
|
|
31e9a0b4ea | ||
|
|
6a9866b9d2 | ||
|
|
1c500fbfc5 | ||
|
|
4992f9c281 | ||
|
|
75c26c807c | ||
|
|
e788c71602 | ||
|
|
7de2131431 | ||
|
|
47f3702ca9 | ||
|
|
3708a5b86a | ||
|
|
a63a7ea611 | ||
|
|
7867f0366e | ||
|
|
251c6d22b2 | ||
|
|
7cee8e392f | ||
|
|
765103dd22 | ||
|
|
50e612511d | ||
|
|
7eb20b232a | ||
|
|
3c7e636b65 | ||
|
|
889a313cc2 | ||
|
|
9586ea0e6f | ||
|
|
42e7317cd4 | ||
|
|
17651bf64c | ||
|
|
73f1c211c2 | ||
|
|
afc6473582 | ||
|
|
663f9d3423 | ||
|
|
5d4142d5b6 | ||
|
|
fe23183aef | ||
|
|
8116ea1dba | ||
|
|
3e6529aeb8 | ||
|
|
c4fc60612f | ||
|
|
4d82bb5322 | ||
|
|
2b684ae7bf | ||
|
|
eb54cf99d4 | ||
|
|
85af82acbe | ||
|
|
3434d447a7 | ||
|
|
1025b6d553 | ||
|
|
b35d6131d4 | ||
|
|
bc502c9c5b | ||
|
|
5f49c1748f | ||
|
|
73ea1a0685 | ||
|
|
a93d325e6a | ||
|
|
dc0af0f4c1 | ||
|
|
1ad85416d8 | ||
|
|
c34a7a92fb | ||
|
|
21d34d1fe0 | ||
|
|
3e088d48ac | ||
|
|
54dbcb7c5e | ||
|
|
59dff54edb | ||
|
|
d358e18f33 | ||
|
|
dd9b1fb78f | ||
|
|
e08a1a6974 | ||
|
|
7f4e7e6aa0 | ||
|
|
18bd91936c | ||
|
|
b9a25f449f | ||
|
|
993532a2f0 | ||
|
|
8a735799c6 | ||
|
|
197da5f425 | ||
|
|
e28e5a0649 | ||
|
|
09b4e19c9d | ||
|
|
653c831473 | ||
|
|
a2f2cdebb7 | ||
|
|
59e0a1325e | ||
|
|
c0446d7a96 | ||
|
|
1fbee02731 | ||
|
|
102fdbce5c | ||
|
|
71c6beb882 | ||
|
|
ce83042317 | ||
|
|
03598d3f22 | ||
|
|
c2eb2014a3 | ||
|
|
9416ba1bfc | ||
|
|
8c3984d21a | ||
|
|
1883dd6d7c | ||
|
|
a354f9fe52 | ||
|
|
41e2c74b5e | ||
|
|
74d9d427bd | ||
|
|
aa27c4e6d4 | ||
|
|
f40ae9ff25 | ||
|
|
e66087861b | ||
|
|
147637fcf5 | ||
|
|
48582cb718 | ||
|
|
ad21a61ffb | ||
|
|
d34eec1d99 | ||
|
|
95aeac201f | ||
|
|
cceee80799 | ||
|
|
71f80be8f7 | ||
|
|
16a4babdca | ||
|
|
85c0622245 | ||
|
|
e3410ec568 | ||
|
|
c0b0f12b0d | ||
|
|
70a2b7d9ab | ||
|
|
a84c47dc33 | ||
|
|
56c5d69b0f | ||
|
|
6c3d7d2079 | ||
|
|
25a98cda81 | ||
|
|
cd6e133c86 | ||
|
|
b16a102f85 | ||
|
|
d51c7f382f | ||
|
|
a57ca5c0cb | ||
|
|
1e9137fcfe | ||
|
|
8e5b6b6e27 | ||
|
|
7e101b8bf1 | ||
|
|
bf0cfa798c | ||
|
|
1793a28cbc | ||
|
|
e565d0ee32 | ||
|
|
f60462a853 | ||
|
|
966547faa0 | ||
|
|
3647af44c9 | ||
|
|
25b4a647b0 | ||
|
|
c6e3c1fd7c | ||
|
|
4fd35d0de4 | ||
|
|
7406c5e6a5 | ||
|
|
aa70885b21 | ||
|
|
8699c9c125 | ||
|
|
bc758e0b06 | ||
|
|
e38980ccc3 | ||
|
|
8dd180046f | ||
|
|
0cd2726752 | ||
|
|
11daa15b89 | ||
|
|
8436bc6144 | ||
|
|
59851f46b7 | ||
|
|
62f1d6eb82 | ||
|
|
ec80f72c8f | ||
|
|
b2c80981cc | ||
|
|
8fa425a76c | ||
|
|
ebe112581d | ||
|
|
bc8f35d7db | ||
|
|
058eeec932 | ||
|
|
8e10cba8e5 | ||
|
|
7a24f6b6f0 | ||
|
|
4f40945458 | ||
|
|
e59870e421 | ||
|
|
cf521fe20b | ||
|
|
f0d47ee50c | ||
|
|
2a5d393c9f | ||
|
|
98e0b832ec | ||
|
|
77e7cbe9ec | ||
|
|
acd53eb640 | ||
|
|
ffdf5d24a0 | ||
|
|
b247a49417 | ||
|
|
dace02d34d | ||
|
|
41d4351176 | ||
|
|
d4bc575c03 | ||
|
|
a59561aee3 | ||
|
|
92523321f1 | ||
|
|
537c9d0865 | ||
|
|
b4051c7e9f | ||
|
|
9e61133886 | ||
|
|
36f47f3636 | ||
|
|
40dcd13394 | ||
|
|
eb20c7c117 | ||
|
|
e9852a3934 | ||
|
|
78d8ec9a3e | ||
|
|
4220309cf8 | ||
|
|
812af0979e | ||
|
|
cca5005541 | ||
|
|
9306d4a4ee | ||
|
|
3ab1ff5e73 | ||
|
|
05fa306782 | ||
|
|
d054439df4 | ||
|
|
15aaacc4b7 | ||
|
|
ef9de52cbc | ||
|
|
8d9d0e9358 | ||
|
|
7f44b181bd | ||
|
|
01c3fec5aa | ||
|
|
94a3a59001 | ||
|
|
4a433a3176 | ||
|
|
f7749bdccc | ||
|
|
c864e836ee | ||
|
|
0738b5f87d | ||
|
|
6198c3907f | ||
|
|
891d794900 | ||
|
|
890f52a00a | ||
|
|
d007f98af6 | ||
|
|
15e9d65798 | ||
|
|
0626f0deb7 | ||
|
|
007c649c31 | ||
|
|
34ea508f5b | ||
|
|
f70aef68be | ||
|
|
61a31c90ee | ||
|
|
c7e3ed805a | ||
|
|
d36a846425 | ||
|
|
a02ec98e9c | ||
|
|
32c06cf1bf | ||
|
|
cf1096b516 | ||
|
|
938953d7b3 | ||
|
|
949dab9afe | ||
|
|
0996f5fd24 | ||
|
|
6e887f1f12 | ||
|
|
ab9338eb89 | ||
|
|
fd4088aed0 | ||
|
|
375ff5ed6d | ||
|
|
847290d9a4 | ||
|
|
56687581f2 | ||
|
|
3be39f5e7b | ||
|
|
1997231adf | ||
|
|
89face4f02 | ||
|
|
37ddce3a29 | ||
|
|
593df96b10 | ||
|
|
1b966171c4 | ||
|
|
047f1a0b39 | ||
|
|
f2f3506b29 | ||
|
|
0ccced4b54 | ||
|
|
f762a564b5 | ||
|
|
57b78ee3c6 | ||
|
|
5dfc470873 | ||
|
|
d5f8ce5435 | ||
|
|
3c65a96b04 | ||
|
|
6ba7fc0317 | ||
|
|
37a5054ebd | ||
|
|
048434024b | ||
|
|
2c757e9b6c | ||
|
|
9c59e1487e | ||
|
|
4b9b723521 | ||
|
|
a389836897 | ||
|
|
eec7723ce0 | ||
|
|
2f938a331f | ||
|
|
847d7cb35a | ||
|
|
094f8fc307 | ||
|
|
e3f11ea9c0 | ||
|
|
124d435f09 | ||
|
|
b700f95c7f | ||
|
|
daf9b48c73 | ||
|
|
0ea5b3c483 | ||
|
|
f3148640eb | ||
|
|
1c84ee1d53 | ||
|
|
cecd4f48ab | ||
|
|
1e001640aa | ||
|
|
3426e5b53e | ||
|
|
936b49a63f | ||
|
|
f6f80b48c9 | ||
|
|
759cb27a43 | ||
|
|
26a2bffcd1 | ||
|
|
fe55452c79 | ||
|
|
16adacac38 | ||
|
|
d86531ac92 | ||
|
|
9231455f0d | ||
|
|
0c6a1d4ae7 | ||
|
|
524efc2620 | ||
|
|
50a4f03931 | ||
|
|
a4681a4042 | ||
|
|
1ca130d7de | ||
|
|
ef6f9a3175 | ||
|
|
aa25aa4474 | ||
|
|
c7af04b317 | ||
|
|
9565173baf | ||
|
|
5f4e3ecc76 | ||
|
|
043c68a333 | ||
|
|
f639d51c11 | ||
|
|
71071b60b2 | ||
|
|
608255fa0f | ||
|
|
f8b0a26acc | ||
|
|
133dab934b | ||
|
|
a81670c447 | ||
|
|
35f84e42cc | ||
|
|
2f6df6a17d | ||
|
|
8bcc6384f2 | ||
|
|
a0fc4b86b0 | ||
|
|
790580eea4 | ||
|
|
3db9024a2d | ||
|
|
a821740469 | ||
|
|
af0ae2e375 | ||
|
|
7d6fa0b159 | ||
|
|
b73a34ed94 | ||
|
|
f3aaff77b9 | ||
|
|
9b7ff375b2 | ||
|
|
18498c0479 | ||
|
|
c652c32575 | ||
|
|
df8642d446 | ||
|
|
abb6eff23d | ||
|
|
3b4f8e53a2 | ||
|
|
4847b8b114 | ||
|
|
e8f124b97c | ||
|
|
f73d59fb57 | ||
|
|
897d7980f6 | ||
|
|
b88aed887a | ||
|
|
4e863bc87f | ||
|
|
507554a596 | ||
|
|
0806436c19 | ||
|
|
1205f0ebf7 | ||
|
|
26e56194ea | ||
|
|
4e67282f2b | ||
|
|
41ec2d992e | ||
|
|
f0e4f3db61 | ||
|
|
6634a0ecb3 | ||
|
|
255f30590f | ||
|
|
1ba7224088 | ||
|
|
4d7c0a7c67 | ||
|
|
a0481e8020 | ||
|
|
affd253e21 | ||
|
|
773b09c2f7 | ||
|
|
ea37128359 | ||
|
|
e9f31ea0f8 | ||
|
|
72363921b0 | ||
|
|
7fa15615df | ||
|
|
ad596b3165 | ||
|
|
724fc895e1 | ||
|
|
77637ff461 | ||
|
|
12d6cbd46a | ||
|
|
bd30e31f6c | ||
|
|
30155924a9 | ||
|
|
a1647bee78 | ||
|
|
c5719be7ae | ||
|
|
de01bf70cd | ||
|
|
23a34af30f | ||
|
|
1cc78b87ab | ||
|
|
c1bba7e48b | ||
|
|
78c33a4dd2 | ||
|
|
649b0a135a | ||
|
|
103f56922f | ||
|
|
07cf7287d6 | ||
|
|
8a277b7380 | ||
|
|
7f7fd4958f | ||
|
|
de4f47b2a1 | ||
|
|
e226eaad45 | ||
|
|
a1f1559936 | ||
|
|
f994f50ef9 | ||
|
|
29431b3038 | ||
|
|
ee14d31194 | ||
|
|
00ee4be723 | ||
|
|
243f80b6d5 | ||
|
|
6fc8072459 | ||
|
|
27b1f00e17 | ||
|
|
2f8edf1fd1 | ||
|
|
9643315d5f | ||
|
|
a1e2d97388 | ||
|
|
9863000f4a | ||
|
|
d0a343ee36 | ||
|
|
7a6c829187 | ||
|
|
a47e065f30 | ||
|
|
fc0ded4990 | ||
|
|
9063b40e06 |
No files matched your search
@@ -44,7 +44,7 @@ test "" = "$(grep '^Signed-off-by: ' "$1" |
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
printError "Please fix your commit message to match AppFlowy coding standards"
|
||||
printError "https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/software-contributions/submitting-code/code-submission-guidelines#commit-message-guidelines"
|
||||
printError "https://docs.appflowy.io/docs/documentation/software-contributions/conventions/git-conventions"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -21,7 +21,7 @@ Before you mark this PR ready for review, run through this checklist!
|
||||
|
||||
#### PR Checklist
|
||||
|
||||
- [ ] My code adheres to the [AppFlowy Style Guide](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/software-contributions/submitting-code/style-guides)
|
||||
- [ ] My code adheres to [AppFlowy's Conventions](https://docs.appflowy.io/docs/documentation/software-contributions/conventions)
|
||||
- [ ] I've listed at least one issue that this PR fixes in the description above.
|
||||
- [ ] I've added a test(s) to validate changes in this PR, or this PR only contains semantic changes.
|
||||
- [ ] All existing tests are passing.
|
||||
@@ -0,0 +1,99 @@
|
||||
name: Build AppFlowy Release APK
|
||||
|
||||
on: workflow_dispatch
|
||||
|
||||
env:
|
||||
FLUTTER_VERSION: "3.18.0-0.2.pre"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
target: aarch64-linux-android
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
# the following step is required to avoid running out of space
|
||||
- name: Maximize build space
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
run: |
|
||||
sudo rm -rf /usr/share/dotnet
|
||||
sudo rm -rf /opt/ghc
|
||||
sudo rm -rf "/usr/local/share/boost"
|
||||
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
||||
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
target: ${{ matrix.target }}
|
||||
override: true
|
||||
profile: minimal
|
||||
|
||||
- name: Install flutter
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
- uses: nttld/setup-ndk@v1
|
||||
id: setup-ndk
|
||||
with:
|
||||
ndk-version: "r24"
|
||||
add-to-path: true
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: ${{ matrix.os }}
|
||||
workspaces: |
|
||||
frontend/rust-lib
|
||||
|
||||
- uses: davidB/rust-cargo-make@v1
|
||||
with:
|
||||
version: "0.36.6"
|
||||
|
||||
- name: Install prerequisites
|
||||
working-directory: frontend
|
||||
run: |
|
||||
rustup target install aarch64-linux-android
|
||||
rustup target install x86_64-linux-android
|
||||
cargo install --force duckscript_cli
|
||||
cargo install cargo-ndk
|
||||
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 libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev
|
||||
sudo apt-get install keybinder-3.0 libnotify-dev
|
||||
sudo apt-get install gcc-multilib
|
||||
elif [ "$RUNNER_OS" == "Windows" ]; then
|
||||
vcpkg integrate install
|
||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||
echo 'do nothing'
|
||||
fi
|
||||
cargo make appflowy-flutter-deps-tools
|
||||
shell: bash
|
||||
|
||||
- name: Build AppFlowy
|
||||
working-directory: frontend
|
||||
env:
|
||||
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
|
||||
run: |
|
||||
cargo make --profile production-android appflowy-android
|
||||
|
||||
- name: Upload APK
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: app-arm64-v8a-release.apk
|
||||
path: frontend/appflowy_flutter/build/app/outputs/flutter-apk/
|
||||
@@ -4,33 +4,390 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
- "develop"
|
||||
- "release/*"
|
||||
paths:
|
||||
- ".github/workflows/flutter_ci.yaml"
|
||||
- "frontend/**"
|
||||
- "!frontend/appflowy_tauri/**"
|
||||
- "frontend/rust-lib/**"
|
||||
- "frontend/appflowy_flutter/**"
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- "main"
|
||||
- "develop"
|
||||
- "release/*"
|
||||
paths:
|
||||
- ".github/workflows/flutter_ci.yaml"
|
||||
- "frontend/**"
|
||||
- "!frontend/appflowy_tauri/**"
|
||||
- "frontend/rust-lib/**"
|
||||
- "frontend/appflowy_flutter/**"
|
||||
|
||||
env:
|
||||
FLUTTER_VERSION: "3.10.1"
|
||||
RUST_TOOLCHAIN: "1.70"
|
||||
CARGO_TERM_COLOR: always
|
||||
FLUTTER_VERSION: "3.18.0-0.2.pre"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
CARGO_MAKE_VERSION: "0.36.6"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
prepare:
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
flutter_profile: development-linux-x86_64
|
||||
target: x86_64-unknown-linux-gnu
|
||||
- os: macos-latest
|
||||
flutter_profile: development-mac-x86_64
|
||||
target: x86_64-apple-darwin
|
||||
- os: windows-latest
|
||||
flutter_profile: development-windows-x86
|
||||
target: x86_64-pc-windows-msvc
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
# the following step is required to avoid running out of space
|
||||
- name: Maximize build space
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
run: |
|
||||
sudo rm -rf /usr/share/dotnet
|
||||
sudo rm -rf /opt/ghc
|
||||
sudo rm -rf "/usr/local/share/boost"
|
||||
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
||||
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
target: ${{ matrix.target }}
|
||||
override: true
|
||||
profile: minimal
|
||||
|
||||
- name: Install flutter
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: ${{ matrix.os }}
|
||||
workspaces: |
|
||||
frontend/rust-lib
|
||||
cache-all-crates: true
|
||||
|
||||
- uses: taiki-e/install-action@v2
|
||||
with:
|
||||
tool: cargo-make@${{ env.CARGO_MAKE_VERSION }}, duckscript_cli
|
||||
|
||||
- name: Install prerequisites
|
||||
working-directory: frontend
|
||||
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 libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev keybinder-3.0 libnotify-dev
|
||||
elif [ "$RUNNER_OS" == "Windows" ]; then
|
||||
vcpkg integrate install
|
||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||
echo 'do nothing'
|
||||
fi
|
||||
cargo make appflowy-flutter-deps-tools
|
||||
shell: bash
|
||||
|
||||
- name: Build AppFlowy
|
||||
working-directory: frontend
|
||||
run: cargo make --profile ${{ matrix.flutter_profile }} appflowy-core-dev
|
||||
|
||||
- name: Run code generation
|
||||
working-directory: frontend
|
||||
run: cargo make code_generation
|
||||
|
||||
- name: Flutter Analyzer
|
||||
working-directory: frontend/appflowy_flutter
|
||||
run: flutter analyze .
|
||||
|
||||
- name: Compress appflowy_flutter
|
||||
run: |
|
||||
tar -czf appflowy_flutter.tar.gz frontend/appflowy_flutter
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ github.run_id }}-${{ matrix.os }}
|
||||
path: appflowy_flutter.tar.gz
|
||||
|
||||
unit_test:
|
||||
needs: [prepare]
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
flutter_profile: development-linux-x86_64
|
||||
target: x86_64-unknown-linux-gnu
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
target: ${{ matrix.target }}
|
||||
override: true
|
||||
profile: minimal
|
||||
|
||||
- name: Install flutter
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: ${{ matrix.os }}
|
||||
workspaces: |
|
||||
frontend/rust-lib
|
||||
cache-all-crates: true
|
||||
|
||||
- uses: taiki-e/install-action@v2
|
||||
with:
|
||||
tool: cargo-make@${{ env.CARGO_MAKE_VERSION }}, duckscript_cli
|
||||
|
||||
- name: Install prerequisites
|
||||
working-directory: frontend
|
||||
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 libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev keybinder-3.0 libnotify-dev
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Enable Flutter Desktop
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||
flutter config --enable-linux-desktop
|
||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||
flutter config --enable-macos-desktop
|
||||
elif [ "$RUNNER_OS" == "Windows" ]; then
|
||||
git config --system core.longpaths true
|
||||
flutter config --enable-windows-desktop
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: ${{ github.run_id }}-${{ matrix.os }}
|
||||
|
||||
- name: Uncompress appflowy_flutter
|
||||
run: tar -xf appflowy_flutter.tar.gz
|
||||
|
||||
- name: Run flutter pub get
|
||||
working-directory: frontend
|
||||
run: cargo make pub_get
|
||||
|
||||
- name: Run Flutter unit tests
|
||||
working-directory: frontend
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "macOS" ]; then
|
||||
cargo make dart_unit_test
|
||||
elif [ "$RUNNER_OS" == "Linux" ]; then
|
||||
cargo make dart_unit_test_no_build
|
||||
elif [ "$RUNNER_OS" == "Windows" ]; then
|
||||
cargo make dart_unit_test_no_build
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
cloud_integration_test:
|
||||
needs: [ prepare ]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-latest ]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
flutter_profile: development-linux-x86_64
|
||||
target: x86_64-unknown-linux-gnu
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: Checkout appflowy cloud code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: AppFlowy-IO/AppFlowy-Cloud
|
||||
path: AppFlowy-Cloud
|
||||
depth: 1
|
||||
|
||||
- name: Prepare appflowy cloud env
|
||||
working-directory: AppFlowy-Cloud
|
||||
run: |
|
||||
# log level
|
||||
cp deploy.env .env
|
||||
sed -i 's|RUST_LOG=.*|RUST_LOG=trace|' .env
|
||||
sed -i 's/GOTRUE_EXTERNAL_GOOGLE_ENABLED=.*/GOTRUE_EXTERNAL_GOOGLE_ENABLED=true/' .env
|
||||
sed -i 's|API_EXTERNAL_URL=.*|API_EXTERNAL_URL=http://localhost|' .env
|
||||
|
||||
- name: Run Docker-Compose
|
||||
working-directory: AppFlowy-Cloud
|
||||
run: |
|
||||
docker compose down -v --remove-orphans
|
||||
docker pull appflowyinc/appflowy_cloud:latest
|
||||
docker compose up -d
|
||||
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install flutter
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
|
||||
- uses: taiki-e/install-action@v2
|
||||
with:
|
||||
tool: cargo-make@${{ env.CARGO_MAKE_VERSION }}
|
||||
|
||||
- name: Install prerequisites
|
||||
working-directory: frontend
|
||||
run: |
|
||||
sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub
|
||||
sudo 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 libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev keybinder-3.0 libnotify-dev
|
||||
shell: bash
|
||||
|
||||
- name: Enable Flutter Desktop
|
||||
run: |
|
||||
flutter config --enable-linux-desktop
|
||||
shell: bash
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: ${{ github.run_id }}-${{ matrix.os }}
|
||||
|
||||
- name: Uncompressed appflowy_flutter
|
||||
run: |
|
||||
tar -xf appflowy_flutter.tar.gz
|
||||
ls -al
|
||||
|
||||
- name: Run flutter pub get
|
||||
working-directory: frontend
|
||||
run: cargo make pub_get
|
||||
|
||||
- name: Run Flutter integration tests
|
||||
working-directory: frontend/appflowy_flutter
|
||||
run: |
|
||||
export DISPLAY=:99
|
||||
sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &
|
||||
sudo apt-get install network-manager
|
||||
flutter test integration_test/cloud/cloud_runner.dart -d Linux --coverage
|
||||
shell: bash
|
||||
|
||||
integration_test:
|
||||
needs: [prepare]
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
flutter_profile: development-linux-x86_64
|
||||
target: x86_64-unknown-linux-gnu
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
target: ${{ matrix.target }}
|
||||
override: true
|
||||
profile: minimal
|
||||
|
||||
- name: Install flutter
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
|
||||
- uses: taiki-e/install-action@v2
|
||||
with:
|
||||
tool: cargo-make@${{ env.CARGO_MAKE_VERSION }}
|
||||
|
||||
- name: Install prerequisites
|
||||
working-directory: frontend
|
||||
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 libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev keybinder-3.0 libnotify-dev
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Enable Flutter Desktop
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||
flutter config --enable-linux-desktop
|
||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||
flutter config --enable-macos-desktop
|
||||
elif [ "$RUNNER_OS" == "Windows" ]; then
|
||||
git config --system core.longpaths true
|
||||
flutter config --enable-windows-desktop
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: ${{ github.run_id }}-${{ matrix.os }}
|
||||
|
||||
- name: Uncompressed appflowy_flutter
|
||||
run: tar -xf appflowy_flutter.tar.gz
|
||||
|
||||
- name: Run flutter pub get
|
||||
working-directory: frontend
|
||||
run: cargo make pub_get
|
||||
|
||||
- name: Run Flutter integration tests
|
||||
working-directory: frontend/appflowy_flutter
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||
export DISPLAY=:99
|
||||
sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &
|
||||
sudo apt-get install network-manager
|
||||
flutter test integration_test/runner.dart -d Linux --coverage
|
||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||
flutter test integration_test/runner.dart -d macOS --coverage
|
||||
elif [ "$RUNNER_OS" == "Windows" ]; then
|
||||
flutter test integration_test/runner.dart -d Windows --coverage
|
||||
fi
|
||||
shell: bash
|
||||
build:
|
||||
needs: [prepare]
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -65,36 +422,22 @@ jobs:
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- uses: taiki-e/install-action@v2
|
||||
with:
|
||||
prefix-key: ${{ matrix.os }}
|
||||
workspaces: |
|
||||
frontend/rust-lib
|
||||
|
||||
- uses: davidB/rust-cargo-make@v1
|
||||
with:
|
||||
version: '0.36.6'
|
||||
tool: cargo-make@${{ env.CARGO_MAKE_VERSION }}
|
||||
|
||||
- name: Install prerequisites
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo install --force duckscript_cli
|
||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||
sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub
|
||||
sudo wget -qO /etc/apt/sources.list.d/dart_stable.list https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y dart curl build-essential libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev
|
||||
sudo apt-get install keybinder-3.0
|
||||
elif [ "$RUNNER_OS" == "Windows" ]; then
|
||||
vcpkg integrate install
|
||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||
echo 'do nothing'
|
||||
sudo apt-get install -y dart curl build-essential libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev keybinder-3.0 libnotify-dev
|
||||
fi
|
||||
cargo make appflowy-flutter-deps-tools
|
||||
shell: bash
|
||||
|
||||
- name: Enable Flutter Desktop
|
||||
@@ -109,32 +452,14 @@ jobs:
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Build AppFlowy
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo make --profile ${{ matrix.flutter_profile }} appflowy-dev
|
||||
|
||||
- name: Flutter Analyzer
|
||||
working-directory: frontend/appflowy_flutter
|
||||
run: |
|
||||
flutter analyze .
|
||||
|
||||
- name: Run Flutter unit tests
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo make dart_unit_test
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: Wandalen/wretry.action@v1.0.36
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
action: codecov/codecov-action@v3
|
||||
with: |
|
||||
name: appflowy
|
||||
flags: appflowy_flutter_unit_test
|
||||
fail_ci_if_error: true
|
||||
verbose: true
|
||||
os: ${{ matrix.os }}
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
attempt_limit: 20
|
||||
attempt_delay: 10000
|
||||
name: ${{ github.run_id }}-${{ matrix.os }}
|
||||
|
||||
- name: Uncompressed appflowy_flutter
|
||||
run: tar -xf appflowy_flutter.tar.gz
|
||||
|
||||
- name: Build flutter product
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo make --profile ${{ matrix.flutter_profile }} appflowy-make-product-dev
|
||||
@@ -1,141 +0,0 @@
|
||||
name: integration test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
- "release/*"
|
||||
paths:
|
||||
- ".github/workflows/integration_test.yml"
|
||||
- "frontend/**"
|
||||
- "!frontend/appflowy_tauri/**"
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- "main"
|
||||
- "release/*"
|
||||
paths:
|
||||
- ".github/workflows/integration_test.yml"
|
||||
- "frontend/**"
|
||||
- "!frontend/appflowy_tauri/**"
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
FLUTTER_VERSION: "3.10.1"
|
||||
RUST_TOOLCHAIN: "1.70"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
flutter_profile: development-linux-x86_64
|
||||
target: x86_64-unknown-linux-gnu
|
||||
- os: windows-latest
|
||||
flutter_profile: development-windows-x86
|
||||
target: x86_64-pc-windows-msvc
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
target: ${{ matrix.target }}
|
||||
override: true
|
||||
profile: minimal
|
||||
|
||||
- name: Install flutter
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: ${{ matrix.os }}
|
||||
workspaces: |
|
||||
frontend/rust-lib
|
||||
cache-all-crates: true
|
||||
|
||||
- uses: davidB/rust-cargo-make@v1
|
||||
with:
|
||||
version: '0.36.6'
|
||||
|
||||
- name: Install prerequisites
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo install --force duckscript_cli
|
||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||
sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub
|
||||
sudo wget -qO /etc/apt/sources.list.d/dart_stable.list https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y dart curl build-essential libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev
|
||||
sudo apt-get install keybinder-3.0
|
||||
elif [ "$RUNNER_OS" == "Windows" ]; then
|
||||
vcpkg integrate install
|
||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||
echo 'do nothing'
|
||||
fi
|
||||
cargo make appflowy-flutter-deps-tools
|
||||
shell: bash
|
||||
|
||||
- name: Enable Flutter Desktop
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||
flutter config --enable-linux-desktop
|
||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||
flutter config --enable-macos-desktop
|
||||
elif [ "$RUNNER_OS" == "Windows" ]; then
|
||||
git config --system core.longpaths true
|
||||
flutter config --enable-windows-desktop
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Build AppFlowy
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo make --profile ${{ matrix.flutter_profile }} appflowy-dev
|
||||
|
||||
- name: Run Flutter integration tests
|
||||
working-directory: frontend/appflowy_flutter
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||
export DISPLAY=:99
|
||||
sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &
|
||||
sudo apt-get install network-manager
|
||||
flutter test integration_test/runner.dart -d Linux --coverage
|
||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||
flutter test integration_test/runner.dart -d macOS --coverage
|
||||
elif [ "$RUNNER_OS" == "Windows" ]; then
|
||||
flutter test integration_test/runner.dart -d Windows --coverage
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: Wandalen/wretry.action@v1.0.36
|
||||
with:
|
||||
action: codecov/codecov-action@v3
|
||||
with: |
|
||||
name: appflowy
|
||||
flags: appflowy_flutter_integrateion_test
|
||||
fail_ci_if_error: true
|
||||
verbose: true
|
||||
os: ${{ matrix.os }}
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
attempt_limit: 20
|
||||
attempt_delay: 10000
|
||||
@@ -0,0 +1,117 @@
|
||||
name: Mobile-CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
paths:
|
||||
- ".github/workflows/mobile_ci.yaml"
|
||||
- "frontend/**"
|
||||
- "!frontend/appflowy_tauri/**"
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- "main"
|
||||
paths:
|
||||
- ".github/workflows/mobile_ci.yaml"
|
||||
- "frontend/**"
|
||||
- "!frontend/appflowy_tauri/**"
|
||||
|
||||
env:
|
||||
FLUTTER_VERSION: "3.18.0-0.2.pre"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
target: aarch64-linux-android
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
# the following step is required to avoid running out of space
|
||||
- name: Maximize build space
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
run: |
|
||||
sudo rm -rf /usr/share/dotnet
|
||||
sudo rm -rf /opt/ghc
|
||||
sudo rm -rf "/usr/local/share/boost"
|
||||
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
||||
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
target: ${{ matrix.target }}
|
||||
override: true
|
||||
profile: minimal
|
||||
|
||||
- name: Install flutter
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
- uses: nttld/setup-ndk@v1
|
||||
id: setup-ndk
|
||||
with:
|
||||
ndk-version: "r24"
|
||||
add-to-path: true
|
||||
|
||||
- uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
gradle-version: 7.6.3
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: ${{ matrix.os }}
|
||||
workspaces: |
|
||||
frontend/rust-lib
|
||||
|
||||
- uses: davidB/rust-cargo-make@v1
|
||||
with:
|
||||
version: "0.36.6"
|
||||
|
||||
- name: Install prerequisites
|
||||
working-directory: frontend
|
||||
run: |
|
||||
rustup target install aarch64-linux-android
|
||||
rustup target install x86_64-linux-android
|
||||
cargo install --force duckscript_cli
|
||||
cargo install cargo-ndk
|
||||
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 libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev
|
||||
sudo apt-get install keybinder-3.0 libnotify-dev
|
||||
sudo apt-get install gcc-multilib
|
||||
elif [ "$RUNNER_OS" == "Windows" ]; then
|
||||
vcpkg integrate install
|
||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||
echo 'do nothing'
|
||||
fi
|
||||
cargo make appflowy-flutter-deps-tools
|
||||
shell: bash
|
||||
|
||||
- name: Build AppFlowy
|
||||
working-directory: frontend
|
||||
env:
|
||||
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
|
||||
run: |
|
||||
cargo make --profile development-android appflowy-android-dev-ci
|
||||
@@ -6,8 +6,8 @@ on:
|
||||
- "*"
|
||||
|
||||
env:
|
||||
FLUTTER_VERSION: "3.10.1"
|
||||
RUST_TOOLCHAIN: "1.70"
|
||||
FLUTTER_VERSION: "3.18.0-0.2.pre"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
|
||||
jobs:
|
||||
create-release:
|
||||
@@ -35,13 +35,15 @@ jobs:
|
||||
release_name: v${{ github.ref }}
|
||||
body_path: ${{ env.RELEASE_NOTES_PATH }}
|
||||
|
||||
# the package name should be with the format: AppFlowy-<version>-<os>-<arch>
|
||||
|
||||
build-for-windows:
|
||||
name: ${{ matrix.job.target }} (${{ matrix.job.os }})
|
||||
needs: create-release
|
||||
env:
|
||||
WINDOWS_APP_RELEASE_PATH: frontend\appflowy_flutter\product\${{ github.ref_name }}\windows
|
||||
WINDOWS_ZIP_NAME: AppFlowy_${{ github.ref_name }}_windows-x86_64.zip
|
||||
WINDOWS_INSTALLER_NAME: AppFlowy_${{ github.ref_name }}_windows-x86_64
|
||||
WINDOWS_ZIP_NAME: AppFlowy-${{ github.ref_name }}-windows-x86_64.zip
|
||||
WINDOWS_INSTALLER_NAME: AppFlowy-${{ github.ref_name }}-windows-x86_64
|
||||
runs-on: ${{ matrix.job.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -55,9 +57,8 @@ jobs:
|
||||
- name: Install flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
@@ -68,11 +69,6 @@ jobs:
|
||||
components: rustfmt
|
||||
profile: minimal
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: appflowy-lib-cache
|
||||
key: ${{ matrix.job.os }}-${{ matrix.job.target }}
|
||||
|
||||
- name: Install prerequisites
|
||||
working-directory: frontend
|
||||
run: |
|
||||
@@ -82,9 +78,12 @@ jobs:
|
||||
|
||||
- name: Build Windows app
|
||||
working-directory: frontend
|
||||
# the cargo make script has to be run separately because of file locking issues
|
||||
run: |
|
||||
flutter config --enable-windows-desktop
|
||||
dart ./scripts/flutter_release_build/build_flowy.dart . ${{ github.ref_name }}
|
||||
dart ./scripts/flutter_release_build/build_flowy.dart exclude-directives . ${{ github.ref_name }}
|
||||
cargo make --env APP_VERSION=${{ github.ref_name }} --profile production-windows-x86 appflowy
|
||||
dart ./scripts/flutter_release_build/build_flowy.dart include-directives . ${{ github.ref_name }}
|
||||
|
||||
- name: Archive Asset
|
||||
uses: vimtor/action-zip@v1
|
||||
@@ -130,8 +129,8 @@ jobs:
|
||||
needs: create-release
|
||||
env:
|
||||
MACOS_APP_RELEASE_PATH: frontend/appflowy_flutter/product/${{ github.ref_name }}/macos/Release
|
||||
MACOS_X86_ZIP_NAME: AppFlowy_${{ github.ref_name }}_macos-x86_64.zip
|
||||
MACOS_DMG_NAME: AppFlowy_${{ github.ref_name }}_macos-x86_64
|
||||
MACOS_X86_ZIP_NAME: AppFlowy-${{ github.ref_name }}-macos-x86_64.zip
|
||||
MACOS_DMG_NAME: AppFlowy-${{ github.ref_name }}-macos-x86_64
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -144,9 +143,8 @@ jobs:
|
||||
- name: Install flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
@@ -157,11 +155,6 @@ jobs:
|
||||
components: rustfmt
|
||||
profile: minimal
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: appflowy-lib-cache
|
||||
key: ${{ matrix.job.os }}-${{ matrix.job.target }}
|
||||
|
||||
- name: Install prerequisites
|
||||
working-directory: frontend
|
||||
run: |
|
||||
@@ -172,7 +165,17 @@ jobs:
|
||||
working-directory: frontend
|
||||
run: |
|
||||
flutter config --enable-macos-desktop
|
||||
dart ./scripts/flutter_release_build/build_flowy.dart . ${{ github.ref_name }}
|
||||
dart ./scripts/flutter_release_build/build_flowy.dart run . ${{ github.ref_name }}
|
||||
|
||||
- name: Codesign AppFlowy
|
||||
run: |
|
||||
echo ${{ secrets.MACOS_CERTIFICATE }} | base64 --decode > certificate.p12
|
||||
security create-keychain -p action build.keychain
|
||||
security default-keychain -s build.keychain
|
||||
security unlock-keychain -p action build.keychain
|
||||
security import certificate.p12 -k build.keychain -P ${{ secrets.MACOS_CERTIFICATE_PWD }} -T /usr/bin/codesign
|
||||
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k action build.keychain
|
||||
/usr/bin/codesign --force --options runtime --deep --sign "${{ secrets.MACOS_CODESIGN_ID }}" "${{ env.MACOS_APP_RELEASE_PATH }}/AppFlowy.app" -v
|
||||
|
||||
- name: Create macOS dmg
|
||||
run: |
|
||||
@@ -188,6 +191,10 @@ jobs:
|
||||
"${{ env.MACOS_APP_RELEASE_PATH }}/${{ env.MACOS_DMG_NAME }}.dmg" \
|
||||
"${{ env.MACOS_APP_RELEASE_PATH }}/AppFlowy.app"
|
||||
|
||||
- name: Notarize AppFlowy
|
||||
run: |
|
||||
xcrun notarytool submit ${{ env.MACOS_APP_RELEASE_PATH }}/${{ env.MACOS_DMG_NAME }}.dmg --apple-id ${{ secrets.MACOS_NOTARY_USER }} --team-id ${{ secrets.MACOS_TEAM_ID }} --password ${{ secrets.MACOS_NOTARY_PWD }} -v -f "json" --wait
|
||||
|
||||
- name: Archive Asset
|
||||
working-directory: ${{ env.MACOS_APP_RELEASE_PATH }}
|
||||
run: zip --symlinks -qr ${{ env.MACOS_X86_ZIP_NAME }} AppFlowy.app
|
||||
@@ -218,8 +225,8 @@ jobs:
|
||||
needs: create-release
|
||||
env:
|
||||
MACOS_APP_RELEASE_PATH: frontend/appflowy_flutter/product/${{ github.ref_name }}/macos/Release
|
||||
MACOS_AARCH64_ZIP_NAME: AppFlowy_${{ github.ref_name }}_macos-universal.zip
|
||||
MACOS_DMG_NAME: AppFlowy_${{ github.ref_name }}_macos-universal
|
||||
MACOS_AARCH64_ZIP_NAME: AppFlowy-${{ github.ref_name }}-macos-universal.zip
|
||||
MACOS_DMG_NAME: AppFlowy-${{ github.ref_name }}-macos-universal
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -236,9 +243,8 @@ jobs:
|
||||
- name: Install flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
@@ -247,11 +253,6 @@ jobs:
|
||||
targets: ${{ matrix.job.targets }}
|
||||
components: rustfmt
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: appflowy-lib-cache
|
||||
key: ${{ matrix.job.os }}-${{ matrix.job.target }}
|
||||
|
||||
- name: Install prerequisites
|
||||
working-directory: frontend
|
||||
run: |
|
||||
@@ -262,7 +263,17 @@ jobs:
|
||||
working-directory: frontend
|
||||
run: |
|
||||
flutter config --enable-macos-desktop
|
||||
sh scripts/flutter_release_build/build_universal_package_for_macos.sh
|
||||
sh scripts/flutter_release_build/build_universal_package_for_macos.sh ${{ github.ref_name }}
|
||||
|
||||
- name: Codesign AppFlowy
|
||||
run: |
|
||||
echo ${{ secrets.MACOS_CERTIFICATE }} | base64 --decode > certificate.p12
|
||||
security create-keychain -p action build.keychain
|
||||
security default-keychain -s build.keychain
|
||||
security unlock-keychain -p action build.keychain
|
||||
security import certificate.p12 -k build.keychain -P ${{ secrets.MACOS_CERTIFICATE_PWD }} -T /usr/bin/codesign
|
||||
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k action build.keychain
|
||||
/usr/bin/codesign --force --options runtime --deep --sign "${{ secrets.MACOS_CODESIGN_ID }}" "${{ env.MACOS_APP_RELEASE_PATH }}/AppFlowy.app" -v
|
||||
|
||||
- name: Create macOS dmg
|
||||
run: |
|
||||
@@ -278,6 +289,10 @@ jobs:
|
||||
"${{ env.MACOS_APP_RELEASE_PATH }}/${{ env.MACOS_DMG_NAME }}.dmg" \
|
||||
"${{ env.MACOS_APP_RELEASE_PATH }}/AppFlowy.app"
|
||||
|
||||
- name: Notarize AppFlowy
|
||||
run: |
|
||||
xcrun notarytool submit ${{ env.MACOS_APP_RELEASE_PATH }}/${{ env.MACOS_DMG_NAME }}.dmg --apple-id ${{ secrets.MACOS_NOTARY_USER }} --team-id ${{ secrets.MACOS_TEAM_ID }} --password ${{ secrets.MACOS_NOTARY_PWD }} -v -f "json" --wait
|
||||
|
||||
- name: Archive Asset
|
||||
working-directory: ${{ env.MACOS_APP_RELEASE_PATH }}
|
||||
run: zip --symlinks -qr ${{ env.MACOS_AARCH64_ZIP_NAME }} AppFlowy.app
|
||||
@@ -308,9 +323,11 @@ jobs:
|
||||
needs: create-release
|
||||
env:
|
||||
LINUX_APP_RELEASE_PATH: frontend/appflowy_flutter/product/${{ github.ref_name }}/linux/Release
|
||||
LINUX_ZIP_NAME: AppFlowy_${{ matrix.job.target }}_${{ matrix.job.os }}.tar.gz
|
||||
LINUX_PACKAGE_NAME: AppFlowy_${{ github.ref_name }}_${{ matrix.job.os }}.deb
|
||||
# PKG_CONFIG_SYSROOT_DIR: /
|
||||
LINUX_ZIP_NAME: AppFlowy-${{ matrix.job.target }}-x86_64.tar.gz
|
||||
LINUX_PACKAGE_DEB_NAME: AppFlowy-${{ github.ref_name }}-linux-x86_64.deb
|
||||
LINUX_PACKAGE_RPM_NAME: AppFlowy-${{ github.ref_name }}-linux-x86_64.rpm
|
||||
LINUX_PACKAGE_TMP_RPM_NAME: AppFlowy-${{ github.ref_name }}-2.x86_64.rpm
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -329,9 +346,8 @@ jobs:
|
||||
- name: Install flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
@@ -342,18 +358,14 @@ jobs:
|
||||
components: rustfmt
|
||||
profile: minimal
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: appflowy-lib-cache
|
||||
key: ${{ matrix.job.os }}-${{ matrix.job.target }}
|
||||
|
||||
- name: Install prerequisites
|
||||
working-directory: frontend
|
||||
run: |
|
||||
sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y build-essential libsqlite3-dev libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev
|
||||
sudo apt-get install keybinder-3.0
|
||||
sudo apt-get install keybinder-3.0 libnotify-dev
|
||||
sudo apt-get -y install alien
|
||||
source $HOME/.cargo/env
|
||||
cargo install --force cargo-make
|
||||
cargo install --force duckscript_cli
|
||||
@@ -363,41 +375,31 @@ jobs:
|
||||
if: ${{ matrix.job.target == 'aarch64-unknown-linux-gnu' }}
|
||||
working-directory: frontend
|
||||
run: |
|
||||
sudo apt-get install -qy binutils-aarch64-linux-gnu gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
|
||||
sudo apt-get install -qy binutils-aarch64-linux-gnu gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libgtk-3-0
|
||||
|
||||
- name: Build AppFlowy
|
||||
working-directory: frontend
|
||||
run: |
|
||||
flutter config --enable-linux-desktop
|
||||
dart ./scripts/flutter_release_build/build_flowy.dart . ${{ github.ref_name }}
|
||||
dart ./scripts/flutter_release_build/build_flowy.dart run . ${{ github.ref_name }}
|
||||
|
||||
- name: Archive Assert
|
||||
- name: Archive Asset
|
||||
working-directory: ${{ env.LINUX_APP_RELEASE_PATH }}
|
||||
run: tar -czf ${{ env.LINUX_ZIP_NAME }} *
|
||||
|
||||
- name: Configuring Linux Package
|
||||
- name: Build Linux package (.deb)
|
||||
working-directory: frontend
|
||||
run: |
|
||||
mkdir -p ../${{ env.LINUX_APP_RELEASE_PATH }}/package/opt
|
||||
mkdir -p ../${{ env.LINUX_APP_RELEASE_PATH }}/package/usr/share/applications
|
||||
cp -r ./scripts/linux_installer ../${{ env.LINUX_APP_RELEASE_PATH }}/package/DEBIAN
|
||||
cd ../${{ env.LINUX_APP_RELEASE_PATH }}/package/DEBIAN
|
||||
grep -rl "\[CHANGE_THIS\]" ./control | xargs sed -i "s/\[CHANGE_THIS\]/${{ github.ref_name }}/"
|
||||
chmod 0755 {postinst,postrm}
|
||||
sh scripts/linux_distribution/deb/build_deb.sh appflowy_flutter/product/${{ github.ref_name }}/linux/Release ${{ github.ref_name }} ${{ env.LINUX_PACKAGE_DEB_NAME }}
|
||||
|
||||
- name: Build Linux package
|
||||
- name: Build Linux package (.rpm)
|
||||
working-directory: ${{ env.LINUX_APP_RELEASE_PATH }}
|
||||
run: |
|
||||
mv AppFlowy package/opt/
|
||||
cd package
|
||||
|
||||
# Update Exec & icon path in desktop entry
|
||||
grep -rl "\[CHANGE_THIS\]" ./opt/AppFlowy/appflowy.desktop.temp | xargs sed -i "s/\[CHANGE_THIS\]/\/opt/"
|
||||
# Add desktop entry in package
|
||||
mv ./opt/AppFlowy/appflowy.desktop.temp ./usr/share/applications/appflowy.desktop
|
||||
|
||||
# Build
|
||||
cd ../ && dpkg-deb --build --root-owner-group -Z xz package ${{ env.LINUX_PACKAGE_NAME }}
|
||||
ls -a
|
||||
sudo alien -r ${{ env.LINUX_PACKAGE_DEB_NAME }}
|
||||
echo '------------'
|
||||
cp -r ${{ env.LINUX_PACKAGE_TMP_RPM_NAME }} ${{ env.LINUX_PACKAGE_RPM_NAME }}
|
||||
ls -a
|
||||
|
||||
- name: Upload Asset
|
||||
id: upload-release-asset
|
||||
@@ -410,16 +412,26 @@ jobs:
|
||||
asset_name: ${{ env.LINUX_ZIP_NAME }}
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
- name: Upload Asset Install Package
|
||||
id: upload-release-asset-install-package
|
||||
- name: Upload Debian package
|
||||
id: upload-release-asset-install-package-deb
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||
asset_path: ${{ env.LINUX_APP_RELEASE_PATH }}/${{ env.LINUX_PACKAGE_NAME }}
|
||||
asset_path: ${{ env.LINUX_APP_RELEASE_PATH }}/${{ env.LINUX_PACKAGE_DEB_NAME }}
|
||||
asset_name: ${{ env.LINUX_PACKAGE_DEB_NAME }}
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
asset_name: ${{ env.LINUX_PACKAGE_NAME }}
|
||||
- name: Upload RPM package
|
||||
id: upload-release-asset-install-package-rpm
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||
asset_path: ${{ env.LINUX_APP_RELEASE_PATH }}/${{ env.LINUX_PACKAGE_RPM_NAME }}
|
||||
asset_name: ${{ env.LINUX_PACKAGE_RPM_NAME }}
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
build-for-docker:
|
||||
|
||||
@@ -8,7 +8,6 @@ on:
|
||||
- "release/*"
|
||||
paths:
|
||||
- "frontend/rust-lib/**"
|
||||
- "shared-lib/**"
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
@@ -17,14 +16,14 @@ on:
|
||||
- "release/*"
|
||||
paths:
|
||||
- "frontend/rust-lib/**"
|
||||
- "shared-lib/**"
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
RUST_TOOLCHAIN: "1.70"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
|
||||
jobs:
|
||||
test-on-ubuntu:
|
||||
# environment: SUPABASE_CI
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
@@ -49,16 +48,60 @@ jobs:
|
||||
with:
|
||||
prefix-key: 'ubuntu-latest'
|
||||
workspaces: |
|
||||
frontend/rust-lib
|
||||
frontend/rust-lib
|
||||
|
||||
# - name: Create .env file in flowy-server
|
||||
# working-directory: frontend/rust-lib/flowy-server
|
||||
# run: |
|
||||
# touch .env.ci
|
||||
# echo SUPABASE_URL=${{ secrets.SUPABASE_URL }} >> .env.ci
|
||||
# echo SUPABASE_ANON_KEY=${{ secrets.SUPABASE_ANON_KEY }} >> .env.ci
|
||||
# echo SUPABASE_JWT_SECRET=${{ secrets.SUPABASE_JWT_SECRET }} >> .env.ci
|
||||
#
|
||||
# - name: Create .env file in event-integration
|
||||
# working-directory: frontend/rust-lib/event-integration
|
||||
# run: |
|
||||
# touch .env.ci
|
||||
# echo SUPABASE_URL=${{ secrets.SUPABASE_URL }} >> .env.ci
|
||||
# echo SUPABASE_ANON_KEY=${{ secrets.SUPABASE_ANON_KEY }} >> .env.ci
|
||||
# echo SUPABASE_JWT_SECRET=${{ secrets.SUPABASE_JWT_SECRET }} >> .env.ci
|
||||
|
||||
- name: Checkout appflowy cloud code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: AppFlowy-IO/AppFlowy-Cloud
|
||||
path: AppFlowy-Cloud
|
||||
depth: 1
|
||||
|
||||
- name: Prepare appflowy cloud env
|
||||
working-directory: AppFlowy-Cloud
|
||||
run: |
|
||||
# log level
|
||||
cp deploy.env .env
|
||||
sed -i 's|RUST_LOG=.*|RUST_LOG=trace|' .env
|
||||
sed -i 's|API_EXTERNAL_URL=.*|API_EXTERNAL_URL=http://localhost|' .env
|
||||
|
||||
- name: Run Docker-Compose
|
||||
working-directory: AppFlowy-Cloud
|
||||
run: |
|
||||
docker pull appflowyinc/appflowy_cloud:latest
|
||||
docker compose up -d
|
||||
|
||||
- name: Run rust-lib tests
|
||||
working-directory: frontend/rust-lib
|
||||
run: RUST_LOG=info RUST_BACKTRACE=1 cargo test --no-default-features --features="rev-sqlite"
|
||||
env:
|
||||
RUST_LOG: info
|
||||
RUST_BACKTRACE: 1
|
||||
af_cloud_test_base_url: http://localhost
|
||||
af_cloud_test_ws_url: ws://localhost/ws
|
||||
af_cloud_test_gotrue_url: http://localhost/gotrue
|
||||
run: cargo test --no-default-features --features="rev-sqlite" -- --nocapture
|
||||
|
||||
|
||||
- name: rustfmt rust-lib
|
||||
run: cargo fmt --all -- --check
|
||||
working-directory: frontend/rust-lib/
|
||||
|
||||
- name: clippy rust-lib
|
||||
run: cargo clippy --features="rev-sqlite"
|
||||
run: cargo clippy --all-targets -- -D warnings
|
||||
working-directory: frontend/rust-lib
|
||||
@@ -7,12 +7,11 @@ on:
|
||||
- "release/*"
|
||||
paths:
|
||||
- "frontend/rust-lib/**"
|
||||
- "shared-lib/**"
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
FLUTTER_VERSION: "3.10.1"
|
||||
RUST_TOOLCHAIN: "1.70"
|
||||
FLUTTER_VERSION: "3.18.0-0.2.pre"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
@@ -34,7 +33,7 @@ jobs:
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ on:
|
||||
env:
|
||||
NODE_VERSION: "18.16.0"
|
||||
PNPM_VERSION: "8.5.0"
|
||||
RUST_TOOLCHAIN: "1.70"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
@@ -32,6 +32,26 @@ jobs:
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Cache Rust Dependencies
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
key: rust-dependencies-${{ runner.os }}
|
||||
workspaces: |
|
||||
frontend/rust-lib
|
||||
frontend/appflowy_tauri/src-tauri
|
||||
|
||||
- name: Cache Node.js dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: npm-${{ runner.os }}
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: frontend/appflowy_tauri/node_modules
|
||||
key: node-modules-${{ runner.os }}
|
||||
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
@@ -40,13 +60,6 @@ jobs:
|
||||
override: true
|
||||
profile: minimal
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: 'ubuntu-latest-tauri'
|
||||
workspaces: |
|
||||
frontend/rust-lib
|
||||
frontend/appflowy_tauri/src-tauri
|
||||
|
||||
- name: install dependencies (windows only)
|
||||
if: matrix.platform == 'windows-latest'
|
||||
working-directory: frontend
|
||||
@@ -75,15 +88,23 @@ jobs:
|
||||
cargo make appflowy-tauri-deps-tools
|
||||
npm install -g pnpm@${{ env.PNPM_VERSION }}
|
||||
|
||||
|
||||
- name: build
|
||||
- name: Build
|
||||
working-directory: frontend/appflowy_tauri
|
||||
run: |
|
||||
mkdir dist
|
||||
pnpm install
|
||||
cargo make --cwd .. tauri_build
|
||||
pnpm test
|
||||
pnpm test:errors
|
||||
|
||||
- name: Check for uncommitted changes
|
||||
run: |
|
||||
diff_files=$(git status --porcelain)
|
||||
if [ -n "$diff_files" ]; then
|
||||
echo "There are uncommitted changes in the working tree. Please commit them before pushing."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- uses: tauri-apps/tauri-action@v0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,82 @@
|
||||
name: WEB-CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- "main"
|
||||
paths:
|
||||
- ".github/workflows/web_ci.yaml"
|
||||
- "frontend/rust-lib/**"
|
||||
- "frontend/appflowy_web/**"
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
NODE_VERSION: "18.16.0"
|
||||
PNPM_VERSION: "8.5.0"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
CARGO_MAKE_VERSION: "0.36.6"
|
||||
|
||||
jobs:
|
||||
web-build:
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [ubuntu-latest]
|
||||
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Cache Rust Dependencies
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
key: rust-dependencies-${{ runner.os }}
|
||||
workspaces: |
|
||||
frontend/rust-lib
|
||||
frontend/appflowy_web/appflowy_wasm
|
||||
|
||||
- name: Cache Node.js dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: npm-${{ runner.os }}
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: frontend/appflowy_web/node_modules
|
||||
key: node-modules-${{ runner.os }}
|
||||
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
override: true
|
||||
profile: minimal
|
||||
|
||||
- name: Install wasm-pack
|
||||
run: cargo install wasm-pack
|
||||
|
||||
- uses: taiki-e/install-action@v2
|
||||
with:
|
||||
tool: cargo-make@${{ env.CARGO_MAKE_VERSION }}
|
||||
|
||||
- name: install dependencies
|
||||
if: matrix.platform == 'ubuntu-latest'
|
||||
working-directory: frontend
|
||||
run: |
|
||||
sudo apt-get update
|
||||
npm install -g pnpm@${{ env.PNPM_VERSION }}
|
||||
cargo make install_web_protobuf
|
||||
|
||||
- name: Build
|
||||
working-directory: frontend/appflowy_web
|
||||
run: |
|
||||
pnpm install
|
||||
pnpm run wasm
|
||||
@@ -21,11 +21,8 @@ node_modules
|
||||
|
||||
**/resources/proto
|
||||
|
||||
!frontend/.vscode/settings.json
|
||||
!frontend/.vscode/tasks.json
|
||||
!frontend/.vscode/launch.json
|
||||
!frontend/.vscode/extensions.json
|
||||
!frontend/.vscode/*.code-snippets
|
||||
# ignore settings.json
|
||||
frontend/.vscode/settings.json
|
||||
|
||||
# Commit the highest level pubspec.lock, but ignore the others
|
||||
pubspec.lock
|
||||
@@ -37,3 +34,9 @@ pubspec.lock
|
||||
.fvm/
|
||||
|
||||
**/AppFlowy-Collab/
|
||||
|
||||
# ignore generated assets
|
||||
frontend/package
|
||||
frontend/*.deb
|
||||
|
||||
**/Cargo.toml.bak
|
||||
@@ -1,23 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="ProtoBuf_Gen" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
|
||||
<option name="command" value="run --manifest-path ${flowy_tool} -- pb-gen --rust_sources=${rust_lib},${shared_lib} --derive_meta=${derive_meta} --flutter_package_lib=${flutter_package_lib}" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$/frontend" />
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="allFeatures" value="false" />
|
||||
<option name="emulateTerminal" value="false" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<envs>
|
||||
<env name="flowy_tool" value="${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/scripts/flowy-tool/Cargo.toml" />
|
||||
<env name="rust_lib" value="${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/" />
|
||||
<env name="shared_lib" value="${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/../shared_lib" />
|
||||
<env name="flutter_lib" value="${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/appflowy_flutter/packages" />
|
||||
<env name="derive_meta" value="${shared_lib}/flowy-derive/src/derive_cache/derive_cache.rs" />
|
||||
<env name="flutter_package_lib" value="${flutter_lib}/flowy_sdk/lib" />
|
||||
</envs>
|
||||
<option name="isRedirectInput" value="false" />
|
||||
<option name="redirectInputPath" value="" />
|
||||
<method v="2">
|
||||
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,18 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Run backend" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
|
||||
<option name="command" value="run --package backend --bin backend" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$/backend" />
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="allFeatures" value="false" />
|
||||
<option name="emulateTerminal" value="false" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<envs>
|
||||
<env name="APP_ENVIRONMENT" value="production" />
|
||||
</envs>
|
||||
<option name="isRedirectInput" value="false" />
|
||||
<option name="redirectInputPath" value="" />
|
||||
<method v="2">
|
||||
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,16 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="dart-event" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
|
||||
<option name="command" value="run --manifest-path $PROJECT_DIR$/scripts/flowy-tool/Cargo.toml -- dart-event --rust_source=$PROJECT_DIR$/rust-lib/ --output=$PROJECT_DIR$/appflowy_flutter/packages/flowy_sdk/lib/dispatch/dart_event.dart" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="allFeatures" value="false" />
|
||||
<option name="emulateTerminal" value="false" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<envs />
|
||||
<option name="isRedirectInput" value="false" />
|
||||
<option name="redirectInputPath" value="" />
|
||||
<method v="2">
|
||||
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,5 +1,168 @@
|
||||
# Release Notes
|
||||
|
||||
## Version 0.4.1 - 01/03/2024
|
||||
### Bug fixes
|
||||
- Fix import AppFlowy data folder
|
||||
|
||||
## Version 0.4.0 - 12/30/2023
|
||||
1. Added capability to import data from an AppFlowy data folder. For detailed information, please see [AppFlowy Data Storage Documentation](https://docs.appflowy.io/docs/appflowy/product/data-storage).
|
||||
2. Enhanced user interface and fixed various bugs.
|
||||
3. Improved the efficiency of data synchronization in AppFlowy Cloud
|
||||
|
||||
## Version 0.3.9.1 - 12/07/2023
|
||||
|
||||
### Bug fixes
|
||||
- Fix potential blank pages that may occur in an empty document
|
||||
|
||||
## Version 0.3.9 - 12/07/2023
|
||||
|
||||
### New Features
|
||||
- Support inserting a new field to the left or right of an existing one
|
||||
|
||||
### Bug fixes
|
||||
- Fix some emojis are shown in black/white
|
||||
- Fix unable to rename a subpage of subpage
|
||||
|
||||
## Version 0.3.8 - 11/13/2023
|
||||
|
||||
### New Features
|
||||
- Support hiding any stack in a board
|
||||
- Support customizing page icons in menu
|
||||
- Display visual hint when card contains notes
|
||||
- Quick action for adding new stack to a board
|
||||
- Support more ways of inserting page references in documents
|
||||
- Shift + click on a checkbox to power toggle its children
|
||||
|
||||
### Bug fixes
|
||||
- Improved color of the "Share"-button text
|
||||
- Text overflow issue in Calendar properties
|
||||
- Default font (Roboto) added to application
|
||||
- Placeholder added for the editor inside a Card
|
||||
- Toggle notifications in settings have been fixed
|
||||
- Dialog for linking board/grid/calendar opens in correct position
|
||||
- Quick add Card in Board at top, correctly adds a new Card at the top
|
||||
|
||||
## Version 0.3.7 - 10/30/2023
|
||||
|
||||
### New Features
|
||||
- Support showing checklist items inline in row page.
|
||||
- Support inserting date from slash menu.
|
||||
- Support renaming a stack directly by clicking on the stack name.
|
||||
- Show the detailed reminder content in the notification center.
|
||||
- Save card order in Board view.
|
||||
- Allow to hide the ungrouped stack.
|
||||
- Segmented the checklist progress bar.
|
||||
|
||||
### Bug fixes
|
||||
- Optimize side panel animation.
|
||||
- Fix calendar with hidden date or title doesn't show options correctly.
|
||||
- Fix the horizontal scroll bar disappears in Grid view.
|
||||
- Improve setting tab UI in Grid view.
|
||||
- Improve theme of the code block.
|
||||
- Fix some UI issues.
|
||||
|
||||
## Version 0.3.6 - 10/16/2023
|
||||
|
||||
### New Features
|
||||
- Support setting Markdown styles through keyboard shortcuts.
|
||||
- Added Ukrainian language.
|
||||
- Support auto-hiding sidebar feature, ensuring a streamlined view even when resizing to a smaller window.
|
||||
- Support toggling the notifitcation on/off.
|
||||
- Added Lemonade theme.
|
||||
|
||||
### Bug fixes
|
||||
- Improve Vietnamese translations.
|
||||
- Improve reminder feature.
|
||||
- Fix some UI issues.
|
||||
|
||||
## Version 0.3.5 - 10/09/2023
|
||||
|
||||
### New Features
|
||||
- Added support for browsing and inserting images from Unsplash.
|
||||
- Revamp and unify the emoji picker throughout AppFlowy.
|
||||
|
||||
### Bug fixes
|
||||
- Improve layout of the settings page.
|
||||
- Improve design of the restore page banner.
|
||||
- Improve UX of the reminders.
|
||||
- Other UI fixes.
|
||||
|
||||
## Version 0.3.4 - 10/02/2023
|
||||
|
||||
### New Features
|
||||
- Added support for creating a reminder.
|
||||
- Added support for finding and replacing in the document page.
|
||||
- Added support for showing the hidden fields in row detail page.
|
||||
- Adjust the toolbar style in RTL mode.
|
||||
|
||||
### Bug fixes
|
||||
- Improve snackbar UI design.
|
||||
- Improve dandelion theme.
|
||||
- Improve id-ID and pl-PL language translations.
|
||||
|
||||
## Version 0.3.3 - 09/24/2023
|
||||
|
||||
### New Features
|
||||
- Added an end date field to the time cell in the database.
|
||||
- Added Support for customizing the font family from GoogleFonts in the editor.
|
||||
- Set the uploaded image to cover by default.
|
||||
- Added Support for resetting the user icon on settings page
|
||||
- Add Urdu language translations.
|
||||
|
||||
### Bug fixes
|
||||
- Default colors for the blocks except for the callout were not transparent.
|
||||
- Option/Alt + click to add a block above didn't work on the first line.
|
||||
- Unable to paste HTML content containing `<mark>` tag.
|
||||
- Unable to select the text from anywhere in the line.
|
||||
- The selection in the editor didn't clear when editing the inline database.
|
||||
- Added a bottom border to new property column in the database.
|
||||
- Set minimum width of 50px for grid fields.
|
||||
|
||||
## Version 0.3.2 - 09/18/2023
|
||||
|
||||
### New Features
|
||||
|
||||
- Improve the performance of the editor, now it is much faster when editing a large document.
|
||||
- Support for reordering the rows of the database on Windows.
|
||||
- Revamp the row detail page of the database.
|
||||
- Revamp the checklist cell editor of the database.
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Some UI issues
|
||||
|
||||
## Version 0.3.1 - 09/04/2023
|
||||
|
||||
### New Features
|
||||
|
||||
- Improve CJK (Chinese, Japanese, Korean) input method support.
|
||||
- Share a database in CSV format.
|
||||
- Support for aligning the block component with the toolbar.
|
||||
- Support for editing name when creating a new page.
|
||||
- Support for inserting a table in the document page.
|
||||
- Database views allow for independent field visibility toggling.
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Paste multiple lines in code block.
|
||||
- Some UI issues
|
||||
|
||||
## Version 0.3.0 - 08/22/2023
|
||||
|
||||
### New Features
|
||||
|
||||
- Improve paste features:
|
||||
- Paste HTML content from website.
|
||||
- Paste image from clipboard.
|
||||
|
||||
- Support Group by Date in Kanban Board.
|
||||
- Notarize the macOS package, which is now verified by Apple.
|
||||
- Add Persian language translations.
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Some UI issues
|
||||
|
||||
## Version 0.2.9 - 08/08/2023
|
||||
|
||||
### New Features
|
||||
|
||||
@@ -18,7 +18,7 @@ You are in charge of your data and customizations.
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="http://www.appflowy.io"><b>Website</b></a> •
|
||||
<a href="https://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>
|
||||
@@ -47,7 +47,7 @@ You are in charge of your data and customizations.
|
||||
|
||||
## Getting Started with development
|
||||
|
||||
Please view the [documentation](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy) for OS specific development instructions
|
||||
Please view the [documentation](https://docs.appflowy.io/docs/documentation/appflowy/from-source) for OS specific development instructions
|
||||
|
||||
## Roadmap
|
||||
|
||||
@@ -73,7 +73,7 @@ Proudly wear your T-shirt and show it to us by tagging [@appflowy](https://twitt
|
||||
|
||||
[](https://inlang.com/editor/github.com/AppFlowy-IO/AppFlowy?ref=badge)
|
||||
|
||||
To add translations, you can manually edit the JSON translation files in `/frontend/appflowy_flutter/assets/translations`, use the [inlang online editor](https://inlang.com/editor/github.com/AppFlowy-IO/AppFlowy), or run `npx inlang machine translate` to add missing translations.
|
||||
To add translations, you can manually edit the JSON translation files in `/frontend/resources/translations`, use the [inlang online editor](https://inlang.com/editor/github.com/AppFlowy-IO/AppFlowy), or run `npx inlang machine translate` to add missing translations.
|
||||
|
||||
|
||||
## Join the community to build AppFlowy together
|
||||
|
||||
@@ -4,6 +4,21 @@
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
// This task only builds the Dart code of AppFlowy.
|
||||
// It supports both the desktop and mobile version.
|
||||
"name": "AF: Build Dart Only",
|
||||
"request": "launch",
|
||||
"program": "./lib/main.dart",
|
||||
"type": "dart",
|
||||
"env": {
|
||||
"RUST_LOG": "trace",
|
||||
"RUST_BACKTRACE": "1"
|
||||
},
|
||||
// uncomment the following line to testing performance.
|
||||
// "flutterMode": "profile",
|
||||
"cwd": "${workspaceRoot}/appflowy_flutter"
|
||||
},
|
||||
{
|
||||
// This task builds the Rust and Dart code of AppFlowy.
|
||||
"name": "AF-desktop: Build All",
|
||||
@@ -13,18 +28,7 @@
|
||||
"preLaunchTask": "AF: Build Appflowy Core",
|
||||
"env": {
|
||||
"RUST_LOG": "trace",
|
||||
"RUST_BACKTRACE": 1
|
||||
},
|
||||
"cwd": "${workspaceRoot}/appflowy_flutter"
|
||||
},
|
||||
{
|
||||
// This task only builds the Dart code of AppFlowy.
|
||||
"name": "AF-desktop: Build Dart Only",
|
||||
"request": "launch",
|
||||
"program": "./lib/main.dart",
|
||||
"type": "dart",
|
||||
"env": {
|
||||
"RUST_LOG": "debug",
|
||||
"RUST_BACKTRACE": "1"
|
||||
},
|
||||
"cwd": "${workspaceRoot}/appflowy_flutter"
|
||||
},
|
||||
@@ -43,6 +47,17 @@
|
||||
},
|
||||
"cwd": "${workspaceRoot}/appflowy_flutter"
|
||||
},
|
||||
{
|
||||
"name": "AF-iOS: Build All",
|
||||
"request": "launch",
|
||||
"program": "./lib/main.dart",
|
||||
"type": "dart",
|
||||
"preLaunchTask": "AF: Build Appflowy Core For iOS",
|
||||
"env": {
|
||||
"RUST_LOG": "trace"
|
||||
},
|
||||
"cwd": "${workspaceRoot}/appflowy_flutter"
|
||||
},
|
||||
{
|
||||
"name": "AF-iOS: Clean + Rebuild All",
|
||||
"request": "launch",
|
||||
@@ -54,6 +69,17 @@
|
||||
},
|
||||
"cwd": "${workspaceRoot}/appflowy_flutter"
|
||||
},
|
||||
{
|
||||
"name": "AF-iOS-Simulator: Build All",
|
||||
"request": "launch",
|
||||
"program": "./lib/main.dart",
|
||||
"type": "dart",
|
||||
"preLaunchTask": "AF: Build Appflowy Core For iOS Simulator",
|
||||
"env": {
|
||||
"RUST_LOG": "trace"
|
||||
},
|
||||
"cwd": "${workspaceRoot}/appflowy_flutter"
|
||||
},
|
||||
{
|
||||
"name": "AF-iOS-Simulator: Clean + Rebuild All",
|
||||
"request": "launch",
|
||||
@@ -65,6 +91,28 @@
|
||||
},
|
||||
"cwd": "${workspaceRoot}/appflowy_flutter"
|
||||
},
|
||||
{
|
||||
"name": "AF-Android: Build All",
|
||||
"request": "launch",
|
||||
"program": "./lib/main.dart",
|
||||
"type": "dart",
|
||||
"preLaunchTask": "AF: Build Appflowy Core For Android",
|
||||
"env": {
|
||||
"RUST_LOG": "trace"
|
||||
},
|
||||
"cwd": "${workspaceRoot}/appflowy_flutter"
|
||||
},
|
||||
{
|
||||
"name": "AF-Android: Clean + Rebuild All",
|
||||
"request": "launch",
|
||||
"program": "./lib/main.dart",
|
||||
"type": "dart",
|
||||
"preLaunchTask": "AF: Clean + Rebuild All (Android)",
|
||||
"env": {
|
||||
"RUST_LOG": "trace"
|
||||
},
|
||||
"cwd": "${workspaceRoot}/appflowy_flutter"
|
||||
},
|
||||
{
|
||||
"name": "AF-desktop: Debug Rust",
|
||||
"request": "attach",
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
{
|
||||
"[dart]": {
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnType": true,
|
||||
"editor.rulers": [80],
|
||||
"editor.selectionHighlight": false,
|
||||
"editor.suggest.snippetsPreventQuickSuggestions": false,
|
||||
"editor.suggestSelection": "first",
|
||||
"editor.tabCompletion": "onlySnippets",
|
||||
"editor.wordBasedSuggestions": false,
|
||||
},
|
||||
"[javascript]": {
|
||||
"editor.formatOnSave": true,
|
||||
"editor.rulers": [80],
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.formatOnSave": true,
|
||||
"editor.rulers": [80],
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"svgviewer.enableautopreview": true,
|
||||
"svgviewer.previewcolumn": "Active",
|
||||
"svgviewer.showzoominout": true,
|
||||
"editor.wordWrapColumn": 80,
|
||||
"editor.minimap.maxColumn": 140,
|
||||
"editor.wordWrap": "wordWrapColumn",
|
||||
"dart.lineLength": 80,
|
||||
"typescript.validate.enable": true,
|
||||
"javascript.validate.enable": true,
|
||||
"files.associations": {
|
||||
"*.log.*": "log"
|
||||
},
|
||||
"editor.formatOnSave": true,
|
||||
"files.eol": "\n",
|
||||
}
|
||||
@@ -18,9 +18,9 @@
|
||||
"AF: Flutter Clean",
|
||||
"AF: Build Appflowy Core",
|
||||
"AF: Flutter Pub Get",
|
||||
"AF: Flutter Package Get",
|
||||
"AF: Generate Language Files",
|
||||
"AF: Generate Freezed Files"
|
||||
"AF: Generate Freezed Files",
|
||||
"AF: Generate Svg Files"
|
||||
],
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
@@ -36,9 +36,9 @@
|
||||
"AF: Flutter Clean",
|
||||
"AF: Build Appflowy Core For iOS",
|
||||
"AF: Flutter Pub Get",
|
||||
"AF: Flutter Package Get",
|
||||
"AF: Generate Language Files",
|
||||
"AF: Generate Freezed Files"
|
||||
"AF: Generate Freezed Files",
|
||||
"AF: Generate Svg Files"
|
||||
],
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
@@ -54,15 +54,50 @@
|
||||
"AF: Flutter Clean",
|
||||
"AF: Build Appflowy Core For iOS Simulator",
|
||||
"AF: Flutter Pub Get",
|
||||
"AF: Flutter Package Get",
|
||||
"AF: Generate Language Files",
|
||||
"AF: Generate Freezed Files"
|
||||
"AF: Generate Freezed Files",
|
||||
"AF: Generate Svg Files"
|
||||
],
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "new"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Clean + Rebuild All (Android)",
|
||||
"type": "shell",
|
||||
"dependsOrder": "sequence",
|
||||
"dependsOn": [
|
||||
"AF: Dart Clean",
|
||||
"AF: Flutter Clean",
|
||||
"AF: Build Appflowy Core For Android",
|
||||
"AF: Flutter Pub Get",
|
||||
"AF: Generate Language Files",
|
||||
"AF: Generate Freezed Files",
|
||||
"AF: Generate Svg Files"
|
||||
],
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "new"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Build Appflowy Core",
|
||||
"type": "shell",
|
||||
"windows": {
|
||||
"command": "cargo make --profile development-windows-x86 appflowy-core-dev"
|
||||
},
|
||||
"linux": {
|
||||
"command": "cargo make --profile \"development-linux-$(uname -m)\" appflowy-core-dev"
|
||||
},
|
||||
"osx": {
|
||||
"command": "cargo make --profile \"development-mac-$(uname -m)\" appflowy-core-dev"
|
||||
},
|
||||
"group": "build",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Build Appflowy Core For iOS",
|
||||
"type": "shell",
|
||||
@@ -82,17 +117,9 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Build Appflowy Core",
|
||||
"label": "AF: Build Appflowy Core For Android",
|
||||
"type": "shell",
|
||||
"windows": {
|
||||
"command": "cargo make --profile development-windows-x86 appflowy-core-dev"
|
||||
},
|
||||
"linux": {
|
||||
"command": "cargo make --profile \"development-linux-$(uname -m)\" appflowy-core-dev"
|
||||
},
|
||||
"osx": {
|
||||
"command": "cargo make --profile \"development-mac-$(uname -m)\" appflowy-core-dev"
|
||||
},
|
||||
"command": "cargo make --profile development-android appflowy-core-dev-android",
|
||||
"group": "build",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}"
|
||||
@@ -105,9 +132,9 @@
|
||||
"dependsOn": [
|
||||
"AF: Flutter Clean",
|
||||
"AF: Flutter Pub Get",
|
||||
"AF: Flutter Package Get",
|
||||
"AF: Generate Language Files",
|
||||
"AF: Generate Freezed Files"
|
||||
"AF: Generate Freezed Files",
|
||||
"AF: Generate Svg Files"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
@@ -118,6 +145,15 @@
|
||||
"panel": "new"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Dart Clean",
|
||||
"type": "shell",
|
||||
"command": "cargo make flutter_clean",
|
||||
"group": "build",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Flutter Clean",
|
||||
"type": "shell",
|
||||
@@ -134,14 +170,6 @@
|
||||
"cwd": "${workspaceFolder}/appflowy_flutter"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Flutter Package Get",
|
||||
"type": "shell",
|
||||
"command": "flutter packages pub get",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/appflowy_flutter"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Generate Freezed Files",
|
||||
"type": "shell",
|
||||
@@ -161,7 +189,7 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Generate Language Files",
|
||||
@@ -185,9 +213,21 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Flutter Clean",
|
||||
"label": "AF: Generate Svg Files",
|
||||
"type": "shell",
|
||||
"command": "cargo make flutter_clean",
|
||||
"command": "sh ./scripts/code_generation/flowy_icons/generate_flowy_icons.sh",
|
||||
"windows": {
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "cmd.exe",
|
||||
"args": [
|
||||
"/d",
|
||||
"/c",
|
||||
".\\scripts\\code_generation\\flowy_icons\\generate_flowy_icons.cmd"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"group": "build",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}"
|
||||
@@ -205,18 +245,6 @@
|
||||
"problemMatcher": [],
|
||||
"detail": "appflowy_flutter"
|
||||
},
|
||||
{
|
||||
"label": "AF: Tauri UI Dev",
|
||||
"type": "shell",
|
||||
"isBackground": true,
|
||||
"command": "yarn",
|
||||
"args": [
|
||||
"dev"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/appflowy_tauri"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Tauri UI Build",
|
||||
"type": "shell",
|
||||
@@ -226,9 +254,10 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Tauri Dev",
|
||||
"label": "AF: Tauri UI Dev",
|
||||
"type": "shell",
|
||||
"command": "npm run tauri:dev",
|
||||
"isBackground": true,
|
||||
"command": "pnpm run tauri:dev",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/appflowy_tauri"
|
||||
}
|
||||
@@ -262,12 +291,12 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Generate Env",
|
||||
"label": "AF: Generate Env File",
|
||||
"type": "shell",
|
||||
"command": "dart run build_runner clean && dart run build_runner build --delete-conflicting-outputs ",
|
||||
"command": "dart run build_runner clean && dart run build_runner build --delete-conflicting-outputs",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/appflowy_flutter"
|
||||
}
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -20,13 +20,15 @@ run_task = { name = ["restore-crate-type"] }
|
||||
|
||||
[env]
|
||||
RUST_LOG = "info"
|
||||
CARGO_PROFILE = "dev"
|
||||
CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
|
||||
CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
|
||||
CARGO_MAKE_CRATE_NAME = "dart-ffi"
|
||||
LIB_NAME = "dart_ffi"
|
||||
CURRENT_APP_VERSION = "0.2.9"
|
||||
APPFLOWY_VERSION = "0.4.2"
|
||||
FLUTTER_DESKTOP_FEATURES = "dart,rev-sqlite"
|
||||
PRODUCT_NAME = "AppFlowy"
|
||||
MACOSX_DEPLOYMENT_TARGET = "11.0"
|
||||
# CRATE_TYPE: https://doc.rust-lang.org/reference/linkage.html
|
||||
# If you update the macOS's CRATE_TYPE, don't forget to update the
|
||||
# appflowy_backend.podspec
|
||||
@@ -75,6 +77,7 @@ BUILD_ACTIVE_ARCHS_ONLY = true
|
||||
CRATE_TYPE = "staticlib"
|
||||
|
||||
[env.production-mac-arm64]
|
||||
CARGO_PROFILE = "release"
|
||||
BUILD_FLAG = "release"
|
||||
TARGET_OS = "macos"
|
||||
RUST_COMPILE_TARGET = "aarch64-apple-darwin"
|
||||
@@ -86,6 +89,7 @@ BUILD_ACTIVE_ARCHS_ONLY = false
|
||||
CRATE_TYPE = "staticlib"
|
||||
|
||||
[env.production-mac-x86_64]
|
||||
CARGO_PROFILE = "release"
|
||||
BUILD_FLAG = "release"
|
||||
TARGET_OS = "macos"
|
||||
RUST_COMPILE_TARGET = "x86_64-apple-darwin"
|
||||
@@ -97,6 +101,7 @@ BUILD_ACTIVE_ARCHS_ONLY = false
|
||||
CRATE_TYPE = "staticlib"
|
||||
|
||||
[env.production-mac-universal]
|
||||
CARGO_PROFILE = "release"
|
||||
BUILD_FLAG = "release"
|
||||
TARGET_OS = "macos"
|
||||
FLUTTER_OUTPUT_DIR = "Release"
|
||||
@@ -114,6 +119,7 @@ CRATE_TYPE = "cdylib"
|
||||
LIB_EXT = "dll"
|
||||
|
||||
[env.production-windows-x86]
|
||||
CARGO_PROFILE = "release"
|
||||
BUILD_FLAG = "release"
|
||||
TARGET_OS = "windows"
|
||||
RUST_COMPILE_TARGET = "x86_64-pc-windows-msvc"
|
||||
@@ -121,6 +127,7 @@ FLUTTER_OUTPUT_DIR = "Release"
|
||||
PRODUCT_EXT = "exe"
|
||||
CRATE_TYPE = "cdylib"
|
||||
LIB_EXT = "dll"
|
||||
BUILD_ARCHS = "x64"
|
||||
APP_ENVIRONMENT = "production"
|
||||
|
||||
[env.development-linux-x86_64]
|
||||
@@ -133,6 +140,7 @@ LIB_EXT = "so"
|
||||
LINUX_ARCH = "x64"
|
||||
|
||||
[env.production-linux-x86_64]
|
||||
CARGO_PROFILE = "release"
|
||||
BUILD_FLAG = "release"
|
||||
TARGET_OS = "linux"
|
||||
RUST_COMPILE_TARGET = "x86_64-unknown-linux-gnu"
|
||||
@@ -153,6 +161,7 @@ LINUX_ARCH = "arm64"
|
||||
FLUTTER_DESKTOP_FEATURES = "dart,rev-sqlite,openssl_vendored"
|
||||
|
||||
[env.production-linux-aarch64]
|
||||
CARGO_PROFILE = "release"
|
||||
BUILD_FLAG = "release"
|
||||
TARGET_OS = "linux"
|
||||
RUST_COMPILE_TARGET = "aarch64-unknown-linux-gnu"
|
||||
@@ -179,6 +188,31 @@ RUST_COMPILE_TARGET = "aarch64-apple-ios"
|
||||
BUILD_ARCHS = "arm64"
|
||||
CRATE_TYPE = "staticlib"
|
||||
|
||||
[env.production-ios-arm64]
|
||||
BUILD_FLAG = "release"
|
||||
TARGET_OS = "ios"
|
||||
FLUTTER_OUTPUT_DIR = "Release"
|
||||
RUST_COMPILE_TARGET = "aarch64-apple-ios"
|
||||
BUILD_ARCHS = "arm64"
|
||||
CRATE_TYPE = "staticlib"
|
||||
|
||||
[env.development-android]
|
||||
BUILD_FLAG = "debug"
|
||||
TARGET_OS = "android"
|
||||
CRATE_TYPE = "cdylib"
|
||||
FLUTTER_OUTPUT_DIR = "Debug"
|
||||
LIB_EXT = "so"
|
||||
PRODUCT_EXT = "apk"
|
||||
FLUTTER_DESKTOP_FEATURES = "dart,rev-sqlite,openssl_vendored"
|
||||
|
||||
[env.production-android]
|
||||
BUILD_FLAG = "release"
|
||||
TARGET_OS = "android"
|
||||
CRATE_TYPE = "cdylib"
|
||||
FLUTTER_OUTPUT_DIR = "Release"
|
||||
PRODUCT_EXT = "apk"
|
||||
LIB_EXT = "so"
|
||||
|
||||
[tasks.echo_env]
|
||||
script = ['''
|
||||
echo "-------- Env Parameters --------"
|
||||
@@ -191,23 +225,10 @@ script = ['''
|
||||
echo APP_ENVIRONMENT: ${APP_ENVIRONMENT}
|
||||
echo ${platforms}
|
||||
echo ${BUILD_ARCHS}
|
||||
echo ${BUILD_VERSION}
|
||||
''']
|
||||
script_runner = "@shell"
|
||||
|
||||
[env.development-android]
|
||||
BUILD_FLAG = "debug"
|
||||
TARGET_OS = "android"
|
||||
CRATE_TYPE = "cdylib"
|
||||
FLUTTER_OUTPUT_DIR = "Debug"
|
||||
FLUTTER_DESKTOP_FEATURES = "dart,rev-sqlite,openssl_vendored"
|
||||
|
||||
[env.production-android]
|
||||
BUILD_FLAG = "release"
|
||||
TARGET_OS = "android"
|
||||
CRATE_TYPE = "cdylib"
|
||||
FLUTTER_OUTPUT_DIR = "Release"
|
||||
FLUTTER_DESKTOP_FEATURES = "dart,rev-sqlite,openssl_vendored"
|
||||
|
||||
[tasks.setup-crate-type]
|
||||
private = true
|
||||
script = [
|
||||
|
||||
@@ -69,11 +69,12 @@ windows/flutter/dart_ffi/
|
||||
**/.sandbox
|
||||
**/.vscode/
|
||||
|
||||
*.env
|
||||
*.env.*
|
||||
.env
|
||||
.env.*
|
||||
|
||||
coverage/
|
||||
|
||||
**/failures/*.png
|
||||
|
||||
assets/translations/
|
||||
assets/flowy_icons/*
|
||||
@@ -4,8 +4,8 @@
|
||||
# This file should be version controlled.
|
||||
|
||||
version:
|
||||
revision: 135454af32477f815a7525073027a3ff9eff1bfd
|
||||
channel: stable
|
||||
revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66
|
||||
channel: unknown
|
||||
|
||||
project_type: app
|
||||
|
||||
@@ -13,11 +13,11 @@ project_type: app
|
||||
migration:
|
||||
platforms:
|
||||
- platform: root
|
||||
create_revision: 135454af32477f815a7525073027a3ff9eff1bfd
|
||||
base_revision: 135454af32477f815a7525073027a3ff9eff1bfd
|
||||
- platform: windows
|
||||
create_revision: 135454af32477f815a7525073027a3ff9eff1bfd
|
||||
base_revision: 135454af32477f815a7525073027a3ff9eff1bfd
|
||||
create_revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66
|
||||
base_revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66
|
||||
- platform: android
|
||||
create_revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66
|
||||
base_revision: 682aa387cfe4fbd71ccd5418b2c2a075729a1c66
|
||||
|
||||
# User provided section
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<h1 align="center" style="margin:0"> AppFlowy_Flutter</h1>
|
||||
<div align="center">
|
||||
<img src="https://img.shields.io/badge/Flutter-v3.10.1-blue"/>
|
||||
<img src="https://img.shields.io/badge/Rust-v1.65-orange"/>
|
||||
<img src="https://img.shields.io/badge/Flutter-v3.13.19-blue"/>
|
||||
<img src="https://img.shields.io/badge/Rust-v1.70-orange"/>
|
||||
</div>
|
||||
|
||||
> Documentation for Contributors
|
||||
@@ -13,11 +13,13 @@ This Repository contains the codebase for the frontend of the application, curre
|
||||
- Linux
|
||||
- macOS
|
||||
- Windows
|
||||
> We later expect to extend support to Android and iOS devices using Flutter.
|
||||
> We are actively working on support for Android & iOS!
|
||||
|
||||
_Additionally, we are working on a Web version built with Tauri!_
|
||||
|
||||
### Am I Eligible to Contribute?
|
||||
|
||||
Yes! You are eligible to contribute, check out the ways in which you can [contribute to AppFlowy](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/contributing-to-appflowy). Some of the ways in which you can contribute are:
|
||||
Yes! You are eligible to contribute, check out the ways in which you can [contribute to AppFlowy](https://docs.appflowy.io/docs/documentation/software-contributions/contributing-to-appflowy). Some of the ways in which you can contribute are:
|
||||
|
||||
- Non-Coding Contributions
|
||||
- Documentation
|
||||
@@ -26,27 +28,23 @@ Yes! You are eligible to contribute, check out the ways in which you can [contri
|
||||
- Improve Translations
|
||||
- Coding Contributions
|
||||
|
||||
To contribute to `AppFlowy_Flutter` codebase specifically (coding contribution) we suggest you to have basic knowledge of Flutter. In case you are new to Flutter, we may suggest you to learn the basics and then try to contribute, get started with Flutter [here](https://flutter.dev/docs/get-started/codelab).
|
||||
To contribute to `AppFlowy_Flutter` codebase specifically (coding contribution) we suggest you to have basic knowledge of Flutter. In case you are new to Flutter, we suggest you learn the basics, and then contribute afterwards. To get started with Flutter read [here](https://flutter.dev/docs/get-started/codelab).
|
||||
|
||||
### What OS Should I Use for Development?
|
||||
### What OS should I use for development?
|
||||
|
||||
We support all OS for Development i.e Linux, macOS and Windows. However, most of us promote macOS and Linux over Windows. We have detailed [docs](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/software-contributions/environment-setup) on How to Setup `AppFlowy_Flutter` in your local system in each OS.
|
||||
We support all OS for Development i.e. Linux, MacOS and Windows. However, most of us promote macOS and Linux over Windows. We have detailed [docs](https://docs.appflowy.io/docs/documentation/appflowy/from-source/environment-setup) on how to setup `AppFlowy_Flutter` on your local system respectively per operating system.
|
||||
|
||||
### Getting Started ❇
|
||||
|
||||
We have a detailed documentation, on how to [get started](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/contributing-to-appflowy) with the project, and make your first contribution. However, we do have some specific picks for you.
|
||||
We have detailed documentation on how to [get started](https://docs.appflowy.io/docs/documentation/software-contributions/contributing-to-appflowy) with the project, and make your first contribution. However, we do have some specific picks for you:
|
||||
|
||||
- [Code Architecture](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/architecture/frontend/frontend/codemap)
|
||||
- [Making Your First PR](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/software-contributions/submitting-code/submitting-your-first-pull-request)
|
||||
- [The Style Guide](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/software-contributions/submitting-code/style-guides)
|
||||
- [How to run/debug the application](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/software-contributions/launcher-and-tasks)
|
||||
- [Styleguide & Conventions](https://docs.appflowy.io/docs/documentation/software-contributions/conventions/naming-conventions)
|
||||
- [Making Your First PR](https://docs.appflowy.io/docs/documentation/software-contributions/submitting-code/submitting-your-first-pull-request)
|
||||
- [All AppFlowy Documentation](https://docs.appflowy.io/docs/documentation/appflowy) - Contribution guide, build and run, debugging, testing, localization, etc.
|
||||
|
||||
### Need Help?
|
||||
|
||||
- New to GitHub? Follow [these](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/software-contributions/submitting-code/setting-up-your-repositories) steps to get started
|
||||
- Stuck Somewhere? Join the [Discord](https://discord.gg/9Q2xaN37tV) Group and we are there to help you!
|
||||
|
||||
<!--
|
||||
## release check
|
||||
1. [entitlements](https://flutter.dev/desktop#setting-up-entitlements)
|
||||
2. [symbols stripped](https://flutter.dev/docs/development/platform-integration/c-interop) -->
|
||||
- New to GitHub? Follow [these](https://docs.appflowy.io/docs/documentation/software-contributions/submitting-code/setting-up-your-repositories) steps to get started
|
||||
- Stuck Somewhere? Join our [Discord](https://discord.gg/9Q2xaN37tV), we're there to help you!
|
||||
- Find out more about the [community initiatives](https://docs.appflowy.io/docs/appflowy/community).
|
||||
@@ -34,6 +34,13 @@ linter:
|
||||
- prefer_final_in_for_each
|
||||
- prefer_final_locals
|
||||
|
||||
- sized_box_for_whitespace
|
||||
- avoid_unnecessary_containers
|
||||
|
||||
- always_declare_return_types
|
||||
- unnecessary_raw_strings
|
||||
- use_decorated_box
|
||||
|
||||
# Additional information about this file can be found at
|
||||
# https://dart.dev/guides/language/analysis-options
|
||||
|
||||
|
||||
@@ -11,3 +11,5 @@ GeneratedPluginRegistrant.java
|
||||
key.properties
|
||||
**/*.keystore
|
||||
**/*.jks
|
||||
|
||||
.cxx
|
||||
@@ -25,8 +25,14 @@ apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
def keystoreProperties = new Properties()
|
||||
def keystorePropertiesFile = rootProject.file('key.properties')
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 31
|
||||
compileSdkVersion 34
|
||||
ndkVersion "24.0.8215888"
|
||||
|
||||
compileOptions {
|
||||
@@ -46,23 +52,41 @@ android {
|
||||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId "io.appflowy.appflowy"
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 31
|
||||
minSdkVersion 33
|
||||
targetSdkVersion 33
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
multiDexEnabled true
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_STL=c++_shared"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
release {
|
||||
keyAlias keystoreProperties['keyAlias']
|
||||
keyPassword keystoreProperties['keyPassword']
|
||||
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
|
||||
storePassword keystoreProperties['storePassword']
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
// TODO: Add your own signing config for the release build.
|
||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
|
||||
// use release instead when publishing the application to google play.
|
||||
// signingConfig signingConfigs.release
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
}
|
||||
|
||||
namespace 'io.appflowy.appflowy'
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path "src/main/CMakeLists.txt"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="io.appflowy.appflowy">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- Flutter needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
|
||||
@@ -1,42 +1,55 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="io.appflowy.appflowy">
|
||||
<application
|
||||
android:label="appflowy_flutter"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:name="${applicationName}">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||
the Android process has started. This theme is visible to the user
|
||||
while the Flutter UI initializes. After that, this theme continues
|
||||
to determine the Window background behind the Flutter UI. -->
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme"
|
||||
/>
|
||||
<!-- Displays an Android View that continues showing the launch screen
|
||||
Drawable until Flutter paints its first frame, then this splash
|
||||
screen fades out. A splash screen is useful to avoid any visual
|
||||
gap between the end of Android's launch screen and the painting of
|
||||
Flutter's first frame. -->
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.SplashScreenDrawable"
|
||||
android:resource="@drawable/launch_background"
|
||||
/>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
</application>
|
||||
</manifest>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<application android:label="AppFlowy" android:icon="@mipmap/ic_launcher"
|
||||
android:name="${applicationName}">
|
||||
<activity android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleInstance"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize">
|
||||
<!--
|
||||
Specifies an Android theme to apply to this Activity as soon as
|
||||
the Android process has started. This theme is visible to the user
|
||||
while the Flutter UI initializes. After that, this theme continues
|
||||
to determine the Window background behind the Flutter UI.
|
||||
-->
|
||||
<meta-data android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme" />
|
||||
<!--
|
||||
Displays an Android View that continues showing the launch screen
|
||||
Drawable until Flutter paints its first frame, then this splash
|
||||
screen fades out. A splash screen is useful to avoid any visual
|
||||
gap between the end of Android's launch screen and the painting of
|
||||
Flutter's first frame.
|
||||
-->
|
||||
<meta-data android:name="io.flutter.embedding.android.SplashScreenDrawable"
|
||||
android:resource="@drawable/launch_background" />
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="flutter_deeplinking_enabled" android:value="true" />
|
||||
<intent-filter android:autoVerify="true">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="http" />
|
||||
<data android:scheme="https" />
|
||||
<data android:scheme="appflowy-flutter" />
|
||||
<!-- <data android:host="login-callback" /> -->
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!--
|
||||
Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java
|
||||
-->
|
||||
<meta-data android:name="flutterEmbedding" android:value="2" />
|
||||
</application>
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.support.customtabs.action.CustomTabsService" />
|
||||
</intent>
|
||||
</queries>
|
||||
</manifest>
|
||||
@@ -0,0 +1,18 @@
|
||||
cmake_minimum_required(VERSION 3.10.0)
|
||||
|
||||
project(AppFlowy)
|
||||
|
||||
message(CONFIGURE_LOG "NDK PATH: ${ANDROID_NDK}")
|
||||
message(CONFIGURE_LOG "Copying libc++_shared.so")
|
||||
|
||||
# arm64-v8a
|
||||
file(COPY
|
||||
${ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_shared.so
|
||||
DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/jniLibs/arm64-v8a
|
||||
)
|
||||
|
||||
# x86_64
|
||||
file(COPY
|
||||
${ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libs/x86_64/libc++_shared.so
|
||||
DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/jniLibs/x86_64
|
||||
)
|
||||
@@ -0,0 +1,18 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int64_t init_sdk(char *data);
|
||||
|
||||
void async_event(int64_t port, const uint8_t *input, uintptr_t len);
|
||||
|
||||
const uint8_t *sync_event(const uint8_t *input, uintptr_t len);
|
||||
|
||||
int32_t set_stream_port(int64_t port);
|
||||
|
||||
void link_me_please(void);
|
||||
|
||||
void backend_log(int64_t level, const char *data);
|
||||
|
||||
void set_env(const char *data);
|
||||
|
Before Width: | Height: | Size: 544 B After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 442 B After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 721 B After Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 17 KiB |
@@ -1,5 +1,4 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="io.appflowy.appflowy">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- Flutter needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.6.10'
|
||||
ext.kotlin_version = '1.8.0'
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.1.0'
|
||||
classpath 'com.android.tools.build:gradle:7.4.2'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,6 @@ subprojects {
|
||||
project.evaluationDependsOn(':app')
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
tasks.register("clean", Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
@@ -2,3 +2,4 @@ org.gradle.jvmargs=-Xmx1536M
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
org.gradle.caching=true
|
||||
android.suppressUnsupportedCompileSdk=33
|
||||
@@ -1,5 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
Before Width: | Height: | Size: 30 KiB |
@@ -1,10 +0,0 @@
|
||||
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_10_2941)">
|
||||
<path d="M17.9706 5.70199L17.9706 5.702L17.9712 5.70405L20.4218 13.6624C20.4393 13.7435 20.4508 13.8258 20.4561 13.9086V19.3106C20.4561 19.7769 20.078 20.1549 19.6117 20.1548H3.40062C2.93431 20.1549 2.55625 19.7769 2.55625 19.3106V13.9086C2.56155 13.8257 2.57301 13.7433 2.59054 13.6622L4.97263 5.70366C5.26597 4.72587 6.16595 4.05625 7.1868 4.05625L15.8285 4.05625C16.8329 4.05625 17.7119 4.7315 17.9706 5.70199ZM4.55716 12.99L4.53544 13.0624H4.61104H8.80431C9.02825 13.0624 9.24302 13.1514 9.40137 13.3097C9.55971 13.4681 9.64867 13.6828 9.64867 13.9068V14.8074V14.8636H9.70492H13.3074H13.3636V14.8074V13.9068C13.3636 13.6828 13.4526 13.4681 13.6109 13.3097C13.7693 13.1514 13.9841 13.0624 14.208 13.0624H18.4013H18.4769L18.4551 12.99L16.5342 6.5868C16.3843 6.08715 15.9244 5.74498 15.4028 5.74498H7.60955C7.0879 5.74498 6.62802 6.08715 6.47812 6.5868L4.55716 12.99ZM15.1086 14.7511H15.0524V14.8074V15.708C15.0524 15.8189 15.0305 15.9287 14.9881 16.0311C14.9457 16.1336 14.8835 16.2267 14.8051 16.3051C14.7267 16.3835 14.6336 16.4457 14.5311 16.4881C14.4287 16.5305 14.3189 16.5524 14.208 16.5524H8.80431C8.69343 16.5524 8.58363 16.5305 8.48118 16.4881C8.37874 16.4457 8.28566 16.3835 8.20725 16.3051C8.12885 16.2267 8.06665 16.1336 8.02422 16.0311C7.98178 15.9287 7.95994 15.8189 7.95994 15.708V14.8074V14.7511H7.90369H4.52623C4.3709 14.7511 4.24498 14.8771 4.24498 15.0324V18.1849C4.24498 18.3402 4.3709 18.4661 4.52623 18.4661H18.4861C18.6414 18.4661 18.7673 18.3402 18.7673 18.1849V15.0324C18.7673 14.8771 18.6414 14.7511 18.4861 14.7511H15.1086ZM8.80435 10.2481C8.58041 10.2481 8.36564 10.1591 8.20729 10.0007C8.04895 9.8424 7.95999 9.62763 7.95999 9.40369C7.95999 9.17975 8.04895 8.96498 8.20729 8.80663C8.36564 8.64829 8.58041 8.55933 8.80435 8.55933H14.208C14.432 8.55933 14.6468 8.64829 14.8051 8.80663C14.9635 8.96498 15.0524 9.17975 15.0524 9.40369C15.0524 9.62763 14.9635 9.8424 14.8051 10.0007C14.6468 10.1591 14.432 10.2481 14.208 10.2481H8.80435Z" fill="#333333" stroke="white" stroke-width="0.1125"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_10_2941">
|
||||
<rect width="18" height="16.2111" fill="white" transform="translate(2.5 4)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.2 KiB |
@@ -1,5 +0,0 @@
|
||||
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8 14.0039C11.3137 14.0039 14 11.3176 14 8.00391C14 4.6902 11.3137 2.00391 8 2.00391C4.68629 2.00391 2 4.6902 2 8.00391C2 11.3176 4.68629 14.0039 8 14.0039Z" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<rect x="7.5" y="7.00391" width="1" height="4" rx="0.5" fill="#333333"/>
|
||||
<rect x="7.5" y="5.00391" width="1" height="1" rx="0.5" fill="#333333"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 482 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.7" d="M14.1579 9L14.6673 8.57546C14.5413 8.42426 14.3547 8.33684 14.1579 8.33684V9ZM16 11.2105L15.4905 11.6351C15.6165 11.7863 15.8032 11.8737 16 11.8737V11.2105ZM9.66316 12.6843C9.66316 12.318 9.36625 12.0211 9 12.0211C8.63375 12.0211 8.33684 12.318 8.33684 12.6843H9.66316ZM8.33684 17.1053C8.33684 17.4716 8.63375 17.7685 9 17.7685C9.36625 17.7685 9.66316 17.4716 9.66316 17.1053H8.33684ZM23.6632 12.6843C23.6632 12.318 23.3663 12.0211 23 12.0211C22.6337 12.0211 22.3368 12.318 22.3368 12.6843H23.6632ZM22.3368 17.1053C22.3368 17.4716 22.6337 17.7685 23 17.7685C23.3663 17.7685 23.6632 17.4716 23.6632 17.1053H22.3368ZM9.66316 9.73684C9.66316 9.69614 9.69614 9.66316 9.73684 9.66316V8.33684C8.96364 8.33684 8.33684 8.96364 8.33684 9.73684H9.66316ZM9.73684 9.66316H14.1579V8.33684H9.73684V9.66316ZM13.6484 9.42454L15.4905 11.6351L16.5094 10.786L14.6673 8.57546L13.6484 9.42454ZM16 11.8737H22.2631V10.5474H16V11.8737ZM22.2631 11.8737C22.3038 11.8737 22.3368 11.9067 22.3368 11.9474H23.6631C23.6631 11.1742 23.0363 10.5474 22.2631 10.5474V11.8737ZM22.3368 11.9474V21.5263H23.6631V11.9474H22.3368ZM22.3368 21.5263C22.3368 21.567 22.3038 21.6 22.2631 21.6V22.9263C23.0363 22.9263 23.6631 22.2995 23.6631 21.5263H22.3368ZM22.2631 21.6H9.73684V22.9263H22.2631V21.6ZM9.73684 21.6C9.69614 21.6 9.66316 21.567 9.66316 21.5263H8.33684C8.33684 22.2995 8.96365 22.9263 9.73684 22.9263V21.6ZM9.66316 21.5263V9.73684H8.33684V21.5263H9.66316ZM22.9999 14.2317H9V15.558H22.9999V14.2317ZM8.33684 12.6843V17.1053H9.66316V12.6843H8.33684ZM22.3368 12.6843V17.1053H23.6632V12.6843H22.3368Z" fill="#333333"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.7 KiB |
@@ -1,4 +0,0 @@
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M21.7874 10.1975C22.48 10.8859 23.0235 11.6885 23.4041 12.5811C23.7967 13.5077 24 14.4863 24 15.499C24 16.5117 23.7987 17.4943 23.4061 18.4189C23.0256 19.3115 22.482 20.1141 21.7894 20.8025C21.0968 21.491 20.2895 22.0314 19.3915 22.4096C18.4614 22.8019 17.4729 23 16.4541 23C15.4354 23 14.4469 22.7999 13.5167 22.4096C12.6188 22.0314 11.8114 21.491 11.1189 20.8025C10.8833 20.5684 10.8833 20.1881 11.1189 19.954C11.3544 19.7198 11.7369 19.7198 11.9725 19.954C13.1684 21.1448 14.7589 21.7992 16.4521 21.7992C18.1453 21.7992 19.7338 21.1428 20.9317 19.954C22.1296 18.7652 22.792 17.1801 22.792 15.499C22.792 13.8179 22.1316 12.2368 20.9357 11.046C19.7398 9.85524 18.1493 9.2008 16.4561 9.2008C15.6971 9.2008 14.9562 9.33089 14.2516 9.59106C13.5711 9.84323 12.9429 10.2055 12.3852 10.6718C11.6041 11.3242 10.996 12.1508 10.6075 13.0734L11.2618 12.7231C11.5557 12.565 11.9222 12.6751 12.0792 12.9673C12.2383 13.2595 12.1275 13.6237 11.8336 13.7799L9.92094 14.8005C9.92094 14.8025 9.91892 14.8025 9.91892 14.8025C9.82832 14.8506 9.72967 14.8746 9.63303 14.8746C9.44378 14.8746 9.26258 14.7885 9.14581 14.6304C9.14455 14.6267 9.14249 14.6237 9.14064 14.621C9.13954 14.6194 9.13851 14.6179 9.13776 14.6164C9.13575 14.6124 9.13323 14.6089 9.13071 14.6054C9.1282 14.6019 9.12568 14.5984 9.12367 14.5944C9.11561 14.5824 9.10756 14.5704 9.10152 14.5584L8.07272 12.6551C7.91367 12.3629 8.0244 11.9987 8.31834 11.8426C8.61228 11.6845 8.97871 11.7945 9.13575 12.0867L9.45989 12.6871C9.91892 11.5584 10.6558 10.5457 11.6061 9.75317C12.2705 9.1988 13.0174 8.76451 13.8288 8.46631C14.6663 8.1561 15.5501 8 16.4521 8C17.4708 8 18.4594 8.20013 19.3895 8.59039C20.2875 8.96865 21.0948 9.50901 21.7874 10.1975ZM15.52 12.1206C15.52 11.7884 15.7898 11.5202 16.124 11.5202C16.4582 11.5202 16.728 11.7884 16.728 12.1206V15.2747H19.8244C20.1587 15.2747 20.4284 15.5429 20.4284 15.8751C20.4284 16.2073 20.1587 16.4755 19.8244 16.4755H16.1481C15.8441 16.4755 15.5925 16.2514 15.5502 15.9612C15.5301 15.9031 15.52 15.8411 15.52 15.7751V12.1206Z" fill="#333333" fill-opacity="0.7"/>
|
||||
<path d="M23.4041 12.5811L23.4435 12.5643L23.4435 12.5642L23.4041 12.5811ZM21.7874 10.1975L21.7572 10.2279L21.7874 10.1975ZM23.4061 18.4189L23.4455 18.4358L23.4455 18.4357L23.4061 18.4189ZM19.3915 22.4096L19.3749 22.3701L19.3749 22.3701L19.3915 22.4096ZM13.5167 22.4096L13.5001 22.4491L13.5001 22.4491L13.5167 22.4096ZM11.1189 20.8025L11.1491 20.7721L11.1189 20.8025ZM11.1189 19.954L11.1491 19.9844L11.1189 19.954ZM11.9725 19.954L12.0027 19.9236L12.0027 19.9236L11.9725 19.954ZM20.9317 19.954L20.9619 19.9844L20.9317 19.954ZM20.9357 11.046L20.9055 11.0764L20.9357 11.046ZM14.2516 9.59106L14.2367 9.55086L14.2367 9.55087L14.2516 9.59106ZM12.3852 10.6718L12.4127 10.7047L12.4127 10.7047L12.3852 10.6718ZM10.6075 13.0734L10.568 13.0567L10.521 13.1683L10.6277 13.1112L10.6075 13.0734ZM11.2618 12.7231L11.282 12.7609L11.2821 12.7609L11.2618 12.7231ZM12.0792 12.9673L12.0415 12.9876L12.0416 12.9878L12.0792 12.9673ZM11.8336 13.7799L11.8135 13.742L11.8134 13.742L11.8336 13.7799ZM9.92094 14.8005L9.90076 14.7627L9.87808 14.7748V14.8005H9.92094ZM9.91892 14.8025L9.9189 14.7597L9.90825 14.7597L9.89885 14.7647L9.91892 14.8025ZM9.14581 14.6304L9.10311 14.6447L9.11134 14.6559L9.14581 14.6304ZM9.14064 14.621L9.10537 14.6453L9.10537 14.6453L9.14064 14.621ZM9.13776 14.6164L9.17605 14.5972L9.17604 14.5972L9.13776 14.6164ZM9.13071 14.6054L9.09591 14.6304L9.09591 14.6304L9.13071 14.6054ZM9.12367 14.5944L9.16225 14.575L9.15926 14.5705L9.12367 14.5944ZM9.10152 14.5584L9.13982 14.5391L9.13922 14.538L9.10152 14.5584ZM8.07272 12.6551L8.11042 12.6347L8.11036 12.6346L8.07272 12.6551ZM8.31834 11.8426L8.33844 11.8804L8.33864 11.8803L8.31834 11.8426ZM9.13575 12.0867L9.09799 12.107L9.09803 12.1071L9.13575 12.0867ZM9.45989 12.6871L9.42218 12.7075L9.46535 12.7875L9.49959 12.7033L9.45989 12.6871ZM11.6061 9.75317L11.6335 9.78608L11.6335 9.78608L11.6061 9.75317ZM13.8288 8.46631L13.8436 8.50654L13.8437 8.5065L13.8288 8.46631ZM19.3895 8.59039L19.4062 8.5509L19.4061 8.55087L19.3895 8.59039ZM16.728 15.2747H16.6851V15.3176H16.728V15.2747ZM15.5502 15.9612L15.5934 15.9549L15.5907 15.9471L15.5502 15.9612ZM23.4435 12.5642C23.0608 11.6666 22.5141 10.8594 21.8176 10.1671L21.7572 10.2279C22.4458 10.9124 22.9863 11.7104 23.3646 12.5979L23.4435 12.5642ZM24.0429 15.499C24.0429 14.4805 23.8383 13.4961 23.4435 12.5643L23.3646 12.5978C23.755 13.5192 23.9571 14.4922 23.9571 15.499H24.0429ZM23.4455 18.4357C23.8404 17.5058 24.0429 16.5174 24.0429 15.499H23.9571C23.9571 16.5059 23.757 17.4829 23.3666 18.4022L23.4455 18.4357ZM21.8196 20.8329C22.5161 20.1406 23.0628 19.3334 23.4455 18.4358L23.3667 18.4021C22.9883 19.2896 22.4478 20.0876 21.7592 20.7721L21.8196 20.8329ZM19.4082 22.4491C20.3112 22.0687 21.1231 21.5253 21.8196 20.8329L21.7592 20.7721C21.0705 21.4567 20.2678 21.994 19.3749 22.3701L19.4082 22.4491ZM16.4541 23.0429C17.4785 23.0429 18.4727 22.8436 19.4082 22.4491L19.3749 22.3701C18.4501 22.7601 17.4672 22.9571 16.4541 22.9571V23.0429ZM13.5001 22.4491C14.4355 22.8416 15.4297 23.0429 16.4541 23.0429V22.9571C15.4411 22.9571 14.4582 22.7581 13.5333 22.3701L13.5001 22.4491ZM11.0886 20.8329C11.7851 21.5253 12.5971 22.0687 13.5001 22.4491L13.5333 22.3701C12.6405 21.994 11.8377 21.4567 11.1491 20.7721L11.0886 20.8329ZM11.0886 19.9236C10.8362 20.1745 10.8362 20.582 11.0886 20.8329L11.1491 20.7721C10.9304 20.5547 10.9304 20.2018 11.1491 19.9844L11.0886 19.9236ZM12.0027 19.9236C11.7504 19.6728 11.3409 19.6728 11.0886 19.9236L11.1491 19.9844C11.3679 19.7668 11.7234 19.7668 11.9423 19.9844L12.0027 19.9236ZM16.4521 21.7563C14.7702 21.7563 13.1906 21.1064 12.0027 19.9236L11.9423 19.9843C13.1462 21.1832 14.7476 21.8421 16.4521 21.8421V21.7563ZM20.9015 19.9235C19.7116 21.1044 18.134 21.7563 16.4521 21.7563V21.8421C18.1566 21.8421 19.756 21.1811 20.9619 19.9844L20.9015 19.9235ZM22.7492 15.499C22.7492 17.1686 22.0914 18.7428 20.9015 19.9235L20.9619 19.9844C22.1679 18.7876 22.8349 17.1916 22.8349 15.499H22.7492ZM20.9055 11.0764C22.0934 12.2592 22.7492 13.8294 22.7492 15.499H22.8349C22.8349 13.8064 22.1699 12.2144 20.966 11.0157L20.9055 11.0764ZM16.4561 9.24366C18.1381 9.24366 19.7177 9.89365 20.9055 11.0764L20.966 11.0157C19.762 9.81683 18.1606 9.15794 16.4561 9.15794V9.24366ZM14.2664 9.63127C14.9662 9.37289 15.7021 9.24366 16.4561 9.24366V9.15794C15.6922 9.15794 14.9462 9.28889 14.2367 9.55086L14.2664 9.63127ZM12.4127 10.7047C12.9666 10.2415 13.5905 9.88174 14.2665 9.63125L14.2367 9.55087C13.5517 9.80472 12.9192 10.1694 12.3577 10.6389L12.4127 10.7047ZM10.647 13.09C11.0329 12.1737 11.6368 11.3527 12.4127 10.7047L12.3578 10.6389C11.5713 11.2957 10.9592 12.1278 10.568 13.0567L10.647 13.09ZM11.2416 12.6854L10.5872 13.0356L10.6277 13.1112L11.282 12.7609L11.2416 12.6854ZM12.117 12.947C11.9487 12.6339 11.5562 12.5161 11.2415 12.6854L11.2821 12.7609C11.5553 12.614 11.8957 12.7164 12.0415 12.9876L12.117 12.947ZM11.8537 13.8177C12.1685 13.6505 12.2874 13.2601 12.1168 12.9468L12.0416 12.9878C12.1891 13.2589 12.0865 13.597 11.8135 13.742L11.8537 13.8177ZM9.94111 14.8383L11.8538 13.8177L11.8134 13.74Line truncated
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 11 KiB |
@@ -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="M8 3L9.3905 5.96215L12.5 6.44006L10.25 8.74448L10.781 12L8 10.4621L5.219 12L5.75 8.74448L3.5 6.44006L6.6095 5.96215L8 3Z" fill="#FFD667" stroke="#FFD667" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 315 B |
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="Calendar / Calendar_Days">
|
||||
<path id="Vector" d="M8 4H7.2002C6.08009 4 5.51962 4 5.0918 4.21799C4.71547 4.40973 4.40973 4.71547 4.21799 5.0918C4 5.51962 4 6.08009 4 7.2002V8M8 4H16M8 4V2M16 4H16.8002C17.9203 4 18.4796 4 18.9074 4.21799C19.2837 4.40973 19.5905 4.71547 19.7822 5.0918C20 5.5192 20 6.07899 20 7.19691V8M16 4V2M4 8V16.8002C4 17.9203 4 18.4801 4.21799 18.9079C4.40973 19.2842 4.71547 19.5905 5.0918 19.7822C5.5192 20 6.07899 20 7.19691 20H16.8031C17.921 20 18.48 20 18.9074 19.7822C19.2837 19.5905 19.5905 19.2842 19.7822 18.9079C20 18.4805 20 17.9215 20 16.8036V8M4 8H20M16 16H16.002L16.002 16.002L16 16.002V16ZM12 16H12.002L12.002 16.002L12 16.002V16ZM8 16H8.002L8.00195 16.002L8 16.002V16ZM16.002 12V12.002L16 12.002V12H16.002ZM12 12H12.002L12.002 12.002L12 12.002V12ZM8 12H8.002L8.00195 12.002L8 12.002V12Z" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1,29 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
|
||||
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M2990 5100 c-19 -10 -382 -366 -806 -792 l-771 -773 -42 -85 c-125
|
||||
-256 -84 -501 120 -714 47 -50 91 -101 98 -113 14 -27 14 -116 0 -168 -57
|
||||
-207 -310 -495 -535 -606 -73 -37 -92 -42 -190 -50 -60 -4 -145 -18 -189 -29
|
||||
-312 -80 -560 -328 -646 -645 -32 -116 -32 -336 -1 -450 88 -318 330 -560 647
|
||||
-646 115 -32 335 -32 450 0 263 71 474 247 591 494 45 95 71 203 83 337 7 90
|
||||
15 122 40 176 149 318 583 627 777 554 15 -6 68 -50 119 -98 214 -205 459
|
||||
-246 715 -121 85 42 85 42 849 803 420 418 776 781 792 805 34 53 37 97 10
|
||||
149 -24 46 -1934 1954 -1978 1976 -42 21 -90 20 -133 -4z m920 -1195 l845
|
||||
-845 -318 -317 -317 -318 -847 847 -848 848 315 315 c173 173 317 315 320 315
|
||||
3 0 385 -380 850 -845z m-282 -1972 c-320 -320 -330 -327 -458 -328 -100 0
|
||||
-145 23 -264 135 -52 49 -114 99 -137 111 -242 123 -589 11 -902 -291 -135
|
||||
-130 -224 -245 -287 -375 -54 -110 -80 -200 -80 -285 -2 -277 -206 -528 -475
|
||||
-585 -203 -43 -395 15 -545 164 -190 188 -233 466 -108 704 42 81 164 203 245
|
||||
245 77 41 198 72 277 72 326 1 780 374 949 780 74 178 76 355 5 494 -11 21
|
||||
-59 80 -108 132 -110 117 -135 164 -135 259 0 131 3 136 324 458 l286 287 847
|
||||
-847 848 -848 -282 -282z"/>
|
||||
<path d="M828 1029 c-43 -22 -78 -81 -78 -129 0 -76 74 -150 150 -150 17 0 49
|
||||
9 70 20 45 23 80 80 80 130 0 50 -35 107 -80 130 -49 25 -94 25 -142 -1z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.7 KiB |
@@ -1,6 +0,0 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3 4.40039H4.11111H13" stroke="#BBC3CD" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M5.77799 4.4V3.2C5.77799 2.88174 5.89506 2.57652 6.10343 2.35147C6.31181 2.12643 6.59442 2 6.88911 2H9.11133C9.40601 2 9.68863 2.12643 9.897 2.35147C10.1054 2.57652 10.2224 2.88174 10.2224 3.2V4.4M11.8891 4.4V12.8C11.8891 13.1183 11.772 13.4235 11.5637 13.6485C11.3553 13.8736 11.0727 14 10.778 14H5.22244C4.92775 14 4.64514 13.8736 4.43676 13.6485C4.22839 13.4235 4.11133 13.1183 4.11133 12.8V4.4H11.8891Z" stroke="#BBC3CD" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6.88867 7.40039V11.0004" stroke="#BBC3CD" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M9.11133 7.40039V11.0004" stroke="#BBC3CD" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 886 B |
@@ -1,4 +0,0 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.5 3H11.5C11.8315 3 12.1495 3.12877 12.3839 3.35798C12.6183 3.58719 12.75 3.89807 12.75 4.22222V12.7778C12.75 13.1019 12.6183 13.4128 12.3839 13.642C12.1495 13.8712 11.8315 14 11.5 14H4.5C4.16848 14 3.85054 13.8712 3.61612 13.642C3.3817 13.4128 3.25 13.1019 3.25 12.7778V4.22222C3.25 3.89807 3.3817 3.58719 3.61612 3.35798C3.85054 3.12877 4.16848 3 4.5 3H5.5" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M9.5 2H6.5C6.22386 2 6 2.22386 6 2.5V3.5C6 3.77614 6.22386 4 6.5 4H9.5C9.77614 4 10 3.77614 10 3.5V2.5C10 2.22386 9.77614 2 9.5 2Z" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 748 B |
@@ -1,4 +0,0 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.974 6.33301H7.35865C6.7922 6.33301 6.33301 6.7922 6.33301 7.35865V11.974C6.33301 12.5405 6.7922 12.9997 7.35865 12.9997H11.974C12.5405 12.9997 12.9997 12.5405 12.9997 11.974V7.35865C12.9997 6.7922 12.5405 6.33301 11.974 6.33301Z" stroke="#BBC3CD" 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="#BBC3CD" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 785 B |
@@ -1,4 +0,0 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="2" y="2" width="12" height="12" rx="4" fill="#00BCF0"/>
|
||||
<path d="M6 8L7.61538 9.5L10.5 6.5" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 268 B |
@@ -1,6 +0,0 @@
|
||||
<?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>
|
||||
|
Before Width: | Height: | Size: 1.6 KiB |
@@ -1,6 +0,0 @@
|
||||
<?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>
|
||||
|
Before Width: | Height: | Size: 2.8 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30" style="width: 16px; height: 16px; display: block; fill: inherit; flex-shrink: 0; backface-visibility: hidden;" width="30" height="30" ><path d="M6.04883 27.3232C7.24219 27.3232 7.86426 26.4854 8.20703 25.3936L13.9834 6.79492H27.5039C28.2275 6.79492 28.7227 6.35059 28.7227 5.65234C28.7227 4.97949 28.2275 4.53516 27.5039 4.53516H13.958C12.6631 4.53516 12.0791 5.01758 11.7363 6.13477L6.18848 24.3525H5.97266L3.58594 15.9355C3.38281 15.2373 3.00195 14.9072 2.40527 14.9072C1.73242 14.9072 1.2373 15.3896 1.2373 16.0117C1.2373 16.2656 1.30078 16.4941 1.35156 16.6846L4.04297 25.5332C4.36035 26.5615 4.93164 27.3232 6.04883 27.3232ZM16.3955 24.7334C16.8652 24.7334 17.1064 24.5684 17.4619 24.0732L20.4707 19.8203H20.5215L23.5049 24.0732C23.873 24.5684 24.1143 24.7334 24.5713 24.7334C25.2061 24.7334 25.6758 24.3018 25.6758 23.7051C25.6758 23.4258 25.6123 23.1973 25.4219 22.9561L21.9307 18.208L25.4473 13.4346C25.6377 13.168 25.7139 12.9395 25.7139 12.6855C25.7139 12.127 25.2568 11.6953 24.6475 11.6953C24.2031 11.6953 23.9365 11.8477 23.6064 12.3174L20.7246 16.5957H20.6611L17.6904 12.3047C17.373 11.8477 17.0938 11.6953 16.624 11.6953C16.0146 11.6953 15.5068 12.165 15.5068 12.7363C15.5068 13.0537 15.583 13.2568 15.8115 13.5488L19.1504 18.1445L15.6084 23.0322C15.418 23.2861 15.3672 23.4639 15.3672 23.7559C15.3672 24.3018 15.8115 24.7334 16.3955 24.7334Z" fill="#2F3030"></path></svg>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
@@ -1,4 +0,0 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9 2.5V6C9 6.55228 9.44772 7 10 7H12" stroke="#333333"/>
|
||||
<path d="M3.5 3.5C3.5 2.94771 3.94772 2.5 4.5 2.5H8H8.5C9.12951 2.5 9.72229 2.79639 10.1 3.3L12.1 5.96667C12.3596 6.31286 12.5 6.73393 12.5 7.16667V8V12.5C12.5 13.0523 12.0523 13.5 11.5 13.5H4.5C3.94772 13.5 3.5 13.0523 3.5 12.5V3.5Z" stroke="#333333"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 423 B |
|
Before Width: | Height: | Size: 18 KiB |
@@ -1,4 +0,0 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9 2.5V6C9 6.55228 9.44772 7 10 7H12" stroke="#333333"/>
|
||||
<path d="M3.5 3.5C3.5 2.94771 3.94772 2.5 4.5 2.5H8H8.5C9.12951 2.5 9.72229 2.79639 10.1 3.3L12.1 5.96667C12.3596 6.31286 12.5 6.73393 12.5 7.16667V8V12.5C12.5 13.0523 12.0523 13.5 11.5 13.5H4.5C3.94772 13.5 3.5 13.0523 3.5 12.5V3.5Z" stroke="#333333"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 423 B |
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3.5 15V6.9C3.5 6.05992 3.5 5.63988 3.66349 5.31901C3.8073 5.03677 4.03677 4.8073 4.31901 4.66349C4.63988 4.5 5.05992 4.5 5.9 4.5H8.47237C8.84808 4.5 9.03594 4.5 9.20646 4.55179C9.35741 4.59763 9.49785 4.6728 9.61972 4.77298C9.75739 4.88614 9.86159 5.04245 10.07 5.35507L10.93 6.64533C11.1384 6.95795 11.2426 7.11426 11.3803 7.22742C11.5022 7.3276 11.6426 7.40277 11.7935 7.44861C11.9641 7.5004 12.1519 7.5004 12.5276 7.5004H16.5004C16.965 7.5004 17.1973 7.5004 17.3879 7.55143C17.9058 7.69008 18.3103 8.09459 18.449 8.61248C18.5 8.80308 18.5 9.03539 18.5 9.5V9.5M10.5 13.5H16.5" stroke="#222222" stroke-linecap="round"/>
|
||||
<path d="M4.5 18.5L16.7701 18.5004C17.3922 18.5004 17.7032 18.5004 17.9679 18.3963C18.2016 18.3044 18.4084 18.1553 18.5695 17.9626C18.752 17.7445 18.8503 17.4494 19.047 16.8593L20.4471 12.6592C20.8026 11.5927 20.9803 11.0595 20.8737 10.635C20.7804 10.2635 20.5485 9.94171 20.2255 9.7357C19.8566 9.50035 19.2945 9.50033 18.1703 9.5003L10.2299 9.50005C9.60784 9.50003 9.29681 9.50002 9.03216 9.60411C8.79846 9.69601 8.59157 9.84513 8.43047 10.0378C8.24804 10.2559 8.14968 10.551 7.95298 11.1411L5.7649 17.7057C5.60671 18.1803 5.16255 18.5004 4.66227 18.5004V18.5004C4.02037 18.5004 3.5 17.98 3.5 17.3381V14.5" stroke="#222222"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
@@ -1,3 +0,0 @@
|
||||
<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>
|
||||
|
Before Width: | Height: | Size: 198 B |
@@ -1,4 +0,0 @@
|
||||
<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>
|
||||
|
Before Width: | Height: | Size: 194 B |
@@ -1,4 +0,0 @@
|
||||
<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>
|
||||
|
Before Width: | Height: | Size: 790 B |
@@ -1,6 +0,0 @@
|
||||
<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>
|
||||
|
Before Width: | Height: | Size: 449 B |
@@ -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="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>
|
||||
|
Before Width: | Height: | Size: 814 B |
@@ -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="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>
|
||||
|
Before Width: | Height: | Size: 641 B |
@@ -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.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>
|
||||
|
Before Width: | Height: | Size: 404 B |
@@ -1,4 +0,0 @@
|
||||
<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>
|
||||
|
Before Width: | Height: | Size: 1.6 KiB |
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg fill="#000000" width="800px" height="800px" viewBox="-0.02 0 122.88 122.88" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="enable-background:new 0 0 122.84 122.88" xml:space="preserve">
|
||||
|
||||
<g>
|
||||
|
||||
<path d="M81.54,4.71c0-2.62,2.58-4.71,5.77-4.71c3.2,0,5.77,2.13,5.77,4.71V25.4c0,2.62-2.58,4.71-5.77,4.71 c-3.2,0-5.77-2.13-5.77-4.71V4.71L81.54,4.71z M20.4,89.87l7.55-0.47c0.16,1.22,0.5,2.16,1,2.79c0.82,1.04,1.99,1.56,3.51,1.56 c1.13,0,2.01-0.26,2.62-0.8C35.69,92.41,36,91.8,36,91.1c0-0.66-0.29-1.26-0.87-1.79c-0.58-0.53-1.93-1.02-4.06-1.49 c-3.49-0.78-5.96-1.82-7.45-3.12c-1.5-1.29-2.25-2.95-2.25-4.96c0-1.32,0.38-2.56,1.15-3.74c0.77-1.18,1.92-2.1,3.46-2.77 c1.54-0.67,3.65-1.01,6.32-1.01c3.29,0,5.79,0.61,7.52,1.84c1.72,1.22,2.75,3.17,3.08,5.84l-7.47,0.44 c-0.2-1.17-0.62-2.02-1.25-2.55c-0.64-0.53-1.52-0.8-2.64-0.8c-0.92,0-1.62,0.2-2.09,0.59c-0.47,0.39-0.7,0.87-0.7,1.43 c0,0.41,0.19,0.77,0.57,1.1c0.37,0.34,1.25,0.65,2.65,0.95c3.47,0.75,5.96,1.51,7.46,2.28c1.5,0.77,2.6,1.71,3.28,2.85 c0.68,1.13,1.02,2.4,1.02,3.81c0,1.65-0.46,3.17-1.37,4.56c-0.92,1.39-2.19,2.45-3.83,3.17c-1.64,0.72-3.7,1.08-6.19,1.08 c-4.37,0-7.4-0.84-9.09-2.53C21.58,94.6,20.62,92.46,20.4,89.87L20.4,89.87z M64.53,72.65h7.94v15.33c0,1.52-0.24,2.95-0.71,4.3 c-0.47,1.35-1.22,2.53-2.23,3.55c-1.01,1.01-2.07,1.72-3.18,2.13c-1.54,0.57-3.4,0.86-5.56,0.86c-1.25,0-2.62-0.09-4.1-0.26 c-1.48-0.17-2.72-0.52-3.71-1.04c-0.99-0.52-1.9-1.26-2.72-2.22c-0.83-0.96-1.39-1.95-1.69-2.96c-0.49-1.64-0.74-3.08-0.74-4.35 V72.65h7.94v15.69c0,1.4,0.39,2.5,1.16,3.28c0.78,0.79,1.86,1.19,3.23,1.19c1.36,0,2.43-0.39,3.21-1.17 c0.77-0.77,1.16-1.87,1.16-3.3V72.65L64.53,72.65z M77.85,72.65h7.42l9.65,14.21V72.65h7.51v25.73h-7.51l-9.59-14.13v14.13h-7.47 V72.65L77.85,72.65z M29.53,4.71c0-2.62,2.58-4.71,5.77-4.71c3.2,0,5.77,2.13,5.77,4.71V25.4c0,2.62-2.58,4.71-5.77,4.71 c-3.2,0-5.77-2.13-5.77-4.71V4.71L29.53,4.71z M7.56,44.09h107.62V22.66c0-0.8-0.31-1.55-0.84-2.04c-0.53-0.53-1.24-0.84-2.04-0.84 h-9.31c-1.78,0-3.2-2.63-3.2-4.41c0-1.78,1.42-3.2,3.2-3.2h10.53c2.58,0,4.88,1.07,6.57,2.75c1.69,1.69,2.75,4.04,2.75,6.57v92.06 c0,2.58-1.07,4.88-2.75,6.57c-1.69,1.69-4.04,2.75-6.57,2.75H9.33c-2.58,0-4.88-1.07-6.57-2.75C1.07,118.44,0,116.08,0,113.55 V21.49c0-2.58,1.07-4.88,2.75-6.57c1.69-1.69,4.04-2.75,6.57-2.75h11.28c1.78,0,3.2,1.42,3.2,3.2s-1.42,4.41-3.2,4.41H10.54 c-0.8,0-1.55,0.31-2.09,0.84c-0.53,0.53-0.84,1.24-0.84,2.09v21.43L7.56,44.09L7.56,44.09z M115.19,52.9H7.56v59.4 c0,0.8,0.31,1.55,0.84,2.09c0.53,0.53,1.24,0.84,2.09,0.84h101.76c0.8,0,1.55-0.31,2.09-0.84c0.53-0.53,0.84-1.24,0.84-2.09V52.9 L115.19,52.9z M50.36,19.73c-1.78,0-3.2-2.63-3.2-4.41c0-1.78,1.42-3.2,3.2-3.2h21.49c1.78,0,3.2,1.42,3.2,3.2 c0,1.78-1.42,4.41-3.2,4.41H50.36L50.36,19.73z"/>
|
||||
|
||||
</g>
|
||||
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.8 KiB |
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3 6C3 3.79086 4.79086 2 7 2H17C19.2091 2 21 3.79086 21 6C21 8.20914 19.2091 10 17 10H7C4.79086 10 3 8.20914 3 6Z" stroke="#000000" stroke-width="2"/>
|
||||
<path d="M3 16C3 14.8954 3.89543 14 5 14H8C9.10457 14 10 14.8954 10 16V19C10 20.1046 9.10457 21 8 21H5C3.89543 21 3 20.1046 3 19V16Z" stroke="#000000" stroke-width="2"/>
|
||||
<path d="M14 17.5C14 15.567 15.567 14 17.5 14C19.433 14 21 15.567 21 17.5C21 19.433 19.433 21 17.5 21C15.567 21 14 19.433 14 17.5Z" stroke="#000000" stroke-width="2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 725 B |
@@ -1,7 +0,0 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10 2H13C13.5523 2 14 2.44772 14 3V6" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6 2H3C2.44772 2 2 2.44772 2 3V6" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6 14H3C2.44772 14 2 13.5523 2 13V10" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M10 14H13C13.5523 14 14 13.5523 14 13V10" stroke="#333333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<rect x="6" y="6" width="4" height="4" rx="1" stroke="#333333"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 620 B |
@@ -1,4 +0,0 @@
|
||||
<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>
|
||||
|
Before Width: | Height: | Size: 606 B |
@@ -1,4 +0,0 @@
|
||||
<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>
|
||||
|
Before Width: | Height: | Size: 238 B |
@@ -1,17 +0,0 @@
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
version="1.1"
|
||||
id="svg808"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs812" />
|
||||
<path
|
||||
id="path930"
|
||||
style="fill:#00bcf0;fill-opacity:1"
|
||||
transform="rotate(-90)"
|
||||
d="M 0,7.9238281 A 8,8 0 0 0 -8.0585938,0 8,8 0 0 0 -16,8.0390625 8,8 0 0 0 -7.9804688,16 8,8 0 0 0 0,8 Z M -4,8 c 0,0.2769988 -0.2230012,0.5 -0.5,0.5 h -3 v 3 c 0,0.277 -0.2230012,0.5 -0.5,0.5 -0.2769988,0 -0.5,-0.223 -0.5,-0.5 v -3 h -3 C -11.777,8.5 -12,8.2769988 -12,8 c 0,-0.2769988 0.223,-0.5 0.5,-0.5 h 3 v -3 C -8.5,4.2230012 -8.2769988,4 -8,4 c 0.2769988,0 0.5,0.2230012 0.5,0.5 v 3 h 3 C -4.2230012,7.5 -4,7.7230012 -4,8 Z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 766 B |
@@ -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="M8 3L9.3905 5.96215L12.5 6.44006L10.25 8.74448L10.781 12L8 10.4621L5.219 12L5.75 8.74448L3.5 6.44006L6.6095 5.96215L8 3Z" fill="#none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 313 B |
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 38 KiB |
@@ -0,0 +1 @@
|
||||
use_precompiled_binaries: true
|
||||
@@ -0,0 +1 @@
|
||||
APPFLOWY_CLOUD_URL=
|
||||
@@ -0,0 +1 @@
|
||||
extensions:
|
||||
@@ -1,8 +1,10 @@
|
||||
import 'package:appflowy/workspace/application/appearance_defaults.dart';
|
||||
import 'package:appflowy/workspace/application/settings/prelude.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_appearance_view.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_appearance/settings_appearance.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import 'util/util.dart';
|
||||
|
||||
void main() {
|
||||
@@ -14,7 +16,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
|
||||
await tester.tapGoButton();
|
||||
tester.expectToSeeHomePage();
|
||||
await tester.expectToSeeHomePageWithGetStartedPage();
|
||||
await tester.openSettings();
|
||||
|
||||
await tester.openSettingsPage(SettingsPage.appearance);
|
||||
@@ -41,5 +43,48 @@ void main() {
|
||||
|
||||
expect(find.textContaining('Abel'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('reset the font family', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
|
||||
await tester.tapGoButton();
|
||||
await tester.expectToSeeHomePageWithGetStartedPage();
|
||||
await tester.openSettings();
|
||||
|
||||
await tester.openSettingsPage(SettingsPage.appearance);
|
||||
|
||||
final dropDown = find.byKey(ThemeFontFamilySetting.popoverKey);
|
||||
await tester.tap(dropDown);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final textField = find.byKey(ThemeFontFamilySetting.textFieldKey);
|
||||
await tester.tap(textField);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.enterText(textField, 'Abel');
|
||||
await tester.pumpAndSettle();
|
||||
final fontFamilyButton = find.byKey(const Key('Abel'));
|
||||
|
||||
expect(fontFamilyButton, findsOneWidget);
|
||||
await tester.tap(fontFamilyButton);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// just switch the page and verify that the font family was set after that
|
||||
await tester.openSettingsPage(SettingsPage.files);
|
||||
await tester.openSettingsPage(SettingsPage.appearance);
|
||||
|
||||
final resetButton = find.byKey(ThemeFontFamilySetting.resetButtonkey);
|
||||
await tester.tap(resetButton);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// just switch the page and verify that the font family was set after that
|
||||
await tester.openSettingsPage(SettingsPage.files);
|
||||
await tester.openSettingsPage(SettingsPage.appearance);
|
||||
|
||||
expect(
|
||||
find.textContaining(DefaultAppearanceSettings.kDefaultFontFamily),
|
||||
findsOneWidget,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/plugins/database/board/presentation/widgets/board_column_header.dart';
|
||||
import 'package:appflowy/plugins/database/widgets/card/container/card_container.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_board/appflowy_board.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import '../util/util.dart';
|
||||
|
||||
const defaultFirstCardName = 'Card 1';
|
||||
const defaultLastCardName = 'Card 3';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('board add row test:', () {
|
||||
testWidgets('from header', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
|
||||
|
||||
final findFirstCard = find.descendant(
|
||||
of: find.byType(AppFlowyGroupCard),
|
||||
matching: find.byType(FlowyText),
|
||||
);
|
||||
|
||||
FlowyText firstCardText = tester.firstWidget(findFirstCard);
|
||||
expect(firstCardText.text, defaultFirstCardName);
|
||||
|
||||
await tester.tap(
|
||||
find
|
||||
.descendant(
|
||||
of: find.byType(BoardColumnHeader),
|
||||
matching: find.byWidgetPredicate(
|
||||
(widget) => widget is FlowySvg && widget.svg == FlowySvgs.add_s,
|
||||
),
|
||||
)
|
||||
.at(1),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
const newCardName = 'Card 4';
|
||||
await tester.enterText(
|
||||
find.descendant(
|
||||
of: find.byType(RowCardContainer),
|
||||
matching: find.byType(TextField),
|
||||
),
|
||||
newCardName,
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.byType(AppFlowyBoard));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
firstCardText = tester.firstWidget(findFirstCard);
|
||||
expect(firstCardText.text, newCardName);
|
||||
});
|
||||
|
||||
testWidgets('from footer', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
|
||||
|
||||
final findLastCard = find.descendant(
|
||||
of: find.byType(AppFlowyGroupCard),
|
||||
matching: find.byType(FlowyText),
|
||||
);
|
||||
|
||||
FlowyText? lastCardText =
|
||||
tester.widgetList(findLastCard).last as FlowyText;
|
||||
expect(lastCardText.text, defaultLastCardName);
|
||||
|
||||
await tester.tap(
|
||||
find
|
||||
.descendant(
|
||||
of: find.byType(AppFlowyGroupFooter),
|
||||
matching: find.byType(FlowySvg),
|
||||
)
|
||||
.at(1),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
const newCardName = 'Card 4';
|
||||
await tester.enterText(
|
||||
find.descendant(
|
||||
of: find.byType(RowCardContainer),
|
||||
matching: find.byType(TextField),
|
||||
),
|
||||
newCardName,
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.byType(AppFlowyBoard));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
lastCardText = tester.widgetList(findLastCard).last as FlowyText;
|
||||
expect(lastCardText.text, newCardName);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import 'package:appflowy/plugins/database/widgets/row/cells/select_option_cell/extension.dart';
|
||||
import 'package:appflowy/plugins/database/widgets/row/row_property.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import 'package:appflowy_board/appflowy_board.dart';
|
||||
|
||||
import '../util/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('board group test', () {
|
||||
testWidgets('move row to another group', (tester) async {
|
||||
const card1Name = 'Card 1';
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
|
||||
final card1 = find.ancestor(
|
||||
of: find.findTextInFlowyText(card1Name),
|
||||
matching: find.byType(AppFlowyGroupCard),
|
||||
);
|
||||
final doingGroup = find.findTextInFlowyText('Doing');
|
||||
final doingGroupCenter = tester.getCenter(doingGroup);
|
||||
final card1Center = tester.getCenter(card1);
|
||||
|
||||
await tester.timedDrag(
|
||||
card1,
|
||||
doingGroupCenter.translate(-card1Center.dx, -card1Center.dy),
|
||||
const Duration(seconds: 1),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(card1);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final card1StatusFinder = find.descendant(
|
||||
of: find.byType(RowPropertyList),
|
||||
matching: find.descendant(
|
||||
of: find.byType(SelectOptionTag),
|
||||
matching: find.byType(FlowyText),
|
||||
),
|
||||
);
|
||||
expect(card1StatusFinder, findsNWidgets(1));
|
||||
final card1StatusText = tester.widget<FlowyText>(card1StatusFinder).text;
|
||||
expect(card1StatusText, 'Doing');
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/plugins/database/board/presentation/widgets/board_column_header.dart';
|
||||
import 'package:appflowy/plugins/database/board/presentation/widgets/board_hidden_groups.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import '../util/database_test_op.dart';
|
||||
import '../util/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('board group options:', () {
|
||||
testWidgets('expand/collapse hidden groups', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
|
||||
|
||||
final collapseFinder = find.byFlowySvg(FlowySvgs.pull_left_outlined_s);
|
||||
final expandFinder = find.byFlowySvg(FlowySvgs.hamburger_s_s);
|
||||
|
||||
// Is expanded by default
|
||||
expect(collapseFinder, findsOneWidget);
|
||||
expect(expandFinder, findsNothing);
|
||||
|
||||
// Collapse hidden groups
|
||||
await tester.tap(collapseFinder);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Is collapsed
|
||||
expect(collapseFinder, findsNothing);
|
||||
expect(expandFinder, findsOneWidget);
|
||||
|
||||
// Expand hidden groups
|
||||
await tester.tap(expandFinder);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Is expanded
|
||||
expect(collapseFinder, findsOneWidget);
|
||||
expect(expandFinder, findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('hide first group, and show it again', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
|
||||
|
||||
// Tap the options of the first group
|
||||
final optionsFinder = find
|
||||
.descendant(
|
||||
of: find.byType(BoardColumnHeader),
|
||||
matching: find.byFlowySvg(FlowySvgs.details_horizontal_s),
|
||||
)
|
||||
.first;
|
||||
|
||||
await tester.tap(optionsFinder);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Tap the hide option
|
||||
await tester.tap(find.byFlowySvg(FlowySvgs.hide_s));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
int shownGroups =
|
||||
tester.widgetList(find.byType(BoardColumnHeader)).length;
|
||||
|
||||
// We still show Doing, Done, No Status
|
||||
expect(shownGroups, 3);
|
||||
|
||||
final hiddenCardFinder = find.byType(HiddenGroupCard);
|
||||
await tester.hoverOnWidget(hiddenCardFinder);
|
||||
await tester.tap(find.byFlowySvg(FlowySvgs.show_m));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
shownGroups = tester.widgetList(find.byType(BoardColumnHeader)).length;
|
||||
expect(shownGroups, 4);
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('delete a group', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
|
||||
|
||||
expect(tester.widgetList(find.byType(BoardColumnHeader)).length, 4);
|
||||
|
||||
// tap group option button for the first group. Delete shouldn't show up
|
||||
await tester.tapButton(
|
||||
find
|
||||
.descendant(
|
||||
of: find.byType(BoardColumnHeader),
|
||||
matching: find.byFlowySvg(FlowySvgs.details_horizontal_s),
|
||||
)
|
||||
.first,
|
||||
);
|
||||
expect(find.byFlowySvg(FlowySvgs.delete_s), findsNothing);
|
||||
|
||||
// dismiss the popup
|
||||
await tester.sendKeyEvent(LogicalKeyboardKey.escape);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// tap group option button for the first group. Delete should show up
|
||||
await tester.tapButton(
|
||||
find
|
||||
.descendant(
|
||||
of: find.byType(BoardColumnHeader),
|
||||
matching: find.byFlowySvg(FlowySvgs.details_horizontal_s),
|
||||
)
|
||||
.at(1),
|
||||
);
|
||||
expect(find.byFlowySvg(FlowySvgs.delete_s), findsOneWidget);
|
||||
|
||||
// Tap the delete button and confirm
|
||||
await tester.tapButton(find.byFlowySvg(FlowySvgs.delete_s));
|
||||
await tester.tapDialogOkButton();
|
||||
|
||||
// Expect number of groups to decrease by one
|
||||
expect(tester.widgetList(find.byType(BoardColumnHeader)).length, 3);
|
||||
});
|
||||
}
|
||||
|
||||
extension FlowySvgFinder on CommonFinders {
|
||||
Finder byFlowySvg(FlowySvgData svg) => _FlowySvgFinder(svg);
|
||||
}
|
||||
|
||||
class _FlowySvgFinder extends MatchFinder {
|
||||
_FlowySvgFinder(this.svg);
|
||||
|
||||
final FlowySvgData svg;
|
||||
|
||||
@override
|
||||
String get description => 'flowy_svg "$svg"';
|
||||
|
||||
@override
|
||||
bool matches(Element candidate) {
|
||||
final Widget widget = candidate.widget;
|
||||
return widget is FlowySvg && widget.svg == svg;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/card/card.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||
import 'package:appflowy/plugins/database/widgets/card/card.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_board/appflowy_board.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import '../util/util.dart';
|
||||
import '../util/database_test_op.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
@@ -15,7 +18,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Board);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
|
||||
const name = 'Card 1';
|
||||
final card1 = find.findTextInFlowyText(name);
|
||||
await tester.hoverOnWidget(
|
||||
@@ -33,7 +36,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Board);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
|
||||
const name = 'Card 1';
|
||||
final card1 = find.findTextInFlowyText(name);
|
||||
await tester.hoverOnWidget(
|
||||
@@ -46,5 +49,56 @@ void main() {
|
||||
await tester.tapButtonWithName(LocaleKeys.button_duplicate.tr());
|
||||
expect(find.textContaining(name, findRichText: true), findsNWidgets(2));
|
||||
});
|
||||
|
||||
testWidgets('add new group', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
|
||||
|
||||
// assert number of groups
|
||||
tester.assertNumberOfGroups(4);
|
||||
|
||||
// scroll the board horizontally to ensure add new group button appears
|
||||
await tester.scrollBoardToEnd();
|
||||
|
||||
// assert and click on add new group button
|
||||
tester.assertNewGroupTextField(false);
|
||||
await tester.tapNewGroupButton();
|
||||
tester.assertNewGroupTextField(true);
|
||||
|
||||
// enter new group name and submit
|
||||
await tester.enterNewGroupName('needs design', submit: true);
|
||||
|
||||
// assert number of groups has increased
|
||||
tester.assertNumberOfGroups(5);
|
||||
|
||||
// assert text field has disappeared
|
||||
await tester.scrollBoardToEnd();
|
||||
tester.assertNewGroupTextField(false);
|
||||
|
||||
// click on add new group button
|
||||
await tester.tapNewGroupButton();
|
||||
tester.assertNewGroupTextField(true);
|
||||
|
||||
// type some things
|
||||
await tester.enterNewGroupName('needs planning', submit: false);
|
||||
|
||||
// click on clear button and assert empty contents
|
||||
await tester.clearNewGroupTextField();
|
||||
|
||||
// press escape to cancel
|
||||
await tester.sendKeyEvent(LogicalKeyboardKey.escape);
|
||||
await tester.pumpAndSettle();
|
||||
tester.assertNewGroupTextField(false);
|
||||
|
||||
// click on add new group button
|
||||
await tester.tapNewGroupButton();
|
||||
tester.assertNewGroupTextField(true);
|
||||
|
||||
// press elsewhere to cancel
|
||||
await tester.tap(find.byType(AppFlowyBoard));
|
||||
await tester.pumpAndSettle();
|
||||
tester.assertNewGroupTextField(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,10 +1,14 @@
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import 'board_row_test.dart' as board_row_test;
|
||||
import 'board_add_row_test.dart' as board_add_row_test;
|
||||
import 'board_group_test.dart' as board_group_test;
|
||||
|
||||
void startTesting() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
// Board integration tests
|
||||
board_row_test.main();
|
||||
board_add_row_test.main();
|
||||
board_group_test.main();
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
// ignore_for_file: unused_import
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:appflowy/env/cloud_env.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/user/application/auth/af_cloud_mock_auth_service.dart';
|
||||
import 'package:appflowy/user/application/auth/auth_service.dart';
|
||||
import 'package:appflowy/workspace/application/settings/prelude.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/setting_appflowy_cloud.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_user_view.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/uuid.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import '../util/dir.dart';
|
||||
import '../util/mock/mock_file_picker.dart';
|
||||
import '../util/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('appflowy cloud', () {
|
||||
testWidgets('anon user and then sign in', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
);
|
||||
|
||||
tester.expectToSeeText(LocaleKeys.signIn_loginStartWithAnonymous.tr());
|
||||
await tester.tapGoButton();
|
||||
await tester.expectToSeeHomePageWithGetStartedPage();
|
||||
|
||||
// reanme the name of the anon user
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
final userNameFinder = find.descendant(
|
||||
of: find.byType(SettingsUserView),
|
||||
matching: find.byType(UserNameInput),
|
||||
);
|
||||
await tester.enterText(userNameFinder, 'local_user');
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// sign up with Google
|
||||
await tester.tapGoogleLoginInButton();
|
||||
|
||||
// sign out
|
||||
await tester.expectToSeeHomePage();
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
await tester.logout();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// tap the continue as anonymous button
|
||||
await tester
|
||||
.tapButton(find.text(LocaleKeys.signIn_loginStartWithAnonymous.tr()));
|
||||
await tester.expectToSeeHomePage();
|
||||
|
||||
// New anon user name
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
final userNameInput = tester.widget(userNameFinder) as UserNameInput;
|
||||
expect(userNameInput.name, 'Me');
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
// ignore_for_file: unused_import
|
||||
|
||||
import 'package:appflowy/env/cloud_env.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/user/application/auth/af_cloud_mock_auth_service.dart';
|
||||
import 'package:appflowy/user/application/auth/auth_service.dart';
|
||||
import 'package:appflowy/workspace/application/settings/prelude.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/setting_appflowy_cloud.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_user_view.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/uuid.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import '../util/mock/mock_file_picker.dart';
|
||||
import '../util/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('appflowy cloud auth', () {
|
||||
testWidgets('sign in', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
);
|
||||
await tester.tapGoogleLoginInButton();
|
||||
await tester.expectToSeeHomePageWithGetStartedPage();
|
||||
});
|
||||
|
||||
testWidgets('sign out', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
);
|
||||
await tester.tapGoogleLoginInButton();
|
||||
|
||||
// Open the setting page and sign out
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
await tester.tapButton(find.byType(SettingLogoutButton));
|
||||
|
||||
tester.expectToSeeText(LocaleKeys.button_ok.tr());
|
||||
await tester.tapButtonWithName(LocaleKeys.button_ok.tr());
|
||||
|
||||
// Go to the sign in page again
|
||||
await tester.pumpAndSettle(const Duration(seconds: 1));
|
||||
tester.expectToSeeGoogleLoginButton();
|
||||
});
|
||||
|
||||
testWidgets('sign in as annoymous', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
);
|
||||
await tester.tapSignInAsGuest();
|
||||
|
||||
// should not see the sync setting page when sign in as annoymous
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
tester.expectToSeeGoogleLoginButton();
|
||||
});
|
||||
|
||||
testWidgets('enable sync', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
);
|
||||
|
||||
await tester.tapGoogleLoginInButton();
|
||||
// Open the setting page and sign out
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.cloud);
|
||||
|
||||
// the switch should be on by default
|
||||
tester.assertAppFlowyCloudEnableSyncSwitchValue(true);
|
||||
await tester.toggleEnableSync(AppFlowyCloudEnableSync);
|
||||
|
||||
// the switch should be off
|
||||
tester.assertAppFlowyCloudEnableSyncSwitchValue(false);
|
||||
|
||||
// the switch should be on after toggling
|
||||
await tester.toggleEnableSync(AppFlowyCloudEnableSync);
|
||||
tester.assertAppFlowyCloudEnableSyncSwitchValue(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import 'empty_test.dart' as preset_af_cloud_env_test;
|
||||
import 'appflowy_cloud_auth_test.dart' as appflowy_cloud_auth_test;
|
||||
// import 'document_sync_test.dart' as document_sync_test;
|
||||
import 'user_setting_sync_test.dart' as user_sync_test;
|
||||
import 'anon_user_continue_test.dart' as anon_user_continue_test;
|
||||
|
||||
Future<void> main() async {
|
||||
preset_af_cloud_env_test.main();
|
||||
|
||||
appflowy_cloud_auth_test.main();
|
||||
|
||||
// document_sync_test.main();
|
||||
|
||||
user_sync_test.main();
|
||||
|
||||
anon_user_continue_test.main();
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// ignore_for_file: unused_import
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:appflowy/env/cloud_env.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/user/application/auth/af_cloud_mock_auth_service.dart';
|
||||
import 'package:appflowy/user/application/auth/auth_service.dart';
|
||||
import 'package:appflowy/workspace/application/settings/prelude.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/setting_appflowy_cloud.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_user_view.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/uuid.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import '../util/dir.dart';
|
||||
import '../util/mock/mock_file_picker.dart';
|
||||
import '../util/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
final email = '${uuid()}@appflowy.io';
|
||||
const inputContent = 'Hello world, this is a test document';
|
||||
|
||||
// The test will create a new document called Sample, and sync it to the server.
|
||||
// Then the test will logout the user, and login with the same user. The data will
|
||||
// be synced from the server.
|
||||
group('appflowy cloud document', () {
|
||||
testWidgets('sync local docuemnt to server', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
email: email,
|
||||
);
|
||||
await tester.tapGoogleLoginInButton();
|
||||
await tester.expectToSeeHomePageWithGetStartedPage();
|
||||
|
||||
// create a new document called Sample
|
||||
await tester.createNewPage(
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
|
||||
// focus on the editor
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
await tester.ime.insertText(inputContent);
|
||||
expect(find.text(inputContent, findRichText: true), findsOneWidget);
|
||||
|
||||
// TODO(nathan): remove the await
|
||||
// 6 seconds for data sync
|
||||
await tester.waitForSeconds(6);
|
||||
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
await tester.logout();
|
||||
});
|
||||
|
||||
testWidgets('sync doc from server', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
email: email,
|
||||
);
|
||||
await tester.tapGoogleLoginInButton();
|
||||
await tester.expectToSeeHomePage();
|
||||
|
||||
// the latest document will be opened, so the content must be the inputContent
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text(inputContent, findRichText: true), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import 'package:appflowy/env/cloud_env.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import '../util/util.dart';
|
||||
|
||||
// This test is meaningless, just for preventing the CI from failing.
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('Empty', () {
|
||||
testWidgets('set appflowy cloud', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
import 'package:appflowy/env/cloud_env.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/workspace/application/settings/prelude.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/setting_supabase_cloud.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_user_view.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import '../util/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('supabase auth', () {
|
||||
testWidgets('sign in with supabase', (tester) async {
|
||||
await tester.initializeAppFlowy(cloudType: AuthenticatorType.supabase);
|
||||
await tester.tapGoogleLoginInButton();
|
||||
await tester.expectToSeeHomePageWithGetStartedPage();
|
||||
});
|
||||
|
||||
testWidgets('sign out with supabase', (tester) async {
|
||||
await tester.initializeAppFlowy(cloudType: AuthenticatorType.supabase);
|
||||
await tester.tapGoogleLoginInButton();
|
||||
|
||||
// Open the setting page and sign out
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
await tester.tapButton(find.byType(SettingLogoutButton));
|
||||
|
||||
tester.expectToSeeText(LocaleKeys.button_ok.tr());
|
||||
await tester.tapButtonWithName(LocaleKeys.button_ok.tr());
|
||||
|
||||
// Go to the sign in page again
|
||||
await tester.pumpAndSettle(const Duration(seconds: 1));
|
||||
tester.expectToSeeGoogleLoginButton();
|
||||
});
|
||||
|
||||
testWidgets('sign in as annoymous', (tester) async {
|
||||
await tester.initializeAppFlowy(cloudType: AuthenticatorType.supabase);
|
||||
await tester.tapSignInAsGuest();
|
||||
|
||||
// should not see the sync setting page when sign in as annoymous
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
tester.expectToSeeGoogleLoginButton();
|
||||
});
|
||||
|
||||
// testWidgets('enable encryption', (tester) async {
|
||||
// await tester.initializeAppFlowy(cloudType: CloudType.supabase);
|
||||
// await tester.tapGoogleLoginInButton();
|
||||
|
||||
// // Open the setting page and sign out
|
||||
// await tester.openSettings();
|
||||
// await tester.openSettingsPage(SettingsPage.cloud);
|
||||
|
||||
// // the switch should be off by default
|
||||
// tester.assertEnableEncryptSwitchValue(false);
|
||||
// await tester.toggleEnableEncrypt();
|
||||
|
||||
// // the switch should be on after toggling
|
||||
// tester.assertEnableEncryptSwitchValue(true);
|
||||
|
||||
// // the switch can not be toggled back to off
|
||||
// await tester.toggleEnableEncrypt();
|
||||
// tester.assertEnableEncryptSwitchValue(true);
|
||||
// });
|
||||
|
||||
testWidgets('enable sync', (tester) async {
|
||||
await tester.initializeAppFlowy(cloudType: AuthenticatorType.supabase);
|
||||
await tester.tapGoogleLoginInButton();
|
||||
|
||||
// Open the setting page and sign out
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.cloud);
|
||||
|
||||
// the switch should be on by default
|
||||
tester.assertSupabaseEnableSyncSwitchValue(true);
|
||||
await tester.toggleEnableSync(SupabaseEnableSync);
|
||||
|
||||
// the switch should be off
|
||||
tester.assertSupabaseEnableSyncSwitchValue(false);
|
||||
|
||||
// the switch should be on after toggling
|
||||
await tester.toggleEnableSync(SupabaseEnableSync);
|
||||
tester.assertSupabaseEnableSyncSwitchValue(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
// ignore_for_file: unused_import
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:appflowy/env/cloud_env.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/user/application/auth/af_cloud_mock_auth_service.dart';
|
||||
import 'package:appflowy/user/application/auth/auth_service.dart';
|
||||
import 'package:appflowy/workspace/application/settings/prelude.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/setting_appflowy_cloud.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_user_view.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/user_avatar.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/uuid.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import '../util/database_test_op.dart';
|
||||
import '../util/dir.dart';
|
||||
import '../util/emoji.dart';
|
||||
import '../util/mock/mock_file_picker.dart';
|
||||
import '../util/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
final email = '${uuid()}@appflowy.io';
|
||||
const name = 'nathan';
|
||||
|
||||
group('appflowy cloud setting', () {
|
||||
testWidgets('sync user name and icon to server', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
email: email,
|
||||
);
|
||||
await tester.tapGoogleLoginInButton();
|
||||
await tester.expectToSeeHomePageWithGetStartedPage();
|
||||
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
final userAvatarFinder = find.descendant(
|
||||
of: find.byType(SettingsUserView),
|
||||
matching: find.byType(UserAvatar),
|
||||
);
|
||||
|
||||
// Open icon picker dialog and select emoji
|
||||
await tester.tap(userAvatarFinder);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tapEmoji('😁');
|
||||
await tester.pumpAndSettle();
|
||||
final UserAvatar userAvatar =
|
||||
tester.widget(userAvatarFinder) as UserAvatar;
|
||||
expect(userAvatar.iconUrl, '😁');
|
||||
|
||||
// enter user name
|
||||
final userNameFinder = find.descendant(
|
||||
of: find.byType(SettingsUserView),
|
||||
matching: find.byType(UserNameInput),
|
||||
);
|
||||
await tester.enterText(userNameFinder, name);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tapEscButton();
|
||||
|
||||
// wait 2 seconds for the sync to finish
|
||||
await tester.pumpAndSettle(const Duration(seconds: 2));
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('get user icon and name from server', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
email: email,
|
||||
);
|
||||
await tester.tapGoogleLoginInButton();
|
||||
await tester.expectToSeeHomePageWithGetStartedPage();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
|
||||
// verify icon
|
||||
final userAvatarFinder = find.descendant(
|
||||
of: find.byType(SettingsUserView),
|
||||
matching: find.byType(UserAvatar),
|
||||
);
|
||||
final UserAvatar userAvatar = tester.widget(userAvatarFinder) as UserAvatar;
|
||||
expect(userAvatar.iconUrl, '😁');
|
||||
|
||||
// verify name
|
||||
final userNameFinder = find.descendant(
|
||||
of: find.byType(SettingsUserView),
|
||||
matching: find.byType(UserNameInput),
|
||||
);
|
||||
final UserNameInput userNameInput =
|
||||
tester.widget(userNameFinder) as UserNameInput;
|
||||
expect(userNameInput.name, name);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/setting_entities.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pbenum.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import '../util/database_test_op.dart';
|
||||
import '../util/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('calendar', () {
|
||||
testWidgets('update calendar layout', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
layout: ViewLayoutPB.Calendar,
|
||||
);
|
||||
|
||||
// open setting
|
||||
await tester.tapDatabaseSettingButton();
|
||||
await tester.tapDatabaseLayoutButton();
|
||||
await tester.selectDatabaseLayoutType(DatabaseLayoutPB.Board);
|
||||
await tester.assertCurrentDatabaseLayoutType(DatabaseLayoutPB.Board);
|
||||
|
||||
await tester.tapDatabaseSettingButton();
|
||||
await tester.tapDatabaseLayoutButton();
|
||||
await tester.selectDatabaseLayoutType(DatabaseLayoutPB.Grid);
|
||||
await tester.assertCurrentDatabaseLayoutType(DatabaseLayoutPB.Grid);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('calendar start from day setting', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
// Create calendar view
|
||||
const name = 'calendar';
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: name,
|
||||
layout: ViewLayoutPB.Calendar,
|
||||
);
|
||||
|
||||
// Open setting
|
||||
await tester.tapDatabaseSettingButton();
|
||||
await tester.tapCalendarLayoutSettingButton();
|
||||
|
||||
// select the first day of week is Monday
|
||||
await tester.tapFirstDayOfWeek();
|
||||
await tester.tapFirstDayOfWeekStartFromMonday();
|
||||
|
||||
// Open the other page and open the new calendar page again
|
||||
await tester.openPage(gettingStarted);
|
||||
await tester.pumpAndSettle(const Duration(milliseconds: 300));
|
||||
await tester.openPage(name, layout: ViewLayoutPB.Calendar);
|
||||
|
||||
// Open setting again and check the start from Monday is selected
|
||||
await tester.tapDatabaseSettingButton();
|
||||
await tester.tapCalendarLayoutSettingButton();
|
||||
await tester.tapFirstDayOfWeek();
|
||||
tester.assertFirstDayOfWeekStartFromMonday();
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('creating and editing calendar events', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
// Create the calendar view
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
layout: ViewLayoutPB.Calendar,
|
||||
);
|
||||
|
||||
// Scroll until today's date cell is visible
|
||||
await tester.scrollToToday();
|
||||
|
||||
// Hover over today's calendar cell
|
||||
await tester.hoverOnTodayCalendarCell(
|
||||
// Tap on create new event button
|
||||
onHover: () async => await tester.tapAddCalendarEventButton(),
|
||||
);
|
||||
|
||||
// Make sure that the event editor popup is shown
|
||||
tester.assertEventEditorOpen();
|
||||
|
||||
tester.assertNumberOfEventsInCalendar(1);
|
||||
|
||||
// Dismiss the event editor popup
|
||||
await tester.dismissEventEditor();
|
||||
|
||||
// Double click on today's calendar cell to create a new event
|
||||
await tester.doubleClickCalendarCell(DateTime.now());
|
||||
|
||||
// Make sure that the event is inserted in the cell
|
||||
tester.assertNumberOfEventsInCalendar(2);
|
||||
|
||||
// Click on the event
|
||||
await tester.openCalendarEvent(index: 0);
|
||||
tester.assertEventEditorOpen();
|
||||
|
||||
// Change the title of the event
|
||||
await tester.editEventTitle('hello world');
|
||||
await tester.dismissEventEditor();
|
||||
|
||||
// Make sure that the event is edited
|
||||
tester.assertNumberOfEventsInCalendar(1, title: 'hello world');
|
||||
tester.assertNumberOfEventsOnSpecificDay(2, DateTime.now());
|
||||
|
||||
// Click on the event
|
||||
await tester.openCalendarEvent(index: 0);
|
||||
tester.assertEventEditorOpen();
|
||||
|
||||
// Click on the open icon
|
||||
await tester.openEventToRowDetailPage();
|
||||
tester.assertRowDetailPageOpened();
|
||||
|
||||
// Duplicate the event
|
||||
await tester.tapRowDetailPageRowActionButton();
|
||||
await tester.tapRowDetailPageDuplicateRowButton();
|
||||
await tester.dismissRowDetailPage();
|
||||
|
||||
// Check that there are 2 events
|
||||
tester.assertNumberOfEventsInCalendar(2, title: 'hello world');
|
||||
tester.assertNumberOfEventsOnSpecificDay(3, DateTime.now());
|
||||
|
||||
// Delete an event
|
||||
await tester.openCalendarEvent(index: 1);
|
||||
await tester.deleteEventFromEventEditor();
|
||||
|
||||
// Check that there is 1 event
|
||||
tester.assertNumberOfEventsInCalendar(1, title: 'hello world');
|
||||
tester.assertNumberOfEventsOnSpecificDay(2, DateTime.now());
|
||||
|
||||
// Delete event from row detail page
|
||||
await tester.openCalendarEvent(index: 0);
|
||||
await tester.openEventToRowDetailPage();
|
||||
tester.assertRowDetailPageOpened();
|
||||
|
||||
await tester.tapRowDetailPageRowActionButton();
|
||||
await tester.tapRowDetailPageDeleteRowButton();
|
||||
|
||||
// Check that there is 0 event
|
||||
tester.assertNumberOfEventsInCalendar(0, title: 'hello world');
|
||||
tester.assertNumberOfEventsOnSpecificDay(1, DateTime.now());
|
||||
});
|
||||
|
||||
testWidgets('rescheduling events', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
// Create the calendar view
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
layout: ViewLayoutPB.Calendar,
|
||||
);
|
||||
|
||||
// Create a new event on the first of this month
|
||||
final today = DateTime.now();
|
||||
final firstOfThisMonth = DateTime(today.year, today.month, 1);
|
||||
await tester.doubleClickCalendarCell(firstOfThisMonth);
|
||||
await tester.dismissEventEditor();
|
||||
|
||||
// Drag and drop the event onto the next week, same day
|
||||
await tester.dragDropRescheduleCalendarEvent();
|
||||
|
||||
// Make sure that the event has been rescheduled to the new date
|
||||
final sameDayNextWeek = firstOfThisMonth.add(const Duration(days: 7));
|
||||
tester.assertNumberOfEventsInCalendar(1);
|
||||
tester.assertNumberOfEventsOnSpecificDay(1, sameDayNextWeek);
|
||||
|
||||
// Delete the event
|
||||
await tester.openCalendarEvent(index: 0, date: sameDayNextWeek);
|
||||
await tester.deleteEventFromEventEditor();
|
||||
|
||||
// Create another event on the 5th of this month
|
||||
final fifthOfThisMonth = DateTime(today.year, today.month, 5);
|
||||
await tester.doubleClickCalendarCell(fifthOfThisMonth);
|
||||
await tester.dismissEventEditor();
|
||||
|
||||
// Make sure that the event is on the 4t
|
||||
tester.assertNumberOfEventsOnSpecificDay(1, fifthOfThisMonth);
|
||||
|
||||
// Click on the event
|
||||
await tester.openCalendarEvent(index: 0, date: fifthOfThisMonth);
|
||||
|
||||
// Open the date editor of the event
|
||||
await tester.tapDateCellInRowDetailPage();
|
||||
await tester.findDateEditor(findsOneWidget);
|
||||
|
||||
// Edit the event's date
|
||||
final newDate = fifthOfThisMonth.add(const Duration(days: 1));
|
||||
await tester.selectDay(content: newDate.day);
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
// Dismiss the event editor
|
||||
await tester.dismissEventEditor();
|
||||
|
||||
// Make sure that the event is edited
|
||||
tester.assertNumberOfEventsInCalendar(1);
|
||||
tester.assertNumberOfEventsOnSpecificDay(1, newDate);
|
||||
|
||||
// Click on the unscheduled events button
|
||||
await tester.openUnscheduledEventsPopup();
|
||||
|
||||
// Assert that nothing shows up
|
||||
tester.findUnscheduledPopup(findsNothing, 0);
|
||||
|
||||
// Click on the event in the calendar
|
||||
await tester.openCalendarEvent(index: 0, date: newDate);
|
||||
|
||||
// Open the date editor of the event
|
||||
await tester.tapDateCellInRowDetailPage();
|
||||
await tester.findDateEditor(findsOneWidget);
|
||||
|
||||
// Clear the date of the event
|
||||
await tester.clearDate();
|
||||
|
||||
// Dismiss the event editor
|
||||
await tester.dismissEventEditor();
|
||||
tester.assertNumberOfEventsInCalendar(0);
|
||||
|
||||
// Click on the unscheduled events button
|
||||
await tester.openUnscheduledEventsPopup();
|
||||
|
||||
// Assert that a popup appears and 1 unscheduled event
|
||||
tester.findUnscheduledPopup(findsOneWidget, 1);
|
||||
|
||||
// Click on the unscheduled event
|
||||
await tester.clickUnscheduledEvent();
|
||||
|
||||
tester.assertRowDetailPageOpened();
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,542 @@
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import '../util/database_test_op.dart';
|
||||
import '../util/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('edit grid cell:', () {
|
||||
testWidgets('text', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
await tester.editCell(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.RichText,
|
||||
input: 'hello world',
|
||||
);
|
||||
|
||||
await tester.assertCellContent(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.RichText,
|
||||
content: 'hello world',
|
||||
);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
// Make sure the text cells are filled with the right content when there are
|
||||
// multiple text cell
|
||||
testWidgets('multiple text cells', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: 'my grid',
|
||||
layout: ViewLayoutPB.Grid,
|
||||
);
|
||||
await tester.createField(FieldType.RichText, 'description');
|
||||
|
||||
await tester.editCell(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.RichText,
|
||||
input: 'hello',
|
||||
);
|
||||
|
||||
await tester.editCell(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.RichText,
|
||||
input: 'world',
|
||||
cellIndex: 1,
|
||||
);
|
||||
|
||||
await tester.assertCellContent(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.RichText,
|
||||
content: 'hello',
|
||||
cellIndex: 0,
|
||||
);
|
||||
|
||||
await tester.assertCellContent(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.RichText,
|
||||
content: 'world',
|
||||
cellIndex: 1,
|
||||
);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('number', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
const fieldType = FieldType.Number;
|
||||
|
||||
// Create a number field
|
||||
await tester.createField(fieldType, fieldType.name);
|
||||
|
||||
await tester.editCell(
|
||||
rowIndex: 0,
|
||||
fieldType: fieldType,
|
||||
input: '-1',
|
||||
);
|
||||
// edit the next cell to force the previous cell at row 0 to lose focus
|
||||
await tester.editCell(
|
||||
rowIndex: 1,
|
||||
fieldType: fieldType,
|
||||
input: '0.2',
|
||||
);
|
||||
// -1 -> -1
|
||||
await tester.assertCellContent(
|
||||
rowIndex: 0,
|
||||
fieldType: fieldType,
|
||||
content: '-1',
|
||||
);
|
||||
|
||||
// edit the next cell to force the previous cell at row 1 to lose focus
|
||||
await tester.editCell(
|
||||
rowIndex: 2,
|
||||
fieldType: fieldType,
|
||||
input: '.1',
|
||||
);
|
||||
// 0.2 -> 0.2
|
||||
await tester.assertCellContent(
|
||||
rowIndex: 1,
|
||||
fieldType: fieldType,
|
||||
content: '0.2',
|
||||
);
|
||||
|
||||
// edit the next cell to force the previous cell at row 2 to lose focus
|
||||
await tester.editCell(
|
||||
rowIndex: 0,
|
||||
fieldType: fieldType,
|
||||
input: '',
|
||||
);
|
||||
// .1 -> 0.1
|
||||
await tester.assertCellContent(
|
||||
rowIndex: 2,
|
||||
fieldType: fieldType,
|
||||
content: '0.1',
|
||||
);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('checkbox', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
await tester.assertCheckboxCell(rowIndex: 0, isSelected: false);
|
||||
await tester.tapCheckboxCellInGrid(rowIndex: 0);
|
||||
await tester.assertCheckboxCell(rowIndex: 0, isSelected: true);
|
||||
|
||||
await tester.tapCheckboxCellInGrid(rowIndex: 1);
|
||||
await tester.tapCheckboxCellInGrid(rowIndex: 2);
|
||||
await tester.assertCheckboxCell(rowIndex: 1, isSelected: true);
|
||||
await tester.assertCheckboxCell(rowIndex: 2, isSelected: true);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('created time', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
const fieldType = FieldType.CreatedTime;
|
||||
// Create a create time field
|
||||
// The create time field is not editable
|
||||
await tester.createField(fieldType, fieldType.name);
|
||||
|
||||
await tester.tapCellInGrid(rowIndex: 0, fieldType: fieldType);
|
||||
|
||||
await tester.findDateEditor(findsNothing);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('last modified time', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
const fieldType = FieldType.LastEditedTime;
|
||||
// Create a last time field
|
||||
// The last time field is not editable
|
||||
await tester.createField(fieldType, fieldType.name);
|
||||
|
||||
await tester.tapCellInGrid(rowIndex: 0, fieldType: fieldType);
|
||||
|
||||
await tester.findDateEditor(findsNothing);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('date time', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
const fieldType = FieldType.DateTime;
|
||||
await tester.createField(fieldType, fieldType.name);
|
||||
|
||||
// Tap the cell to invoke the field editor
|
||||
await tester.tapCellInGrid(rowIndex: 0, fieldType: fieldType);
|
||||
await tester.findDateEditor(findsOneWidget);
|
||||
|
||||
// Toggle include time
|
||||
await tester.toggleIncludeTime();
|
||||
|
||||
// Dismiss the cell editor
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
await tester.tapCellInGrid(rowIndex: 0, fieldType: fieldType);
|
||||
await tester.findDateEditor(findsOneWidget);
|
||||
|
||||
// Turn off include time
|
||||
await tester.toggleIncludeTime();
|
||||
|
||||
// Select a date
|
||||
final today = DateTime.now();
|
||||
await tester.selectDay(content: today.day);
|
||||
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
await tester.assertDateCellInGrid(
|
||||
rowIndex: 0,
|
||||
content: DateFormat('MMM dd, y').format(today),
|
||||
);
|
||||
|
||||
await tester.tapCellInGrid(rowIndex: 0, fieldType: fieldType);
|
||||
await tester.findDateEditor(findsOneWidget);
|
||||
|
||||
// Toggle include time
|
||||
final now = DateTime.now();
|
||||
await tester.toggleIncludeTime();
|
||||
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
await tester.assertDateCellInGrid(
|
||||
rowIndex: 0,
|
||||
content: DateFormat('MMM dd, y HH:mm').format(now),
|
||||
);
|
||||
|
||||
await tester.tapCellInGrid(rowIndex: 0, fieldType: fieldType);
|
||||
await tester.findDateEditor(findsOneWidget);
|
||||
|
||||
// Change date format
|
||||
await tester.changeDateFormat();
|
||||
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
await tester.assertDateCellInGrid(
|
||||
rowIndex: 0,
|
||||
content: DateFormat('dd/MM/y HH:mm').format(now),
|
||||
);
|
||||
|
||||
await tester.tapCellInGrid(rowIndex: 0, fieldType: fieldType);
|
||||
await tester.findDateEditor(findsOneWidget);
|
||||
|
||||
// Change time format
|
||||
await tester.changeTimeFormat();
|
||||
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
await tester.assertDateCellInGrid(
|
||||
rowIndex: 0,
|
||||
content: DateFormat('dd/MM/y hh:mm a').format(now),
|
||||
);
|
||||
|
||||
await tester.tapCellInGrid(rowIndex: 0, fieldType: fieldType);
|
||||
await tester.findDateEditor(findsOneWidget);
|
||||
|
||||
// Clear the date and time
|
||||
await tester.clearDate();
|
||||
|
||||
await tester.assertDateCellInGrid(
|
||||
rowIndex: 0,
|
||||
content: '',
|
||||
);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('single select', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
const fieldType = FieldType.SingleSelect;
|
||||
|
||||
// When create a grid, it will create a single select field by default
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Tap the cell to invoke the selection option editor
|
||||
await tester.tapSelectOptionCellInGrid(rowIndex: 0, fieldType: fieldType);
|
||||
await tester.findSelectOptionEditor(findsOneWidget);
|
||||
|
||||
// Create a new select option
|
||||
await tester.createOption(name: 'tag 1');
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
// Make sure the option is created and displayed in the cell
|
||||
await tester.findSelectOptionWithNameInGrid(
|
||||
rowIndex: 0,
|
||||
name: 'tag 1',
|
||||
);
|
||||
|
||||
await tester.tapSelectOptionCellInGrid(rowIndex: 0, fieldType: fieldType);
|
||||
await tester.findSelectOptionEditor(findsOneWidget);
|
||||
|
||||
// Create another select option
|
||||
await tester.createOption(name: 'tag 2');
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
await tester.findSelectOptionWithNameInGrid(
|
||||
rowIndex: 0,
|
||||
name: 'tag 2',
|
||||
);
|
||||
|
||||
await tester.assertNumberOfSelectedOptionsInGrid(
|
||||
rowIndex: 0,
|
||||
matcher: findsOneWidget,
|
||||
);
|
||||
|
||||
await tester.tapSelectOptionCellInGrid(rowIndex: 0, fieldType: fieldType);
|
||||
await tester.findSelectOptionEditor(findsOneWidget);
|
||||
|
||||
// switch to first option
|
||||
await tester.selectOption(name: 'tag 1');
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
await tester.findSelectOptionWithNameInGrid(
|
||||
rowIndex: 0,
|
||||
name: 'tag 1',
|
||||
);
|
||||
|
||||
await tester.assertNumberOfSelectedOptionsInGrid(
|
||||
rowIndex: 0,
|
||||
matcher: findsOneWidget,
|
||||
);
|
||||
|
||||
await tester.tapSelectOptionCellInGrid(rowIndex: 0, fieldType: fieldType);
|
||||
await tester.findSelectOptionEditor(findsOneWidget);
|
||||
|
||||
// Deselect the currently-selected option
|
||||
await tester.selectOption(name: 'tag 1');
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
await tester.assertNumberOfSelectedOptionsInGrid(
|
||||
rowIndex: 0,
|
||||
matcher: findsNothing,
|
||||
);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('multi select', (tester) async {
|
||||
final tags = [
|
||||
'tag 1',
|
||||
'tag 2',
|
||||
'tag 3',
|
||||
'tag 4',
|
||||
];
|
||||
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
const fieldType = FieldType.MultiSelect;
|
||||
await tester.createField(fieldType, fieldType.name);
|
||||
|
||||
// Tap the cell to invoke the selection option editor
|
||||
await tester.tapSelectOptionCellInGrid(rowIndex: 0, fieldType: fieldType);
|
||||
await tester.findSelectOptionEditor(findsOneWidget);
|
||||
|
||||
// Create a new select option
|
||||
await tester.createOption(name: tags.first);
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
// Make sure the option is created and displayed in the cell
|
||||
await tester.findSelectOptionWithNameInGrid(
|
||||
rowIndex: 0,
|
||||
name: tags.first,
|
||||
);
|
||||
|
||||
await tester.tapSelectOptionCellInGrid(rowIndex: 0, fieldType: fieldType);
|
||||
await tester.findSelectOptionEditor(findsOneWidget);
|
||||
|
||||
// Create some other select options
|
||||
await tester.createOption(name: tags[1]);
|
||||
await tester.createOption(name: tags[2]);
|
||||
await tester.createOption(name: tags[3]);
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
for (final tag in tags) {
|
||||
await tester.findSelectOptionWithNameInGrid(
|
||||
rowIndex: 0,
|
||||
name: tag,
|
||||
);
|
||||
}
|
||||
|
||||
await tester.assertNumberOfSelectedOptionsInGrid(
|
||||
rowIndex: 0,
|
||||
matcher: findsNWidgets(4),
|
||||
);
|
||||
|
||||
await tester.tapSelectOptionCellInGrid(rowIndex: 0, fieldType: fieldType);
|
||||
await tester.findSelectOptionEditor(findsOneWidget);
|
||||
|
||||
// Deselect all options
|
||||
for (final tag in tags) {
|
||||
await tester.selectOption(name: tag);
|
||||
}
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
await tester.assertNumberOfSelectedOptionsInGrid(
|
||||
rowIndex: 0,
|
||||
matcher: findsNothing,
|
||||
);
|
||||
|
||||
await tester.tapSelectOptionCellInGrid(rowIndex: 0, fieldType: fieldType);
|
||||
await tester.findSelectOptionEditor(findsOneWidget);
|
||||
|
||||
// Select some options
|
||||
await tester.selectOption(name: tags[1]);
|
||||
await tester.selectOption(name: tags[3]);
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
await tester.findSelectOptionWithNameInGrid(
|
||||
rowIndex: 0,
|
||||
name: tags[1],
|
||||
);
|
||||
await tester.findSelectOptionWithNameInGrid(
|
||||
rowIndex: 0,
|
||||
name: tags[3],
|
||||
);
|
||||
|
||||
await tester.assertNumberOfSelectedOptionsInGrid(
|
||||
rowIndex: 0,
|
||||
matcher: findsNWidgets(2),
|
||||
);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('checklist', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
const fieldType = FieldType.Checklist;
|
||||
await tester.createField(fieldType, fieldType.name);
|
||||
|
||||
// assert that there is no progress bar in the grid
|
||||
tester.assertChecklistCellInGrid(rowIndex: 0, percent: null);
|
||||
|
||||
// tap on the first checklist cell
|
||||
await tester.tapChecklistCellInGrid(rowIndex: 0);
|
||||
|
||||
// assert that the checklist editor is shown
|
||||
tester.assertChecklistEditorVisible(visible: true);
|
||||
|
||||
// create a new task with enter
|
||||
await tester.createNewChecklistTask(name: "task 0", enter: true);
|
||||
|
||||
// assert that the task is displayed
|
||||
tester.assertChecklistTaskInEditor(
|
||||
index: 0,
|
||||
name: "task 0",
|
||||
isChecked: false,
|
||||
);
|
||||
|
||||
// update the task's name
|
||||
await tester.renameChecklistTask(index: 0, name: "task 1");
|
||||
|
||||
// assert that the task's name is updated
|
||||
tester.assertChecklistTaskInEditor(
|
||||
index: 0,
|
||||
name: "task 1",
|
||||
isChecked: false,
|
||||
);
|
||||
|
||||
// dismiss new task editor
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
// dismiss checklist cell editor
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
// assert that progress bar is shown in grid at 0%
|
||||
tester.assertChecklistCellInGrid(rowIndex: 0, percent: 0);
|
||||
|
||||
// start editing the first checklist cell again
|
||||
await tester.tapChecklistCellInGrid(rowIndex: 0);
|
||||
|
||||
// create another task with the create button
|
||||
await tester.createNewChecklistTask(name: "task 2", button: true);
|
||||
|
||||
// assert that the task was inserted
|
||||
tester.assertChecklistTaskInEditor(
|
||||
index: 1,
|
||||
name: "task 2",
|
||||
isChecked: false,
|
||||
);
|
||||
|
||||
// mark it as complete
|
||||
await tester.checkChecklistTask(index: 1);
|
||||
|
||||
// assert that the task was checked in the editor
|
||||
tester.assertChecklistTaskInEditor(
|
||||
index: 1,
|
||||
name: "task 2",
|
||||
isChecked: true,
|
||||
);
|
||||
|
||||
// dismiss checklist editor
|
||||
await tester.dismissCellEditor();
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
// assert that progressbar is shown in grid at 50%
|
||||
tester.assertChecklistCellInGrid(rowIndex: 0, percent: 0.5);
|
||||
|
||||
// re-open the cell editor
|
||||
await tester.tapChecklistCellInGrid(rowIndex: 0);
|
||||
|
||||
// hover over first task and delete it
|
||||
await tester.deleteChecklistTask(index: 0);
|
||||
|
||||
// dismiss cell editor
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
// assert that progressbar is shown in grid at 100%
|
||||
tester.assertChecklistCellInGrid(rowIndex: 0, percent: 1);
|
||||
|
||||
// re-open the cell edior
|
||||
await tester.tapChecklistCellInGrid(rowIndex: 0);
|
||||
|
||||
// delete the remaining task
|
||||
await tester.deleteChecklistTask(index: 0);
|
||||
|
||||
// dismiss the cell editor
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
// check that the progress bar is not viisble
|
||||
tester.assertChecklistCellInGrid(rowIndex: 0, percent: null);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import 'package:appflowy/plugins/database/grid/presentation/grid_page.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/setting_entities.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pbenum.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import '../util/database_test_op.dart';
|
||||
import '../util/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('database field settings', () {
|
||||
testWidgets('field visibility', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
await tester.tapCreateLinkedDatabaseViewButton(DatabaseLayoutPB.Grid);
|
||||
|
||||
// create a field
|
||||
await tester.scrollToRight(find.byType(GridPage));
|
||||
await tester.tapNewPropertyButton();
|
||||
await tester.renameField('New field 1');
|
||||
await tester.dismissFieldEditor();
|
||||
|
||||
// hide the field
|
||||
await tester.tapGridFieldWithName('New field 1');
|
||||
await tester.tapHidePropertyButton();
|
||||
await tester.noFieldWithName('New field 1');
|
||||
|
||||
// go back to inline database view, expect field to be shown
|
||||
await tester.tapTabBarLinkedViewByViewName('Untitled');
|
||||
await tester.findFieldWithName('New field 1');
|
||||
|
||||
// go back to linked database view, expect field to be hidden
|
||||
await tester.tapTabBarLinkedViewByViewName('Grid');
|
||||
await tester.noFieldWithName('New field 1');
|
||||
|
||||
// use the settings button to show the field
|
||||
await tester.tapDatabaseSettingButton();
|
||||
await tester.tapViewPropertiesButton();
|
||||
await tester.tapViewTogglePropertyVisibilityButtonByName('New field 1');
|
||||
await tester.dismissFieldEditor();
|
||||
await tester.findFieldWithName('New field 1');
|
||||
|
||||
// open first row in popup then hide the field
|
||||
await tester.openFirstRowDetailPage();
|
||||
await tester.tapGridFieldWithNameInRowDetailPage('New field 1');
|
||||
await tester.tapHidePropertyButtonInFieldEditor();
|
||||
await tester.dismissRowDetailPage();
|
||||
await tester.noFieldWithName('New field 1');
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,23 +1,23 @@
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/grid_page.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/type_option/select_option.dart';
|
||||
import 'package:appflowy/plugins/database/grid/presentation/grid_page.dart';
|
||||
import 'package:appflowy/plugins/database/grid/presentation/widgets/header/type_option/select/select_option.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import 'util/database_test_op.dart';
|
||||
import 'util/util.dart';
|
||||
import '../util/database_test_op.dart';
|
||||
import '../util/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('grid page', () {
|
||||
group('grid field editor:', () {
|
||||
testWidgets('rename existing field', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Invoke the field editor
|
||||
await tester.tapGridFieldWithName('Name');
|
||||
@@ -34,7 +34,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Invoke the field editor
|
||||
await tester.tapGridFieldWithName('Type');
|
||||
@@ -56,7 +56,7 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new grid
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// create a field
|
||||
await tester.createField(FieldType.Checklist, 'checklist');
|
||||
@@ -70,7 +70,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// create a field
|
||||
await tester.createField(FieldType.Checkbox, 'New field 1');
|
||||
@@ -90,7 +90,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// create a field
|
||||
await tester.scrollToRight(find.byType(GridPage));
|
||||
@@ -98,7 +98,7 @@ void main() {
|
||||
await tester.renameField('New field 1');
|
||||
await tester.dismissFieldEditor();
|
||||
|
||||
// Delete the field
|
||||
// duplicate the field
|
||||
await tester.tapGridFieldWithName('New field 1');
|
||||
await tester.tapDuplicatePropertyButton();
|
||||
|
||||
@@ -106,31 +106,34 @@ void main() {
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('hide field', (tester) async {
|
||||
testWidgets('insert field on either side of a field', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// create a field
|
||||
await tester.scrollToRight(find.byType(GridPage));
|
||||
await tester.tapNewPropertyButton();
|
||||
await tester.renameField('New field 1');
|
||||
|
||||
// insert new field to the right
|
||||
await tester.tapGridFieldWithName('Type');
|
||||
await tester.tapInsertFieldButton(left: false, name: 'Right');
|
||||
await tester.dismissFieldEditor();
|
||||
await tester.findFieldWithName('Right');
|
||||
|
||||
// Delete the field
|
||||
await tester.tapGridFieldWithName('New field 1');
|
||||
await tester.tapHidePropertyButton();
|
||||
// insert new field to the right
|
||||
await tester.tapGridFieldWithName('Type');
|
||||
await tester.tapInsertFieldButton(left: true, name: "Left");
|
||||
await tester.dismissFieldEditor();
|
||||
await tester.findFieldWithName('Left');
|
||||
|
||||
await tester.noFieldWithName('New field 1');
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('create checklist field ', (tester) async {
|
||||
testWidgets('create checklist field', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
await tester.scrollToRight(find.byType(GridPage));
|
||||
await tester.tapNewPropertyButton();
|
||||
@@ -150,7 +153,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
for (final fieldType in [
|
||||
FieldType.Checklist,
|
||||
@@ -182,7 +185,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
layout: ViewLayoutPB.Grid,
|
||||
);
|
||||
|
||||