mirror of https://github.com/tasks/tasks
Compare commits
1077 Commits
Author | SHA1 | Date |
---|---|---|
renovate[bot] | 3986fe1431 | 2 months ago |
renovate[bot] | ceac030ca5 | 2 months ago |
renovate[bot] | 66ef650e2c | 2 months ago |
renovate[bot] | 73529cfe35 | 2 months ago |
renovate[bot] | 41e2ee3416 | 2 months ago |
Don Zouras | 456d063243 | 2 months ago |
Abdullhakim Sami Alshanqiti | aff90cb740 | 2 months ago |
Don Zouras | ecfdac5401 | 2 months ago |
tct123 | 0f8199b1c8 | 2 months ago |
Luna | d7f77913ff | 2 months ago |
Don Zouras | a4d1b683dd | 2 months ago |
bittin1ddc447d824349b2 | 4d5b1a604a | 2 months ago |
bittin1ddc447d824349b2 | f6e103d4e1 | 2 months ago |
Anonymous | 1e3850127e | 2 months ago |
Ettore Atalan | e24eb0d933 | 2 months ago |
dependabot[bot] | 13d4c029e8 | 2 months ago |
renovate[bot] | 17bb50efb4 | 2 months ago |
renovate[bot] | 8b685da563 | 2 months ago |
dependabot[bot] | 6dce036427 | 2 months ago |
renovate[bot] | a6c05fe600 | 2 months ago |
renovate[bot] | adb4d20c12 | 2 months ago |
Alex Baker | 865cec7220 | 2 months ago |
Jose Delvani | fcc4b2ef2a | 2 months ago |
Luna | 2a194bdcb0 | 2 months ago |
Pierfrancesco Passerini | 0b463fe331 | 2 months ago |
Luna | 0b34b2630c | 2 months ago |
renovate[bot] | 46cc225ceb | 2 months ago |
renovate[bot] | 34750e052c | 2 months ago |
renovate[bot] | 71cdabad8b | 2 months ago |
Jose Delvani | ffd5806bc8 | 2 months ago |
Pierfrancesco Passerini | 33734e031f | 2 months ago |
Kat Alimpieva | b67f849c53 | 2 months ago |
Jose Delvani | e88220cc70 | 2 months ago |
RonnyAL182e77f4e26446af | b4ced4698a | 2 months ago |
Alex Baker | 4aee7ee2fe | 2 months ago |
Alex Baker | 3ab672bfbc | 2 months ago |
Alex Baker | f66df67592 | 2 months ago |
renovate[bot] | 4f3df04921 | 2 months ago |
Alex Baker | 25557579f9 | 2 months ago |
Jonatan Nyberg | 40ec1d86f7 | 2 months ago |
Tntdruid | 42d4cbc7fb | 2 months ago |
Milo Ivir | fb2cd132de | 2 months ago |
Marc Van Impe | 435c42920d | 2 months ago |
Tntdruid | 8373e8238e | 2 months ago |
Milo Ivir | e1f50c5cf4 | 2 months ago |
renovate[bot] | 75f1f057aa | 2 months ago |
Alex Baker | 2566b86fec | 2 months ago |
Alex Baker | e6cb93c57d | 2 months ago |
Alex Baker | 5314736958 | 2 months ago |
Alex Baker | 12f8ba360c | 2 months ago |
Alex Baker | 5f0b6b668a | 3 months ago |
109247019824 | aadcb6355f | 3 months ago |
renovate[bot] | 4491eb1cc6 | 3 months ago |
renovate[bot] | 6d023303cf | 3 months ago |
renovate[bot] | 81dd8fc2ea | 3 months ago |
renovate[bot] | bb7209a07f | 3 months ago |
renovate[bot] | a7b92ecb4b | 3 months ago |
Alex Baker | c2bd95ed06 | 3 months ago |
Alex Baker | da1139f6a4 | 3 months ago |
Alex Baker | 0ba6164ac9 | 3 months ago |
Alex Baker | 9894919f49 | 3 months ago |
Alex Baker | 7731b90672 | 3 months ago |
Alex Baker | 8f4514fc78 | 3 months ago |
Alex Baker | d3421bd0c3 | 3 months ago |
renovate[bot] | 65f3240ce6 | 3 months ago |
renovate[bot] | c9f4242c2a | 3 months ago |
renovate[bot] | 4cdf7efef2 | 3 months ago |
renovate[bot] | b45588410d | 3 months ago |
Alex Baker | 8f68811a59 | 3 months ago |
Alex Baker | 93f1735965 | 3 months ago |
Alex Baker | 686b141bb8 | 3 months ago |
Alex Baker | 41f8835717 | 3 months ago |
Alex Baker | 1acb2a3658 | 3 months ago |
renovate[bot] | 6275dfbd36 | 3 months ago |
Alex Baker | bd7ad1ad9d | 3 months ago |
Alex Baker | 64ad4ca33a | 3 months ago |
Alex Baker | 6700ce5aa1 | 3 months ago |
Ihor Hordiichuk | 0422412cb9 | 3 months ago |
Alex Baker | e7ce174ffe | 3 months ago |
Ihor Hordiichuk | 4956a136fa | 3 months ago |
Alex Baker | a067651c23 | 3 months ago |
Alex Baker | 83e43ba72c | 3 months ago |
Alex Baker | f8633bbd63 | 3 months ago |
Alex Baker | ddfedb58ae | 3 months ago |
Alex Baker | ca5b7daa36 | 3 months ago |
Alex Baker | ba8d56cc96 | 3 months ago |
Alex Baker | a538c25dcc | 3 months ago |
Alex Baker | 939f801382 | 3 months ago |
Alex Baker | dbff9758ef | 3 months ago |
Josep Torrens | beb44f7634 | 3 months ago |
Sergi Ventosa Ordóñez | 131ab0747f | 3 months ago |
hugoalh | 21ebf7c867 | 3 months ago |
大王叫我来巡山 | 27c0530825 | 3 months ago |
Jose Delvani | 1fc04af48e | 3 months ago |
Florian Trayon | 6622f16b14 | 3 months ago |
gallegonovato | b2d2a614de | 3 months ago |
109247019824 | f7211a45e0 | 3 months ago |
Oğuz Ersen | e7140fd042 | 3 months ago |
Alex Baker | 00d2ef4916 | 3 months ago |
大王叫我来巡山 | bf818ee817 | 3 months ago |
hugoalh | 15cc9c1b56 | 3 months ago |
Florian Trayon | 31aea94d07 | 3 months ago |
gallegonovato | 82ae20bfc8 | 3 months ago |
109247019824 | 94b7e04444 | 3 months ago |
Jose Delvani | ae1c15cd1e | 3 months ago |
Oğuz Ersen | edb09ebbb5 | 3 months ago |
Alex Baker | eef736a3c1 | 3 months ago |
Alex Baker | 95bc9aa6f2 | 3 months ago |
Alex Baker | 33798b3255 | 3 months ago |
Alex Baker | 053cffd389 | 3 months ago |
Alex Baker | bf3da3249d | 3 months ago |
Alex Baker | 05fbdaba88 | 3 months ago |
Alex Baker | b4b5d8d80f | 3 months ago |
Alex Baker | 86f23a0768 | 3 months ago |
Alex Baker | 72759e67d2 | 3 months ago |
Alex Baker | ae6b068b66 | 3 months ago |
Alex Baker | 0ce07152cf | 3 months ago |
Alex Baker | ec94d92e11 | 3 months ago |
Alex Baker | 2c62d928d3 | 3 months ago |
Alex Baker | 4c727722c3 | 3 months ago |
Alex Baker | bfe8d1c929 | 3 months ago |
Alex Baker | 9cd8af6d78 | 3 months ago |
Alex Baker | 08da2f56a6 | 3 months ago |
Alex Baker | 7d52d58f3d | 3 months ago |
Alex Baker | 282042538c | 3 months ago |
Alex Baker | 8ccab99f23 | 3 months ago |
Alex Baker | f459541902 | 3 months ago |
renovate[bot] | c2feb2144f | 3 months ago |
renovate[bot] | 22366a8de6 | 3 months ago |
renovate[bot] | 5ae53e63ff | 3 months ago |
CSharpest | 00c3a117ac | 3 months ago |
Rami Lehtinen | 922dd861b0 | 3 months ago |
Alex Baker | 4770acbd65 | 3 months ago |
Alex Baker | 45911b149a | 3 months ago |
Alex Baker | 9f7dfc11ec | 3 months ago |
Alex Baker | 0b76553122 | 3 months ago |
Alex Baker | 8ac5d51308 | 3 months ago |
Alex Baker | 4f2d676ae4 | 3 months ago |
Alex Baker | 59d81f5755 | 3 months ago |
Alex Baker | 8547fa2459 | 3 months ago |
Milo Ivir | 6bb1a9748c | 3 months ago |
gallegonovato | 81a0034cba | 3 months ago |
renovate[bot] | 475ff37d70 | 3 months ago |
renovate[bot] | 2015f8d0ef | 3 months ago |
Alex Baker | 8c9b996cb8 | 3 months ago |
Alex Baker | 87ae179efc | 3 months ago |
Alex Baker | 79ebc9a2c7 | 3 months ago |
Alex Baker | bf4167651b | 3 months ago |
renovate[bot] | b990716502 | 3 months ago |
Alex Baker | 285b0a9486 | 3 months ago |
Alex Baker | 01a788bdb6 | 3 months ago |
大王叫我来巡山 | 12c7170a0b | 3 months ago |
Oğuz Ersen | aa278922f5 | 3 months ago |
Jose Delvani | 2be5d3bbbc | 3 months ago |
renovate[bot] | 7673710d44 | 3 months ago |
Alex Baker | cb31651c2a | 3 months ago |
Alex Baker | fb7960bf26 | 3 months ago |
renovate[bot] | fecfea8df5 | 3 months ago |
Alex Baker | 6ce170533e | 3 months ago |
Alex Baker | ad4d938b94 | 3 months ago |
renovate[bot] | 1702249abc | 3 months ago |
renovate[bot] | b52d954731 | 3 months ago |
Alex Baker | a1a02faf3d | 3 months ago |
Alex Baker | 9307b8fb7d | 3 months ago |
Alex Baker | 8b345316a8 | 3 months ago |
Alex Baker | ab0f123c8a | 3 months ago |
renovate[bot] | 36a28b6210 | 3 months ago |
renovate[bot] | d2ae1008f5 | 3 months ago |
Alex Baker | 17af8ab373 | 3 months ago |
renovate[bot] | e78d452d7b | 3 months ago |
renovate[bot] | e9ddf29b9c | 3 months ago |
renovate[bot] | 898c88bec9 | 3 months ago |
renovate[bot] | 184e7def49 | 3 months ago |
Alex Baker | d8186e5fe4 | 3 months ago |
Alex Baker | a4cd0829b0 | 3 months ago |
Alex Baker | 9a693177db | 3 months ago |
Alex Baker | 58955bd0a1 | 3 months ago |
renovate[bot] | 95ecac8e7c | 3 months ago |
renovate[bot] | 57395423c6 | 3 months ago |
renovate[bot] | b1613e9845 | 3 months ago |
renovate[bot] | dcd70c7bc2 | 3 months ago |
Alex Baker | c1e2eb7cd0 | 4 months ago |
Alex Baker | 145ea03714 | 4 months ago |
Alex Baker | bada09f5c2 | 4 months ago |
Alex Baker | 007c536312 | 4 months ago |
renovate[bot] | 28de989a05 | 4 months ago |
Alex Baker | 97c3852f2f | 4 months ago |
hugoalh | f739cac8b4 | 4 months ago |
min7-i | cd6a474cce | 4 months ago |
Jose Delvani | 4ffc11903e | 4 months ago |
Jose Delvani | 70d6cc63ca | 4 months ago |
islam2hamy | 6e97e602c9 | 4 months ago |
Alex Baker | 3251becf9b | 4 months ago |
Alex Baker | d9293c7262 | 4 months ago |
Alex Baker | 929a01cd8c | 4 months ago |
Alex Baker | 0d5803b9ca | 4 months ago |
Alex Baker | bbaaf27386 | 4 months ago |
Alex Baker | 4c1121869d | 4 months ago |
Alex Baker | b918e87e05 | 4 months ago |
Alex Baker | df8f637239 | 4 months ago |
Alex Baker | 9fad43c6c9 | 4 months ago |
Alex Baker | eb95cd24d7 | 4 months ago |
Alex Baker | 30cb374a21 | 4 months ago |
Alex Baker | b09a8967e4 | 4 months ago |
Alex Baker | 39b56296bd | 4 months ago |
Alex Baker | 1d8d2efce6 | 4 months ago |
Alex Baker | c9af39b6ba | 4 months ago |
renovate[bot] | f8bb045d76 | 4 months ago |
renovate[bot] | 4040a2379b | 4 months ago |
Alex Baker | c4ee7479ca | 4 months ago |
Alex Baker | be861597ef | 4 months ago |
Alex Baker | f27332595d | 4 months ago |
Alex Baker | ea7f051d85 | 4 months ago |
Alex Baker | 8be7fab033 | 4 months ago |
Alex Baker | d6e0c0bdcf | 4 months ago |
Alex Baker | 5ec02011f8 | 4 months ago |
Alex Baker | b35090cd43 | 4 months ago |
renovate[bot] | 92f62450ae | 4 months ago |
renovate[bot] | 3ca6912492 | 4 months ago |
renovate[bot] | 080b1428dd | 4 months ago |
Alex Baker | f67c3bc56c | 4 months ago |
renovate[bot] | 5d0e88a620 | 4 months ago |
renovate[bot] | c5d5795fe2 | 4 months ago |
renovate[bot] | 3bbc0e0ab0 | 4 months ago |
Alex Baker | 009a195580 | 4 months ago |
renovate[bot] | 772f69d8c0 | 4 months ago |
renovate[bot] | 4229bf7067 | 4 months ago |
Alex Baker | 212a4b0a3d | 4 months ago |
Alex Baker | 4ddfe937b0 | 4 months ago |
Alex Baker | 19de0e08a5 | 4 months ago |
Alex Baker | 60211355e0 | 4 months ago |
Alex Baker | 17d218aa4e | 4 months ago |
Alex Baker | 505c8c29d5 | 4 months ago |
Alex Baker | 7149308c97 | 4 months ago |
Alex Baker | 2c5a497007 | 4 months ago |
Alex Baker | 09f53fe1e5 | 4 months ago |
Alex Baker | 5da4183aed | 4 months ago |
Alex Baker | d35912e503 | 4 months ago |
renovate[bot] | 82fd99f83e | 4 months ago |
renovate[bot] | f944becea1 | 4 months ago |
Alex Baker | acd713dc5b | 4 months ago |
Alex Baker | 1a93c87ad9 | 4 months ago |
Alex Baker | c4e25b8b15 | 4 months ago |
Alex Baker | e11c0d2528 | 4 months ago |
Alex Baker | 2fc6833854 | 4 months ago |
Alex Baker | 4a2fb13d10 | 4 months ago |
Alex Baker | a2572e2dee | 4 months ago |
Alex Baker | 64e05c9f8f | 4 months ago |
Alex Baker | ad833b5f49 | 4 months ago |
Alex Baker | eea944cc7b | 4 months ago |
Alex Baker | c82dfc7d39 | 4 months ago |
Alex Baker | 8607f9556a | 4 months ago |
Alex Baker | f338e84d46 | 4 months ago |
Alex Baker | 9ee739627e | 4 months ago |
Alex Baker | a49c233584 | 4 months ago |
Alex Baker | 74fca07c1b | 4 months ago |
Alex Baker | 5bd0cef42e | 4 months ago |
Alex Baker | 4c245edbb4 | 4 months ago |
Alex Baker | 97a3f074d0 | 4 months ago |
Alex Baker | 86ecd3cf81 | 4 months ago |
Alex Baker | 07a2eda5ea | 4 months ago |
renovate[bot] | 09ffbdd036 | 4 months ago |
renovate[bot] | 60f22146ca | 4 months ago |
renovate[bot] | c11225abaf | 4 months ago |
dependabot[bot] | 133ea493e3 | 4 months ago |
Alex Baker | 0ba901be69 | 5 months ago |
Alex Baker | ebe5e5c009 | 5 months ago |
Alex Baker | d556863fda | 5 months ago |
Alex Baker | 55adbc2025 | 5 months ago |
Alex Baker | 06c4255886 | 5 months ago |
renovate[bot] | 4734a99bae | 5 months ago |
Alex Baker | a6a8cac8e4 | 5 months ago |
Alex Baker | c3fc9a57cc | 5 months ago |
Alex Baker | 6e14d07d0c | 5 months ago |
Alex Baker | 6118121698 | 5 months ago |
Alex Baker | 6bf3bd4d08 | 5 months ago |
Alex Baker | 065be79355 | 5 months ago |
Alex Baker | f8f8ba3c51 | 5 months ago |
Alex Baker | 89465f36b3 | 5 months ago |
Alex Baker | 1380a34ffa | 5 months ago |
Alex Baker | 10af5280a3 | 5 months ago |
Alex Baker | 8c0f7b952d | 5 months ago |
Alex Baker | 65362b203f | 5 months ago |
Alex Baker | 3327f97a17 | 5 months ago |
Alex Baker | c9fc02a42e | 5 months ago |
renovate[bot] | 93670bb9e4 | 5 months ago |
Alex Baker | 1fc6a50d0b | 5 months ago |
Alex Baker | e1ef924909 | 5 months ago |
Alex Baker | 686cb5d346 | 5 months ago |
renovate[bot] | ebec25c4cb | 5 months ago |
renovate[bot] | c140f7e673 | 5 months ago |
renovate[bot] | efbcf11a4a | 5 months ago |
renovate[bot] | 6adee85a37 | 5 months ago |
Alex Baker | 5c8643110b | 5 months ago |
Alex Baker | abd13aeb75 | 5 months ago |
Alex Baker | c210fe1893 | 5 months ago |
Alex Baker | 26aa916c20 | 5 months ago |
renovate[bot] | 1eff2d1cd5 | 5 months ago |
islam2hamy | c90e683ea3 | 5 months ago |
Alex Baker | 3cd0295b71 | 5 months ago |
Alex Baker | 95c351e9fd | 5 months ago |
renovate[bot] | 4ddb7816f1 | 5 months ago |
renovate[bot] | 91c30f7bbf | 5 months ago |
renovate[bot] | 3f4398b6e0 | 5 months ago |
renovate[bot] | c822e989a3 | 5 months ago |
renovate[bot] | da146723e5 | 5 months ago |
109247019824 | 931626c84a | 5 months ago |
Alex Baker | c534632c52 | 5 months ago |
Alex Baker | c1347a7455 | 5 months ago |
renovate[bot] | 9544909a58 | 5 months ago |
Yurt Page | 5c10dce2b9 | 5 months ago |
Alex Baker | 584d4a5cbb | 5 months ago |
Alex Baker | 7c68a7fa59 | 5 months ago |
purushottamyadavbattula | 215cc838ef | 5 months ago |
Alex Baker | d60472d1bc | 5 months ago |
Alex Baker | f84a37a60a | 5 months ago |
Alex Baker | 7fb85b6da1 | 5 months ago |
Alex Baker | dc90e583e4 | 5 months ago |
Don Zouras | 0eac5f61eb | 5 months ago |
Milo Ivir | c686ce883d | 5 months ago |
大王叫我来巡山 | ab25398cd0 | 5 months ago |
renovate[bot] | 3b1c133d22 | 5 months ago |
renovate[bot] | 3bfd0ab4f8 | 5 months ago |
Liz de Sartiges | ffc0113d7f | 5 months ago |
Don Zouras | 9de9718ad5 | 5 months ago |
Oğuz Ersen | a7d2c9c406 | 5 months ago |
gallegonovato | b3006b9ac2 | 5 months ago |
Don Zouras | de3ef1f9c9 | 5 months ago |
Alex Baker | ce9e722a3f | 5 months ago |
Alex Baker | 4b892a0eb1 | 5 months ago |
Hady | e6e275834a | 5 months ago |
Alex Baker | 782f4d6d7c | 5 months ago |
elmuffo | a1da71d3e1 | 5 months ago |
Alex Baker | c793a300cc | 5 months ago |
Ilya Bizyaev | bf84bf9e82 | 5 months ago |
SC | 363b29babb | 5 months ago |
min7-i | c1ff953f5c | 6 months ago |
Alex Baker | 63482e5db9 | 6 months ago |
Emin Tufan Çetin | 2f7dc0c7f1 | 6 months ago |
Lionel HANNEQUIN | d672507fae | 6 months ago |
Jonatan Nyberg | ce2a3c8a3f | 6 months ago |
sorifukobexomajepasiricupuva33 | 9cd114d68b | 6 months ago |
Patrick V. Leguizamon | 0e663f0e08 | 6 months ago |
Mayhm | 1d1efd008d | 6 months ago |
Alex Baker | 26ab3d5866 | 6 months ago |
Mayhm | 9a4fcbbd39 | 6 months ago |
Alex Baker | 72bfda9224 | 6 months ago |
Alex Baker | 1067de4183 | 6 months ago |
Alex Baker | d686b8c7e0 | 6 months ago |
Alex Baker | b2efb42d55 | 6 months ago |
Fabio Parri | 3448808c94 | 6 months ago |
Alex Baker | 06a9626052 | 6 months ago |
Alex Baker | e92ab7f7e1 | 6 months ago |
Alex Baker | 4ff7b18c0f | 6 months ago |
Alex Baker | 91887f6b17 | 6 months ago |
Alex Baker | cf30b56098 | 6 months ago |
Alex Baker | 9bcadaab5a | 6 months ago |
Alex Baker | be766074b0 | 6 months ago |
Ihor Hordiichuk | 64a42a3f61 | 6 months ago |
Mayhm | 7b65ba6f06 | 6 months ago |
109247019824 | ac2b270e9e | 6 months ago |
Alex Baker | db2ea0a039 | 6 months ago |
renovate[bot] | 08b78fe9f4 | 6 months ago |
Alex Baker | 1a1301ae3e | 6 months ago |
Milo Ivir | d00061aa7f | 6 months ago |
大王叫我来巡山 | 45add6ab32 | 6 months ago |
Pierfrancesco Passerini | af43737c4e | 6 months ago |
macpac59 | dd40e59b17 | 6 months ago |
gallegonovato | 13f3248a01 | 6 months ago |
renovate[bot] | f6972e3e30 | 6 months ago |
Alex Baker | 83cf48a836 | 6 months ago |
Alex Baker | b7b4747a04 | 6 months ago |
Alex Baker | 6bec2ceef0 | 6 months ago |
Milo Ivir | d1e60d6512 | 6 months ago |
bittin1ddc447d824349b2 | 2b85089d3a | 6 months ago |
ferranpujolcamins | 2a0ef9feb6 | 6 months ago |
109247019824 | 33adbbd884 | 6 months ago |
Alex Baker | c25eb2e0c5 | 6 months ago |
Alex Baker | 14026356eb | 6 months ago |
Alex Baker | b328651dd4 | 6 months ago |
Alex Baker | a0e9bfabeb | 6 months ago |
大王叫我来巡山 | a1ad421b33 | 6 months ago |
Mayhm | 3488a08af1 | 6 months ago |
gallegonovato | b71d1af516 | 6 months ago |
Alex Baker | 041dce8617 | 6 months ago |
Alex Baker | 3d92ca78dd | 6 months ago |
Alex Baker | a32fce2d8b | 6 months ago |
Alex Baker | 4fb3cda173 | 6 months ago |
Alex Baker | f33cc896dd | 6 months ago |
Alex Baker | 4d1d6a06a8 | 7 months ago |
Alex Baker | 2202516688 | 7 months ago |
Alex Baker | d4a5008ecb | 7 months ago |
Alex Baker | 08189e10f1 | 7 months ago |
Anonymous | d3e4c066d8 | 7 months ago |
Anonymous | bbc5ae4d6d | 7 months ago |
Anonymous | c6cc00cf07 | 7 months ago |
Anonymous | 22e8720021 | 7 months ago |
Anonymous | a3ce98f0ea | 7 months ago |
macpac59 | 258f607d52 | 7 months ago |
ngocanhtve | 927acae7e4 | 7 months ago |
Odweta | 49ad9bafe3 | 7 months ago |
Alex Baker | 6df616d9ce | 7 months ago |
Alex Baker | 157668e35a | 7 months ago |
Aslam Karachiwala | efdf343869 | 7 months ago |
renovate[bot] | 5606df17c5 | 7 months ago |
renovate[bot] | fc3b4971f4 | 7 months ago |
renovate[bot] | 6a1699bb33 | 7 months ago |
renovate[bot] | e49303d5ca | 7 months ago |
renovate[bot] | 4b55569b51 | 7 months ago |
renovate[bot] | 2d7145cde3 | 7 months ago |
renovate[bot] | f2ab8bed95 | 7 months ago |
renovate[bot] | a5bc4cf536 | 7 months ago |
renovate[bot] | 1b35372b3a | 7 months ago |
Alex Baker | c0fd4bf66a | 7 months ago |
renovate[bot] | 5d366f0d61 | 7 months ago |
renovate[bot] | d0635ac6f3 | 7 months ago |
renovate[bot] | 8d4cf4daa5 | 7 months ago |
renovate[bot] | d1e439e70e | 7 months ago |
renovate[bot] | 4d4c3e5193 | 7 months ago |
Alex Baker | 20f87061fd | 8 months ago |
renovate[bot] | c03e3747c6 | 8 months ago |
renovate[bot] | 925b1b9124 | 8 months ago |
Alex Baker | 43db712f64 | 8 months ago |
Alex Baker | 9d33a73ee6 | 8 months ago |
renovate[bot] | 391c600ce2 | 8 months ago |
renovate[bot] | ee4ae94817 | 8 months ago |
renovate[bot] | 70b4be1447 | 8 months ago |
Don Zouras | bc54d92789 | 8 months ago |
Сергій | 2f34724b95 | 8 months ago |
Alex Baker | 940fdc28dd | 8 months ago |
Alex Baker | 68542fce38 | 8 months ago |
renovate[bot] | 7ba2977100 | 8 months ago |
Don Zouras | cb242539f0 | 8 months ago |
bittin1ddc447d824349b2 | 304841f2c3 | 8 months ago |
Don Zouras | 819ea797e6 | 8 months ago |
abc0922001 | 2dbea57262 | 8 months ago |
Don Zouras | 516a916fd5 | 8 months ago |
109247019824 | 3bd52efc80 | 8 months ago |
renovate[bot] | 64af955ea7 | 8 months ago |
Milo Ivir | 4cc5ec9639 | 8 months ago |
大王叫我来巡山 | 0d9292e53a | 8 months ago |
Oğuz Ersen | 732ccf1913 | 8 months ago |
gallegonovato | a2852bdbbf | 8 months ago |
Don Zouras | 68790ad401 | 8 months ago |
Alex Baker | e9afacb595 | 8 months ago |
Alex Baker | cf182aceab | 8 months ago |
Alex Baker | db889d233a | 8 months ago |
Alex Baker | 457b89c092 | 8 months ago |
Don Zouras | ad53af1b6a | 8 months ago |
renovate[bot] | 2c32b08c97 | 8 months ago |
renovate[bot] | a2fcf57c9e | 8 months ago |
renovate[bot] | 59a61325f2 | 8 months ago |
vulewuxe86 | 38a6064677 | 8 months ago |
renovate[bot] | 67daccf3e8 | 8 months ago |
renovate[bot] | dfe829d2a1 | 8 months ago |
renovate[bot] | 23c64f4d28 | 8 months ago |
renovate[bot] | e4b8f694f3 | 8 months ago |
renovate[bot] | e667c80731 | 8 months ago |
renovate[bot] | 909b077e25 | 8 months ago |
Don Zouras | e6fab9ad45 | 8 months ago |
raulmagdalena | 9474f5b7af | 8 months ago |
Don Zouras | 1ee051d768 | 8 months ago |
Don Zouras | f42edaa158 | 8 months ago |
RayBB | b97eade59c | 8 months ago |
renovate[bot] | 41aa1ca65f | 8 months ago |
renovate[bot] | 3e9a13ea14 | 8 months ago |
renovate[bot] | d966e8a12b | 9 months ago |
renovate[bot] | 8ba4e64994 | 9 months ago |
109247019824 | ee792f1ceb | 9 months ago |
renovate[bot] | caa09163a1 | 9 months ago |
renovate[bot] | d270abf5b3 | 9 months ago |
renovate[bot] | 1ef530abad | 9 months ago |
renovate[bot] | df26a6dbb9 | 9 months ago |
renovate[bot] | 1882c3b7e0 | 9 months ago |
renovate[bot] | cb53a0ca9f | 9 months ago |
renovate[bot] | b2fdef1ae7 | 9 months ago |
renovate[bot] | defb16ce95 | 9 months ago |
renovate[bot] | 823f99b28a | 9 months ago |
renovate[bot] | 6df872b1a1 | 10 months ago |
renovate[bot] | 133b960583 | 10 months ago |
renovate[bot] | 2e6753faec | 10 months ago |
renovate[bot] | cb07c2c267 | 10 months ago |
renovate[bot] | 23757ab320 | 10 months ago |
Alex Baker | 1b6ce0e48e | 10 months ago |
Kakaeo | 5af012068f | 10 months ago |
Alex Baker | 6c9ffa57d7 | 10 months ago |
Alex Baker | 52c54b1eac | 10 months ago |
Alex Baker | c8d81b44b6 | 10 months ago |
renovate[bot] | ef27a50e42 | 10 months ago |
Alex Baker | bde1356e7f | 10 months ago |
Alex Baker | 6c031925ba | 10 months ago |
Alex Baker | 8058414137 | 10 months ago |
Alex Baker | 3e37ea50f0 | 10 months ago |
renovate[bot] | 62f5a9c492 | 10 months ago |
renovate[bot] | a84fd65722 | 10 months ago |
renovate[bot] | 517b2d8f1b | 10 months ago |
renovate[bot] | 90942bf0be | 10 months ago |
Alex Baker | 83c3d1c4ba | 10 months ago |
Software In Interlingua | 6362ece569 | 10 months ago |
renovate[bot] | 8df85041b8 | 10 months ago |
ngocanhtve | 6d85af4c34 | 10 months ago |
Olli | 63f001dd72 | 10 months ago |
renovate[bot] | de49a50944 | 10 months ago |
renovate[bot] | df20d2f593 | 10 months ago |
renovate[bot] | fd16772236 | 10 months ago |
renovate[bot] | b77caac255 | 10 months ago |
renovate[bot] | ad058ed09b | 10 months ago |
Alex Baker | 8312113d7b | 10 months ago |
Alex Baker | ee21cc660e | 10 months ago |
Alex Baker | 5edc481ffe | 10 months ago |
Alex Baker | d0360a4862 | 10 months ago |
Alex Baker | ac35002408 | 10 months ago |
Subham Jena | 582ebad0f0 | 10 months ago |
Shaban Mamedov | 684c47184a | 10 months ago |
ngocanhtve | ac7a519e4e | 10 months ago |
renovate[bot] | 5c2b41af9d | 11 months ago |
renovate[bot] | 13986cf380 | 11 months ago |
CennoxX | c4f0b404e9 | 11 months ago |
Alex Baker | 145b5afbc6 | 11 months ago |
elig0n | 0b87a206fe | 11 months ago |
mm4c | d0e70ceea8 | 11 months ago |
J. Lavoie | bf3546a878 | 11 months ago |
Alex Baker | 8895acbf6b | 11 months ago |
Alex Baker | a52b1200f5 | 11 months ago |
renovate[bot] | 23964e807a | 11 months ago |
Alex Baker | 287b106dd4 | 11 months ago |
renovate[bot] | 33bab626e0 | 11 months ago |
renovate[bot] | a980cd75cc | 11 months ago |
renovate[bot] | 7eac4ac223 | 11 months ago |
renovate[bot] | 82cb2f7d3f | 11 months ago |
renovate[bot] | da2646597c | 11 months ago |
renovate[bot] | 495855133c | 11 months ago |
renovate[bot] | 242cb61662 | 11 months ago |
renovate[bot] | ab8886f3dc | 11 months ago |
Alex Baker | e48e92d2e6 | 11 months ago |
Alex Baker | 5f22f5cd38 | 11 months ago |
Alex Baker | 8a47cc2934 | 11 months ago |
Alex Baker | 0d94729d37 | 11 months ago |
Alex Baker | 14599eb3c0 | 11 months ago |
Alex Baker | b477623524 | 11 months ago |
Alex Baker | c8bfb67b50 | 11 months ago |
Alex Baker | 0a36e58525 | 11 months ago |
Alex Baker | 94a719cb66 | 11 months ago |
Alex Baker | b5748aa8e6 | 11 months ago |
Alex Baker | 7fd5647cb8 | 11 months ago |
Alex Baker | 2545832d67 | 11 months ago |
Alex Baker | 738bf435db | 11 months ago |
renovate[bot] | ab02323f29 | 11 months ago |
Alex Baker | d73a9d2795 | 11 months ago |
Alex Baker | ebe67354b6 | 11 months ago |
Alex Baker | 58edc6b4d8 | 11 months ago |
Weblate (bot) | 78b2cdac06 | 11 months ago |
renovate[bot] | c3d7db0087 | 11 months ago |
renovate[bot] | d7b1770b85 | 11 months ago |
Weblate (bot) | bebb3165a5 | 11 months ago |
Alex Baker | ad1198aace | 11 months ago |
Alex Baker | 7ae77a81e1 | 11 months ago |
Weblate (bot) | 3e79dd5190 | 11 months ago |
renovate[bot] | 9d57a849bf | 11 months ago |
Alex Baker | 82103eb477 | 11 months ago |
renovate[bot] | 11fa9a2bbd | 11 months ago |
renovate[bot] | b65831120f | 11 months ago |
renovate[bot] | f26a90a4f9 | 11 months ago |
renovate[bot] | dd3aa20485 | 11 months ago |
renovate[bot] | 8c84e1af50 | 11 months ago |
renovate[bot] | dc1eac23b9 | 11 months ago |
renovate[bot] | 5883952883 | 11 months ago |
Alex Baker | 775289b058 | 11 months ago |
Alex Baker | ee500c24b1 | 12 months ago |
Igor Sorocean | 68fd36b14d | 12 months ago |
renovate[bot] | b8f265fa36 | 12 months ago |
Alex Baker | cf4e6c1273 | 12 months ago |
renovate[bot] | 0dcc577497 | 12 months ago |
kmj-99 | b525e8cab3 | 12 months ago |
renovate[bot] | db0ad280eb | 12 months ago |
Alex Baker | 5092f80dcc | 12 months ago |
Kazushi Hayama | 6bc42363dd | 12 months ago |
Michal Šmahel | 115461c7b0 | 12 months ago |
renovate[bot] | 369c508890 | 12 months ago |
bittin1ddc447d824349b2 | a432cc33cc | 12 months ago |
Alex Baker | e5b51150cb | 12 months ago |
renovate[bot] | d43639556e | 12 months ago |
Alex Baker | ef2dd8f202 | 12 months ago |
Alex Baker | abc099c309 | 12 months ago |
Alex Baker | 348367e084 | 12 months ago |
renovate[bot] | 6a73f6745c | 12 months ago |
renovate[bot] | 5185c14e44 | 12 months ago |
Olli | aa7ff0fa16 | 12 months ago |
renovate[bot] | 12b979d363 | 12 months ago |
Alex Baker | 082f741983 | 12 months ago |
Alex Baker | 0bdd83988f | 12 months ago |
Alex Baker | 60784c10b5 | 12 months ago |
Alex Baker | da8467ac56 | 12 months ago |
renovate[bot] | 434d067822 | 12 months ago |
renovate[bot] | 04af310285 | 12 months ago |
renovate[bot] | 5555771f45 | 12 months ago |
renovate[bot] | 35b60df0ff | 12 months ago |
renovate[bot] | fef19b4995 | 12 months ago |
Alex Baker | 4c25b81a4d | 12 months ago |
Alex Baker | 0f37f4859e | 12 months ago |
Alex Baker | ee3d3fa4f5 | 12 months ago |
Alex Baker | a32d35720a | 12 months ago |
Alex Baker | bf6fe02fe3 | 1 year ago |
Alex Baker | 6664defc16 | 1 year ago |
renovate[bot] | b318b930a5 | 1 year ago |
Loucura | 91d18fd675 | 1 year ago |
Alex Baker | 94b6d7569b | 1 year ago |
Alex Baker | e70f5f3b24 | 1 year ago |
renovate[bot] | 68c21c4b1f | 1 year ago |
renovate[bot] | cbcc7f9bee | 1 year ago |
Milo Ivir | ba394b9db4 | 1 year ago |
Eric | 13298aa3be | 1 year ago |
Alex Baker | 993c41b197 | 1 year ago |
Alex Baker | 2bfc46f32b | 1 year ago |
Alex Baker | 4c61353411 | 1 year ago |
Alex Baker | f8d3985e97 | 1 year ago |
Alex Baker | c2a9d21f01 | 1 year ago |
Alex Baker | 20c81417a0 | 1 year ago |
Alex Baker | 77c86bbfb4 | 1 year ago |
renovate[bot] | 7e9ec26f53 | 1 year ago |
Alex Baker | 928ec9f647 | 1 year ago |
Alex Baker | 84ab8d0517 | 1 year ago |
Alex Baker | db66a66578 | 1 year ago |
Alex Baker | ea8a4b5e2d | 1 year ago |
Alex Baker | 5a4485818f | 1 year ago |
renovate[bot] | 1d348fcac9 | 1 year ago |
renovate[bot] | 79250cb8ff | 1 year ago |
renovate[bot] | 5d550df62e | 1 year ago |
Pierfrancesco Passerini | 1267fbeb0d | 1 year ago |
renovate[bot] | 2b0e285b42 | 1 year ago |
Alex Baker | 374f10c731 | 1 year ago |
abc0922001 | a38fdc065e | 1 year ago |
Ihor Hordiichuk | 6d4159eaac | 1 year ago |
Oğuz Ersen | 20fe494cd9 | 1 year ago |
Frits van Bommel | e7686bd9eb | 1 year ago |
Kaci | d4d721f060 | 1 year ago |
Florian Trayon | 1e9b39afd5 | 1 year ago |
Florian Trayon | 8878df27c4 | 1 year ago |
C. Rüdinger | 07eb9db157 | 1 year ago |
109247019824 | b4ad27152f | 1 year ago |
kmj-99 | 417a1cca46 | 1 year ago |
renovate[bot] | 3a6086adbd | 1 year ago |
Alex Baker | 9f3f0a9698 | 1 year ago |
Alex Baker | 8a085861de | 1 year ago |
Alex Baker | 7048f6a965 | 1 year ago |
Alex Baker | a9cb7b0e89 | 1 year ago |
Alex Baker | 4c7e2caa73 | 1 year ago |
Alex Baker | 3a5e45283a | 1 year ago |
renovate[bot] | a1885574da | 1 year ago |
vulewuxe86 | 113cf6f1b8 | 1 year ago |
renovate[bot] | 138cc21796 | 1 year ago |
Alex Baker | dea3484a2f | 1 year ago |
Alex Baker | 5948e4a958 | 1 year ago |
renovate[bot] | 10d2e8feda | 1 year ago |
renovate[bot] | cef7998a52 | 1 year ago |
renovate[bot] | 834bef7933 | 1 year ago |
renovate[bot] | 8ed6afff2b | 1 year ago |
renovate[bot] | 7d13e4f0ba | 1 year ago |
Alex Baker | 5cb8419206 | 1 year ago |
Alex Baker | 7283491872 | 1 year ago |
Alex Baker | 2de5b3c275 | 1 year ago |
Alex Baker | 864550d027 | 1 year ago |
renovate[bot] | b48348f30e | 1 year ago |
renovate[bot] | 81fdddc631 | 1 year ago |
Luna Jernberg | 21cb25d902 | 1 year ago |
Anaemix | b73ba43735 | 1 year ago |
renovate[bot] | a3ba87e4e6 | 1 year ago |
renovate[bot] | 26321633e2 | 1 year ago |
renovate[bot] | 1c3656a69c | 1 year ago |
renovate[bot] | 88bb66a7b3 | 1 year ago |
renovate[bot] | 0f7c200851 | 1 year ago |
renovate[bot] | f6d5732c07 | 1 year ago |
renovate[bot] | b278a04fce | 1 year ago |
renovate[bot] | 71c2e2b0f6 | 1 year ago |
renovate[bot] | 87639da922 | 1 year ago |
Anaemix | d7e366712c | 1 year ago |
renovate[bot] | 74ecb4a8bf | 1 year ago |
Emin Tufan Çetin | 305bd24883 | 1 year ago |
renovate[bot] | 68b7bef1ca | 1 year ago |
renovate[bot] | f6a6b0716f | 1 year ago |
renovate[bot] | dced669176 | 1 year ago |
Emin Tufan Çetin | 1b431f7a61 | 1 year ago |
Joan Montané | 2b3b7184e0 | 1 year ago |
renovate[bot] | a7062fe937 | 1 year ago |
Alex Baker | 573f6b897e | 1 year ago |
renovate[bot] | e1845d71bc | 1 year ago |
renovate[bot] | 1027d57860 | 1 year ago |
renovate[bot] | a2c92b8fd9 | 1 year ago |
renovate[bot] | 77643d7355 | 1 year ago |
Patrick V. Leguizamon | 54911021a5 | 1 year ago |
renovate[bot] | 908ac19754 | 1 year ago |
Alex Baker | 4ebd53fdf7 | 1 year ago |
Alex Baker | a0fbeba938 | 1 year ago |
Alex Baker | bd6000fcd6 | 1 year ago |
Alex Baker | aa861cb5e5 | 1 year ago |
Alex Baker | 17818c6e29 | 1 year ago |
Poesty Li | ca6521db23 | 1 year ago |
Alex Baker | dedf306106 | 1 year ago |
Alex Baker | 40f9b83dba | 1 year ago |
Alex Baker | c8b057867f | 1 year ago |
Alex Baker | d1ebd45492 | 1 year ago |
Alex Baker | ac28e26333 | 1 year ago |
renovate[bot] | fdf9fbce08 | 1 year ago |
renovate[bot] | 6d712642b3 | 1 year ago |
renovate[bot] | 329939e2b0 | 1 year ago |
Alex Baker | f62de8b7f3 | 1 year ago |
deep map | a2ef184c7d | 1 year ago |
Salif Mehmed | 6ac2c88782 | 1 year ago |
Naga | ada31293ea | 1 year ago |
Pierfrancesco Passerini | 805d914ff4 | 1 year ago |
109247019824 | aa1b4ef71a | 1 year ago |
vulewuxe86 | 3d0cf46f8d | 1 year ago |
abc0922001 | f7e2c7824a | 1 year ago |
Stefan | 2e2bdbe07a | 1 year ago |
Alex Baker | 427ee369b4 | 1 year ago |
Alex Baker | 804c0f974a | 1 year ago |
109247019824 | 691dc635a9 | 1 year ago |
renovate[bot] | 9f2364867b | 1 year ago |
renovate[bot] | cd638bba71 | 1 year ago |
Naga | 156669cb86 | 1 year ago |
Kazushi Hayama | 6c1daf5a3c | 1 year ago |
Pierfrancesco Passerini | 0a297c595f | 1 year ago |
qwerty287 | b698fc04db | 1 year ago |
109247019824 | ab6f3463d0 | 1 year ago |
Alex Baker | dbcaa36812 | 1 year ago |
Alex Baker | 83a42c9d8f | 1 year ago |
Alex Baker | ec97722857 | 1 year ago |
Alex Baker | dd78acadcd | 1 year ago |
Htet Oo Hlaing | 454faa234e | 1 year ago |
bruh | 55027ad625 | 1 year ago |
Alex Tereschenko | 13740c3d0d | 1 year ago |
Alex Tereschenko | 6037ee70e5 | 1 year ago |
Kazushi Hayama | 0f2e659e6f | 1 year ago |
Milo Ivir | 7945ecb9c4 | 1 year ago |
Poesty Li | 56f0be50ff | 1 year ago |
Ihor Hordiichuk | 91d46c5f11 | 1 year ago |
Htet Oo Hlaing | bab3898a7f | 1 year ago |
Alex Baker | 7b12e491ad | 1 year ago |
Alex Baker | ce2bc81276 | 1 year ago |
Frits van Bommel | 39ddc8d0d6 | 1 year ago |
Pierfrancesco Passerini | 8081da3a36 | 1 year ago |
Florian Trayon | 766d5fa043 | 1 year ago |
Florian Trayon | b2135f33c5 | 1 year ago |
109247019824 | d1afb5891a | 1 year ago |
Alex Baker | dff522437d | 1 year ago |
Alex Baker | 5308404ed6 | 1 year ago |
renovate[bot] | 320b399ab3 | 1 year ago |
renovate[bot] | 28c1ecaebc | 1 year ago |
renovate[bot] | 7083eb2ede | 1 year ago |
renovate[bot] | 194edd2084 | 1 year ago |
Michal Šmahel | e21637cb3c | 1 year ago |
Alex Baker | ee82f683bd | 1 year ago |
Alex Baker | 166635e18b | 1 year ago |
Alex Baker | 8ed5242573 | 1 year ago |
Alex Baker | a3d86dcb03 | 1 year ago |
Alex Baker | c065525cef | 1 year ago |
renovate[bot] | 049f995e96 | 1 year ago |
renovate[bot] | 8ac962d9ea | 1 year ago |
renovate[bot] | 849e785189 | 1 year ago |
renovate[bot] | 1b1288678b | 1 year ago |
renovate[bot] | d2710a3c61 | 1 year ago |
renovate[bot] | 0fe5b7fdb9 | 1 year ago |
renovate[bot] | dcf645c2b8 | 1 year ago |
renovate[bot] | 1fcd780b3f | 1 year ago |
renovate[bot] | 5fc3ac2e7f | 1 year ago |
Luna Jernberg | 3ad24f49d8 | 1 year ago |
SC | 5d386bc83a | 1 year ago |
Kaci | c7a65c81d4 | 1 year ago |
Sunjae Choi | 2034a4be74 | 1 year ago |
Sameer Rustamzada | ca4f120433 | 1 year ago |
renovate[bot] | 7c6aae3219 | 1 year ago |
renovate[bot] | 18450e8e2b | 1 year ago |
renovate[bot] | 1181125417 | 1 year ago |
renovate[bot] | e52c80ea3f | 1 year ago |
renovate[bot] | 2474dbab2a | 1 year ago |
renovate[bot] | 049d46ceff | 1 year ago |
renovate[bot] | 6f01f9a590 | 1 year ago |
renovate[bot] | de2f39b2df | 1 year ago |
Naga | 393f7868d8 | 1 year ago |
renovate[bot] | cad6470497 | 1 year ago |
renovate[bot] | 065385d105 | 1 year ago |
renovate[bot] | 159fc3ad50 | 1 year ago |
Alex Baker | f697015d7f | 1 year ago |
Alex Baker | b977f01402 | 1 year ago |
Naga | 07c7297bc8 | 1 year ago |
Gerald Schneider | 7fc81f4876 | 1 year ago |
Naga | 3cebc6f874 | 1 year ago |
Frits van Bommel | 1d997ae411 | 1 year ago |
renovate[bot] | 2e213312fe | 1 year ago |
renovate[bot] | dc7c9aec76 | 1 year ago |
renovate[bot] | 2faff24ac9 | 1 year ago |
Eudald Puy Polls | 045ec4cb3f | 1 year ago |
Milo Ivir | f5a2e9282e | 1 year ago |
Ander Romero | 5ef7b6f786 | 1 year ago |
109247019824 | 936dfb29c9 | 1 year ago |
renovate[bot] | e8ac6ed556 | 1 year ago |
Alex Baker | a45959052b | 1 year ago |
Alex Baker | e1aed0f1af | 1 year ago |
Alex Baker | 52d664856d | 1 year ago |
Alex Baker | 53738031d1 | 1 year ago |
Alex Baker | b0bb58bb4c | 1 year ago |
Alex Baker | 1811eb561f | 1 year ago |
Alex Baker | 6ef2f4a989 | 1 year ago |
renovate[bot] | 6b041dc47d | 1 year ago |
Alex Baker | 2659f4fa4a | 1 year ago |
Alex Baker | 09a1e5bc4f | 1 year ago |
renovate[bot] | cc370557df | 1 year ago |
Poesty Li | d7fc766b49 | 1 year ago |
Ihor Hordiichuk | 6734e0b281 | 1 year ago |
Frits van Bommel | ec75338027 | 1 year ago |
Pierfrancesco Passerini | 407adb07d2 | 1 year ago |
Florian Trayon | 664d8bc1f8 | 1 year ago |
Florian Trayon | 51441e4ad0 | 1 year ago |
109247019824 | 4c7e88b18a | 1 year ago |
renovate[bot] | e7372f3e8b | 1 year ago |
Milo Ivir | c9a5d19b83 | 1 year ago |
Frits van Bommel | b317a3885a | 1 year ago |
Pierfrancesco Passerini | 98dc48decd | 1 year ago |
Florian Trayon | 2f36ad8043 | 1 year ago |
Florian Trayon | ed2acfbe97 | 1 year ago |
C. Rüdinger | acb95583dc | 1 year ago |
Alex Baker | 4830aed7b4 | 1 year ago |
Alex Baker | f5ab0e6f56 | 1 year ago |
Ihor Hordiichuk | be55a3bc5d | 1 year ago |
Frits van Bommel | 643af2e2fb | 1 year ago |
Kaci | 24f810763f | 1 year ago |
Florian Trayon | cb792e8111 | 1 year ago |
Florian Trayon | c451a1e272 | 1 year ago |
109247019824 | a25e93f3de | 1 year ago |
renovate[bot] | 50926bc0ad | 1 year ago |
Alex Baker | 48e73b4bb3 | 1 year ago |
renovate[bot] | a4184fa63a | 1 year ago |
Alex Baker | 08ae11046a | 1 year ago |
Ander Romero | 74a1ee9e4f | 1 year ago |
Alex Baker | d4192803f8 | 1 year ago |
Alex Baker | 7945160536 | 1 year ago |
renovate[bot] | 79e1a73c2a | 1 year ago |
renovate[bot] | f7bc821a16 | 1 year ago |
renovate[bot] | 4ac6a5fdf6 | 1 year ago |
renovate[bot] | f623046385 | 1 year ago |
renovate[bot] | afdabb3dc3 | 1 year ago |
Alex Baker | 48804de63d | 1 year ago |
qwerty287 | 2ad445aceb | 1 year ago |
Alex Baker | f1790b574f | 1 year ago |
Alex Baker | ac9e782527 | 1 year ago |
Don Zouras | e0758206d8 | 1 year ago |
Alex Baker | 85c0ba9ccf | 1 year ago |
Alex Baker | a0f85fcbbd | 1 year ago |
Alex Baker | 02958e46e6 | 1 year ago |
Alex Baker | fce12ae4a8 | 1 year ago |
Alex Baker | fc3dc96ade | 1 year ago |
renovate[bot] | 559858d19c | 1 year ago |
Ander Romero | 99ffb68e7a | 1 year ago |
renovate[bot] | 1ce507b0bb | 1 year ago |
Sunjae Choi | d4feb8fd31 | 1 year ago |
o20n3 | 16270f66c8 | 1 year ago |
Sunjae Choi | 3f8c8feb08 | 1 year ago |
Oğuz Ersen | 8f370fec62 | 1 year ago |
Alex Baker | f3c28fe60d | 1 year ago |
Alex Baker | b06b10f930 | 1 year ago |
Alex Baker | 6efac620c4 | 1 year ago |
Alex Baker | 41c8a803a1 | 1 year ago |
renovate[bot] | 0ed04d7739 | 1 year ago |
renovate[bot] | f9dbedad3b | 1 year ago |
Alex Baker | 16d91aafb1 | 1 year ago |
Alex Baker | 4882570b3c | 1 year ago |
renovate[bot] | ece1758696 | 1 year ago |
renovate[bot] | cfebf04b4b | 1 year ago |
Alex Baker | 3c87ab4fc1 | 1 year ago |
Alex Baker | 1562c1315c | 1 year ago |
Alex Baker | 2668e9a1df | 1 year ago |
Alex Baker | ac0fbccb54 | 1 year ago |
Alex Baker | d25f859385 | 1 year ago |
Alex Baker | 3555c11b33 | 1 year ago |
Alex Baker | a7662d9cb6 | 1 year ago |
Alex Baker | 2da4dcd17a | 1 year ago |
Alex Baker | 1d58292a07 | 1 year ago |
renovate[bot] | df2a7f8857 | 1 year ago |
renovate[bot] | 56c6f2ce33 | 1 year ago |
renovate[bot] | 019dc6ecaa | 1 year ago |
renovate[bot] | e6ac0b072e | 1 year ago |
Alex Baker | 86d4bcbc40 | 1 year ago |
Alex Baker | e05874d36a | 1 year ago |
Alex Baker | 7d83e8ba06 | 1 year ago |
Alex Baker | 99243e5751 | 1 year ago |
Don Zouras | c6652c851e | 1 year ago |
Alex Baker | 585f12d2f9 | 1 year ago |
Alex Baker | 47c425f7e8 | 1 year ago |
Alex Baker | 72a337d572 | 1 year ago |
Alex Baker | cbaede67cf | 1 year ago |
Alex Baker | 7b2f526f7b | 1 year ago |
renovate[bot] | 2e6ec655db | 1 year ago |
Alex Baker | 57c4018e37 | 1 year ago |
Alex Baker | 067317b5a0 | 1 year ago |
Alex Baker | ad3c35bc5d | 1 year ago |
Alex Baker | 8907d3f520 | 1 year ago |
renovate[bot] | 9f59d8ddf2 | 1 year ago |
Alex Baker | af72e35f05 | 1 year ago |
Alex Baker | 251edd39ed | 1 year ago |
renovate[bot] | 455221c625 | 1 year ago |
Alex Baker | f62d007ff1 | 1 year ago |
Subham Jena | b466170bbf | 1 year ago |
109247019824 | ebeeb06420 | 1 year ago |
Milo Ivir | 81646bb133 | 1 year ago |
Ihor Hordiichuk | 98cc3908b6 | 1 year ago |
Frits van Bommel | 41f4faebe7 | 1 year ago |
Pierfrancesco Passerini | bf512537fe | 1 year ago |
Florian Trayon | 76e19e292b | 1 year ago |
Florian Trayon | 77db8dbe86 | 1 year ago |
Subham Jena | 31f6c85f89 | 1 year ago |
renovate[bot] | eeb448729c | 1 year ago |
Alex Baker | 84e45f0b20 | 1 year ago |
Alex Baker | 114ec3f03b | 1 year ago |
Alex Baker | f72860cef1 | 1 year ago |
Alex Baker | 686a36ecbd | 1 year ago |
renovate[bot] | 4f01e4dba4 | 1 year ago |
Alex Baker | a8d62b6632 | 1 year ago |
Alex Baker | 19b2551f54 | 1 year ago |
Alex Baker | c303ce32ab | 1 year ago |
Alex Baker | f18a646d09 | 1 year ago |
renovate[bot] | 1ec48feb36 | 1 year ago |
renovate[bot] | 8c60f54f77 | 1 year ago |
Alex Baker | cfa46c7e24 | 1 year ago |
Alex Baker | 1d6d8e87d1 | 1 year ago |
Alex Baker | 18242e5284 | 1 year ago |
Alex Baker | 13b4f80c70 | 1 year ago |
renovate[bot] | e72ceca528 | 1 year ago |
renovate[bot] | b331f1440f | 1 year ago |
Alex Baker | a739b21f0f | 1 year ago |
Alex Baker | 47f4ae8dde | 1 year ago |
Alex Baker | 9e60949019 | 1 year ago |
renovate[bot] | d00987fcc8 | 1 year ago |
renovate[bot] | 52d9fdce79 | 1 year ago |
Alex Baker | 2848bd4f53 | 1 year ago |
Alex Baker | 70ab826598 | 1 year ago |
Alex Baker | 5f4753da6f | 1 year ago |
renovate[bot] | 5ac6a3ca79 | 1 year ago |
renovate[bot] | 0ba7b319b2 | 1 year ago |
Alex Baker | bdc01b271d | 1 year ago |
Alex Baker | 013f43ca34 | 1 year ago |
Alex Baker | e41b9561dc | 1 year ago |
Alex Baker | 2c697fd5b9 | 1 year ago |
renovate[bot] | 1a810e0298 | 1 year ago |
Alex Baker | 4121163008 | 1 year ago |
renovate[bot] | f4e5c5c72b | 1 year ago |
renovate[bot] | a21ee0a3c2 | 1 year ago |
Alex Baker | e37497b77f | 1 year ago |
Alex Baker | 4018277645 | 1 year ago |
Alex Baker | 97e1b75781 | 1 year ago |
109247019824 | d477dfb448 | 1 year ago |
renovate[bot] | 360a85c57b | 2 years ago |
Alex Baker | 88a3da822b | 2 years ago |
Alex Baker | df50cf9459 | 2 years ago |
renovate[bot] | 05bad27d63 | 2 years ago |
renovate[bot] | acbf3f2f97 | 2 years ago |
renovate[bot] | b6116623fa | 2 years ago |
renovate[bot] | 5ecc52bf78 | 2 years ago |
renovate[bot] | 26af7d74f7 | 2 years ago |
renovate[bot] | 72e4f853b2 | 2 years ago |
renovate[bot] | 4c572f7504 | 2 years ago |
Kazushi Hayama | 31d7f489a7 | 2 years ago |
renovate[bot] | 14d4fa702b | 2 years ago |
renovate[bot] | 887007d898 | 2 years ago |
Alex Baker | db82ef7fd6 | 2 years ago |
Alex Baker | b75be2c5af | 2 years ago |
renovate[bot] | 8574c4f8bd | 2 years ago |
renovate[bot] | 94eb48c326 | 2 years ago |
renovate[bot] | db8744123f | 2 years ago |
renovate[bot] | 63e3311fd3 | 2 years ago |
renovate[bot] | fc58a059e4 | 2 years ago |
renovate[bot] | 7010d06432 | 2 years ago |
renovate[bot] | c206634de1 | 2 years ago |
renovate[bot] | b13a080ba4 | 2 years ago |
Alex Baker | 26e1ffcc85 | 2 years ago |
Simona Iacob | 4be0a80d17 | 2 years ago |
renovate[bot] | 272b7d9dcf | 2 years ago |
renovate[bot] | 2f8d698dd6 | 2 years ago |
Alex Baker | 049e4a9329 | 2 years ago |
Alex Baker | 91da3191c5 | 2 years ago |
Alex Baker | 2bc906868d | 2 years ago |
Alex Baker | 9d142bd80b | 2 years ago |
Alex Baker | db563b04ae | 2 years ago |
Alex Baker | e2ab005e29 | 2 years ago |
Alex Baker | b1b85444bd | 2 years ago |
renovate[bot] | 2c6ebf3c3e | 2 years ago |
renovate[bot] | 58230f5e61 | 2 years ago |
renovate[bot] | 80d69ea3f5 | 2 years ago |
Alex Baker | 4b325c0133 | 2 years ago |
Alex Baker | 32eed65f04 | 2 years ago |
renovate[bot] | fe87eac962 | 2 years ago |
Alex Baker | 43a943dedd | 2 years ago |
Alex Baker | de61bb3fe9 | 2 years ago |
renovate[bot] | b6523bf30f | 2 years ago |
renovate[bot] | 6fa7b53cd7 | 2 years ago |
renovate[bot] | ad5c1dc8d0 | 2 years ago |
renovate[bot] | 089337aabc | 2 years ago |
renovate[bot] | ae87325c58 | 2 years ago |
renovate[bot] | 73dfa62fcc | 2 years ago |
renovate[bot] | 0dd10e835c | 2 years ago |
renovate[bot] | 19cd5b967a | 2 years ago |
renovate[bot] | 406ae0dfdd | 2 years ago |
renovate[bot] | 72fbf21067 | 2 years ago |
renovate[bot] | fc13be33c4 | 2 years ago |
renovate[bot] | 204f8312ad | 2 years ago |
renovate[bot] | 82b1b7bd57 | 2 years ago |
renovate[bot] | 973bd086dd | 2 years ago |
renovate[bot] | 3778aaaf05 | 2 years ago |
Alex Baker | c2cc2e0c31 | 2 years ago |
Alex Baker | 567c3ba0e7 | 2 years ago |
renovate[bot] | 38d273d149 | 2 years ago |
renovate[bot] | 1bd3cb84b2 | 2 years ago |
renovate[bot] | 273c9ebe52 | 2 years ago |
renovate[bot] | ddee3b44d1 | 2 years ago |
renovate[bot] | ccfd494b49 | 2 years ago |
renovate[bot] | 3e3b37a66b | 2 years ago |
renovate[bot] | 3ce8f864ce | 2 years ago |
Alex Baker | 8d2aee359b | 2 years ago |
Alex Baker | 7ced8a2fdc | 2 years ago |
Alex Baker | 5ecc604b37 | 2 years ago |
Alex Baker | 379a49fa81 | 2 years ago |
Alex Baker | bd1101d73e | 2 years ago |
Alex Baker | e114bb4851 | 2 years ago |
Don Zouras | 82fae728c4 | 2 years ago |
Don Zouras | 5f25f953fd | 2 years ago |
Chih-Hsuan Yen | a1487e4c41 | 2 years ago |
Poesty Li | 5c10c748dd | 2 years ago |
Naga | ea994122e7 | 2 years ago |
Kisaragi Hiu | c1008a31b7 | 2 years ago |
NN | 1be1f3e0ae | 2 years ago |
Gabriel Camargo | ea0a110576 | 2 years ago |
Olli | 582e0a1a3d | 2 years ago |
Don Zouras | 3d490f0ed6 | 2 years ago |
AHOHNMYC | 8764b01301 | 2 years ago |
Alex Baker | 100928d002 | 2 years ago |
Alex Baker | b85dc20d24 | 2 years ago |
Alex Baker | 1fdeb5fb35 | 2 years ago |
Alex Baker | 0738ebb758 | 2 years ago |
Alex Baker | 417f5ac224 | 2 years ago |
Alex Baker | ad54394c08 | 2 years ago |
Alex Baker | 3cb8cd9a45 | 2 years ago |
Alex Baker | 6c10466904 | 2 years ago |
Alex Baker | 3131c56651 | 2 years ago |
Alex Baker | e644971619 | 2 years ago |
Alex Baker | 120eb4dd30 | 2 years ago |
Alex Baker | c2222657ec | 2 years ago |
Alex Baker | f6ca98e096 | 2 years ago |
Alex Baker | ac62b4f385 | 2 years ago |
Alex Baker | 2006e2c84b | 2 years ago |
Alex Baker | 513f8b017f | 2 years ago |
Alex Baker | a04fbebd0f | 2 years ago |
Alex Baker | 0c2b31b84b | 2 years ago |
Alex Baker | 1eba02604d | 2 years ago |
Alex Baker | 0f6013cecc | 2 years ago |
Alex Baker | 68d80a5d2a | 2 years ago |
Alex Baker | c5587d9fea | 2 years ago |
gnu-ewm | e4e0ec013b | 2 years ago |
Alex Baker | ab8af2a3a1 | 2 years ago |
Alex Baker | e2ad2507d3 | 2 years ago |
Don Zouras | 705b6e05dd | 2 years ago |
JoseFabio El que Conoces | ab968dcf17 | 2 years ago |
Don Zouras | 50bb209cd3 | 2 years ago |
Julius Härtl | 99d1dea0f1 | 2 years ago |
bruh | 9a5c4ea010 | 2 years ago |
Olli | 6f7890ea3b | 2 years ago |
Alex Baker | 63fda6f681 | 2 years ago |
Alex Baker | 738870ac6b | 2 years ago |
Kazushi Hayama | 3b04ddb44f | 2 years ago |
Alex Baker | 4f6749dc24 | 2 years ago |
Kazushi Hayama | c18eac2b00 | 2 years ago |
C. Rüdinger | 5ac9df3cb6 | 2 years ago |
o20n3 | 6405d5fe66 | 2 years ago |
Pierfrancesco Passerini | 6df420d584 | 2 years ago |
Tntdruid | 9bea3ee6df | 2 years ago |
haidarah esmander | b85694eebd | 2 years ago |
Slávek Banko | fb5ab13d99 | 2 years ago |
Trevor Terris | bc906090aa | 3 years ago |
Trevor Terris | 9742d93e83 | 3 years ago |
@ -0,0 +1,47 @@
|
||||
name: Assemble bundle
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
check:
|
||||
uses: ./.github/workflows/check.yml
|
||||
bundle:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [ check ]
|
||||
steps:
|
||||
- name: Decode Keystore
|
||||
run: |
|
||||
echo ${{ secrets.KEY_STORE }} | base64 -di > "${RUNNER_TEMP}"/keystore.jks
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
bundler-cache: true
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
cache: 'gradle'
|
||||
- name: Grant execute permission for gradlew
|
||||
run: chmod +x gradlew
|
||||
- name: Bundle
|
||||
env:
|
||||
KEY_PATH: ${{ runner.temp }}/keystore.jks
|
||||
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
|
||||
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
||||
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||
MAPBOX_KEY: ${{ secrets.MAPBOX_KEY }}
|
||||
GOOGLE_KEY: ${{ secrets.GOOGLE_KEY }}
|
||||
run: bundle exec fastlane bundle
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: release
|
||||
path: app/build/outputs/**
|
@ -0,0 +1,91 @@
|
||||
name: Run automated checks
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
workflow_call:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
bundler-cache: true
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
cache: 'gradle'
|
||||
- name: Grant execute permission for gradlew
|
||||
run: chmod +x gradlew
|
||||
- name: Lint checks
|
||||
run: bundle exec fastlane lint
|
||||
- name: Archive lint reports
|
||||
uses: actions/upload-artifact@v4
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: lint-reports
|
||||
path: app/build/reports/*.html
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
flavor: [Googleplay, Generic]
|
||||
api-level: [29]
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
cache: 'gradle'
|
||||
|
||||
- name: Enable KVM
|
||||
run: |
|
||||
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
|
||||
sudo udevadm control --reload-rules
|
||||
sudo udevadm trigger --name-match=kvm
|
||||
|
||||
# - name: AVD cache
|
||||
# uses: actions/cache@v4
|
||||
# id: avd-cache
|
||||
# with:
|
||||
# path: |
|
||||
# ~/.android/avd/*
|
||||
# ~/.android/adb*
|
||||
# key: avd-${{ matrix.api-level }}
|
||||
#
|
||||
# - name: create AVD and generate snapshot for caching
|
||||
# if: steps.avd-cache.outputs.cache-hit != 'true'
|
||||
# uses: reactivecircus/android-emulator-runner@v2
|
||||
# with:
|
||||
# api-level: ${{ matrix.api-level }}
|
||||
# force-avd-creation: false
|
||||
# emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
# disable-animations: false
|
||||
# script: echo "Generated AVD snapshot for caching."
|
||||
|
||||
- name: run tests
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
force-avd-creation: false
|
||||
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
disable-animations: true
|
||||
script: ./gradlew -Pcoverage app:test${{ matrix.flavor }}DebugUnitTest app:connected${{ matrix.flavor }}DebugAndroidTest
|
||||
|
||||
- name: Upload test reports
|
||||
uses: actions/upload-artifact@v4
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: test-reports-${{ matrix.flavor }}
|
||||
path: app/build/reports/**
|
@ -1,46 +0,0 @@
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- CODE_OF_CONDUCT.md
|
||||
- CONTRIBUTING.md
|
||||
- README.md
|
||||
- 'fastlane/**'
|
||||
- .github/FUNDING.yml
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- CODE_OF_CONDUCT.md
|
||||
- CONTRIBUTING.md
|
||||
- README.md
|
||||
- 'fastlane/**'
|
||||
- .github/FUNDING.yml
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
bundler-cache: true
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '11'
|
||||
- name: Grant execute permission for gradlew
|
||||
run: chmod +x gradlew
|
||||
- name: Lint checks
|
||||
run: bundle exec fastlane lint
|
||||
- name: Archive lint reports
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: lint-reports
|
||||
if: always()
|
||||
path: app/build/reports/*.html
|
@ -1,41 +0,0 @@
|
||||
name: Run tests
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- CODE_OF_CONDUCT.md
|
||||
- CONTRIBUTING.md
|
||||
- README.md
|
||||
- 'fastlane/**'
|
||||
- .github/FUNDING.yml
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- CODE_OF_CONDUCT.md
|
||||
- CONTRIBUTING.md
|
||||
- README.md
|
||||
- 'fastlane/**'
|
||||
- .github/FUNDING.yml
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '11'
|
||||
- name: run tests
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
with:
|
||||
api-level: 29
|
||||
script: ./gradlew -Pcoverage :app:jacocoTestReportGoogleplayDebug :app:createGoogleplayDebugAndroidTestCoverageReport
|
||||
- name: upload coverage
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
directory: ./app/build
|
@ -1 +1 @@
|
||||
3.0.3
|
||||
3.3.4
|
||||
|
@ -1,263 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module PUBLIC
|
||||
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
|
||||
"https://checkstyle.org/dtds/configuration_1_3.dtd">
|
||||
|
||||
<!-- https://raw.githubusercontent.com/checkstyle/checkstyle/checkstyle-8.16/src/main/resources/google_checks.xml -->
|
||||
|
||||
<!--
|
||||
Checkstyle configuration that checks the Google coding conventions from Google Java Style
|
||||
that can be found at https://google.github.io/styleguide/javaguide.html.
|
||||
|
||||
Checkstyle is very configurable. Be sure to read the documentation at
|
||||
http://checkstyle.sf.net (or in your downloaded distribution).
|
||||
|
||||
To completely disable a check, just comment it out or delete it from the file.
|
||||
|
||||
Authors: Max Vetrenko, Ruslan Diachenko, Roman Ivanov.
|
||||
-->
|
||||
|
||||
<module name = "Checker">
|
||||
<property name="charset" value="UTF-8"/>
|
||||
|
||||
<property name="severity" value="warning"/>
|
||||
|
||||
<property name="fileExtensions" value="java, properties, xml"/>
|
||||
<!-- Checks for whitespace -->
|
||||
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
|
||||
<module name="FileTabCharacter">
|
||||
<property name="eachLine" value="true"/>
|
||||
</module>
|
||||
|
||||
<module name="TreeWalker">
|
||||
<module name="OuterTypeFilename"/>
|
||||
<module name="IllegalTokenText">
|
||||
<property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
|
||||
<property name="format"
|
||||
value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
|
||||
<property name="message"
|
||||
value="Consider using special escape sequence instead of octal value or Unicode escaped value."/>
|
||||
</module>
|
||||
<module name="AvoidEscapedUnicodeCharacters">
|
||||
<property name="allowEscapesForControlCharacters" value="true"/>
|
||||
<property name="allowByTailComment" value="true"/>
|
||||
<property name="allowNonPrintableEscapes" value="true"/>
|
||||
</module>
|
||||
<module name="LineLength">
|
||||
<property name="max" value="100"/>
|
||||
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
|
||||
</module>
|
||||
<module name="AvoidStarImport"/>
|
||||
<module name="OneTopLevelClass"/>
|
||||
<module name="NoLineWrap"/>
|
||||
<module name="EmptyBlock">
|
||||
<property name="option" value="TEXT"/>
|
||||
<property name="tokens"
|
||||
value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/>
|
||||
</module>
|
||||
<module name="NeedBraces"/>
|
||||
<module name="LeftCurly"/>
|
||||
<module name="RightCurly">
|
||||
<property name="id" value="RightCurlySame"/>
|
||||
<property name="tokens"
|
||||
value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE,
|
||||
LITERAL_DO"/>
|
||||
</module>
|
||||
<module name="RightCurly">
|
||||
<property name="id" value="RightCurlyAlone"/>
|
||||
<property name="option" value="alone"/>
|
||||
<property name="tokens"
|
||||
value="CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, STATIC_INIT,
|
||||
INSTANCE_INIT"/>
|
||||
</module>
|
||||
<module name="WhitespaceAround">
|
||||
<property name="allowEmptyConstructors" value="true"/>
|
||||
<property name="allowEmptyMethods" value="true"/>
|
||||
<property name="allowEmptyTypes" value="true"/>
|
||||
<property name="allowEmptyLoops" value="true"/>
|
||||
<message key="ws.notFollowed"
|
||||
value="WhitespaceAround: ''{0}'' is not followed by whitespace. Empty blocks may only be represented as '{}' when not part of a multi-block statement (4.1.3)"/>
|
||||
<message key="ws.notPreceded"
|
||||
value="WhitespaceAround: ''{0}'' is not preceded with whitespace."/>
|
||||
</module>
|
||||
<module name="OneStatementPerLine"/>
|
||||
<module name="MultipleVariableDeclarations"/>
|
||||
<module name="ArrayTypeStyle"/>
|
||||
<module name="MissingSwitchDefault"/>
|
||||
<module name="FallThrough"/>
|
||||
<module name="UpperEll"/>
|
||||
<module name="ModifierOrder"/>
|
||||
<module name="EmptyLineSeparator">
|
||||
<property name="allowNoEmptyLineBetweenFields" value="true"/>
|
||||
</module>
|
||||
<module name="SeparatorWrap">
|
||||
<property name="id" value="SeparatorWrapDot"/>
|
||||
<property name="tokens" value="DOT"/>
|
||||
<property name="option" value="nl"/>
|
||||
</module>
|
||||
<module name="SeparatorWrap">
|
||||
<property name="id" value="SeparatorWrapComma"/>
|
||||
<property name="tokens" value="COMMA"/>
|
||||
<property name="option" value="EOL"/>
|
||||
</module>
|
||||
<module name="SeparatorWrap">
|
||||
<!-- ELLIPSIS is EOL until https://github.com/google/styleguide/issues/258 -->
|
||||
<property name="id" value="SeparatorWrapEllipsis"/>
|
||||
<property name="tokens" value="ELLIPSIS"/>
|
||||
<property name="option" value="EOL"/>
|
||||
</module>
|
||||
<module name="SeparatorWrap">
|
||||
<!-- ARRAY_DECLARATOR is EOL until https://github.com/google/styleguide/issues/259 -->
|
||||
<property name="id" value="SeparatorWrapArrayDeclarator"/>
|
||||
<property name="tokens" value="ARRAY_DECLARATOR"/>
|
||||
<property name="option" value="EOL"/>
|
||||
</module>
|
||||
<module name="SeparatorWrap">
|
||||
<property name="id" value="SeparatorWrapMethodRef"/>
|
||||
<property name="tokens" value="METHOD_REF"/>
|
||||
<property name="option" value="nl"/>
|
||||
</module>
|
||||
<module name="PackageName">
|
||||
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Package name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="TypeName">
|
||||
<message key="name.invalidPattern"
|
||||
value="Type name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="MemberName">
|
||||
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Member name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="ParameterName">
|
||||
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Parameter name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="LambdaParameterName">
|
||||
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Lambda parameter name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="CatchParameterName">
|
||||
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Catch parameter name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="LocalVariableName">
|
||||
<property name="tokens" value="VARIABLE_DEF"/>
|
||||
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Local variable name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="ClassTypeParameterName">
|
||||
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Class type name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="MethodTypeParameterName">
|
||||
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Method type name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="InterfaceTypeParameterName">
|
||||
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Interface type name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="NoFinalizer"/>
|
||||
<module name="GenericWhitespace">
|
||||
<message key="ws.followed"
|
||||
value="GenericWhitespace ''{0}'' is followed by whitespace."/>
|
||||
<message key="ws.preceded"
|
||||
value="GenericWhitespace ''{0}'' is preceded with whitespace."/>
|
||||
<message key="ws.illegalFollow"
|
||||
value="GenericWhitespace ''{0}'' should followed by whitespace."/>
|
||||
<message key="ws.notPreceded"
|
||||
value="GenericWhitespace ''{0}'' is not preceded with whitespace."/>
|
||||
</module>
|
||||
<module name="Indentation">
|
||||
<property name="basicOffset" value="2"/>
|
||||
<property name="braceAdjustment" value="0"/>
|
||||
<property name="caseIndent" value="2"/>
|
||||
<property name="throwsIndent" value="4"/>
|
||||
<property name="lineWrappingIndentation" value="4"/>
|
||||
<property name="arrayInitIndent" value="2"/>
|
||||
</module>
|
||||
<module name="AbbreviationAsWordInName">
|
||||
<property name="ignoreFinal" value="false"/>
|
||||
<property name="allowedAbbreviationLength" value="1"/>
|
||||
</module>
|
||||
<module name="OverloadMethodsDeclarationOrder"/>
|
||||
<module name="VariableDeclarationUsageDistance"/>
|
||||
<module name="CustomImportOrder">
|
||||
<property name="sortImportsInGroupAlphabetically" value="true"/>
|
||||
<property name="separateLineBetweenGroups" value="true"/>
|
||||
<property name="customImportOrderRules" value="STATIC###THIRD_PARTY_PACKAGE"/>
|
||||
</module>
|
||||
<module name="MethodParamPad"/>
|
||||
<module name="NoWhitespaceBefore">
|
||||
<property name="tokens"
|
||||
value="COMMA, SEMI, POST_INC, POST_DEC, DOT, ELLIPSIS, METHOD_REF"/>
|
||||
<property name="allowLineBreaks" value="true"/>
|
||||
</module>
|
||||
<module name="ParenPad"/>
|
||||
<module name="OperatorWrap">
|
||||
<property name="option" value="NL"/>
|
||||
<property name="tokens"
|
||||
value="BAND, BOR, BSR, BXOR, DIV, EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR,
|
||||
LT, MINUS, MOD, NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR, METHOD_REF "/>
|
||||
</module>
|
||||
<module name="AnnotationLocation">
|
||||
<property name="id" value="AnnotationLocationMostCases"/>
|
||||
<property name="tokens"
|
||||
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF"/>
|
||||
</module>
|
||||
<module name="AnnotationLocation">
|
||||
<property name="id" value="AnnotationLocationVariables"/>
|
||||
<property name="tokens" value="VARIABLE_DEF"/>
|
||||
<property name="allowSamelineMultipleAnnotations" value="true"/>
|
||||
</module>
|
||||
<module name="NonEmptyAtclauseDescription"/>
|
||||
<module name="JavadocTagContinuationIndentation">
|
||||
<property name="severity" value="ignore" />
|
||||
</module>
|
||||
<module name="SummaryJavadoc">
|
||||
<property name="severity" value="ignore" />
|
||||
<property name="forbiddenSummaryFragments"
|
||||
value="^@return the *|^This method returns |^A [{]@code [a-zA-Z0-9]+[}]( is a )"/>
|
||||
</module>
|
||||
<module name="JavadocParagraph">
|
||||
<property name="severity" value="ignore" />
|
||||
</module>
|
||||
<module name="AtclauseOrder">
|
||||
<property name="tagOrder" value="@param, @return, @throws, @deprecated"/>
|
||||
<property name="target"
|
||||
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
|
||||
</module>
|
||||
<module name="JavadocMethod">
|
||||
<property name="severity" value="ignore" />
|
||||
<property name="scope" value="public"/>
|
||||
<property name="allowMissingParamTags" value="true"/>
|
||||
<property name="allowMissingThrowsTags" value="true"/>
|
||||
<property name="allowMissingReturnTag" value="true"/>
|
||||
<property name="minLineCount" value="2"/>
|
||||
<property name="allowedAnnotations" value="Override, Test"/>
|
||||
<property name="allowThrowsTagsForSubclasses" value="true"/>
|
||||
</module>
|
||||
<module name="MethodName">
|
||||
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9_]*$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Method name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="SingleLineJavadoc">
|
||||
<property name="severity" value="ignore"/>
|
||||
</module>
|
||||
<module name="EmptyCatchBlock">
|
||||
<property name="exceptionVariableName" value="expected"/>
|
||||
</module>
|
||||
<module name="CommentsIndentation"/>
|
||||
</module>
|
||||
</module>
|
@ -1,78 +0,0 @@
|
||||
package com.todoroo.astrid.adapter
|
||||
|
||||
import android.content.Context
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.natpryce.makeiteasy.MakeItEasy.with
|
||||
import com.natpryce.makeiteasy.PropertyValue
|
||||
import com.todoroo.astrid.core.BuiltInFilterExposer
|
||||
import com.todoroo.astrid.dao.TaskDao
|
||||
import com.todoroo.astrid.data.Task
|
||||
import dagger.hilt.android.testing.HiltAndroidTest
|
||||
import dagger.hilt.android.testing.UninstallModules
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.tasks.LocalBroadcastManager
|
||||
import org.tasks.R
|
||||
import org.tasks.data.CaldavDao
|
||||
import org.tasks.data.GoogleTaskDao
|
||||
import org.tasks.data.TaskContainer
|
||||
import org.tasks.data.TaskListQuery.getQuery
|
||||
import org.tasks.injection.InjectingTestCase
|
||||
import org.tasks.injection.ProductionModule
|
||||
import org.tasks.makers.TaskMaker.PARENT
|
||||
import org.tasks.makers.TaskMaker.newTask
|
||||
import org.tasks.preferences.Preferences
|
||||
import javax.inject.Inject
|
||||
|
||||
@UninstallModules(ProductionModule::class)
|
||||
@HiltAndroidTest
|
||||
class NonRecursiveQueryTest : InjectingTestCase() {
|
||||
@Inject lateinit var googleTaskDao: GoogleTaskDao
|
||||
@Inject lateinit var caldavDao: CaldavDao
|
||||
@Inject lateinit var taskDao: TaskDao
|
||||
@Inject lateinit var preferences: Preferences
|
||||
@Inject lateinit var localBroadcastManager: LocalBroadcastManager
|
||||
|
||||
private lateinit var adapter: TaskAdapter
|
||||
private val tasks = ArrayList<TaskContainer>()
|
||||
private val filter = BuiltInFilterExposer.getMyTasksFilter(ApplicationProvider.getApplicationContext<Context>().resources)
|
||||
private val dataSource = object : TaskAdapterDataSource {
|
||||
override fun getItem(position: Int) = tasks[position]
|
||||
|
||||
override fun getTaskCount() = tasks.size
|
||||
}
|
||||
|
||||
@Before
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
preferences.clear()
|
||||
preferences.setBoolean(R.string.p_use_paged_queries, true)
|
||||
tasks.clear()
|
||||
adapter = TaskAdapter(false, googleTaskDao, caldavDao, taskDao, localBroadcastManager)
|
||||
adapter.setDataSource(dataSource)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ignoreSubtasks() {
|
||||
val parent = addTask()
|
||||
val child = addTask(with(PARENT, parent))
|
||||
|
||||
query()
|
||||
|
||||
assertEquals(child, tasks[1].id)
|
||||
assertEquals(parent, tasks[1].parent)
|
||||
assertEquals(0, tasks[1].indent)
|
||||
}
|
||||
|
||||
private fun addTask(vararg properties: PropertyValue<in Task?, *>): Long = runBlocking {
|
||||
val task = newTask(*properties)
|
||||
taskDao.createNew(task)
|
||||
task.id
|
||||
}
|
||||
|
||||
private fun query() = runBlocking {
|
||||
tasks.addAll(taskDao.fetchTasks { getQuery(preferences, filter, it) })
|
||||
}
|
||||
}
|
@ -1,106 +1,290 @@
|
||||
package com.todoroo.astrid.alarms
|
||||
|
||||
import com.natpryce.makeiteasy.MakeItEasy.with
|
||||
import com.todoroo.andlib.utility.DateUtilities
|
||||
import dagger.hilt.android.testing.HiltAndroidTest
|
||||
import dagger.hilt.android.testing.UninstallModules
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.tasks.data.Alarm
|
||||
import org.tasks.data.Alarm.Companion.TYPE_DATE_TIME
|
||||
import org.tasks.data.Alarm.Companion.TYPE_RANDOM
|
||||
import org.tasks.data.Alarm.Companion.TYPE_SNOOZE
|
||||
import org.tasks.data.Alarm.Companion.whenDue
|
||||
import org.tasks.data.Alarm.Companion.whenOverdue
|
||||
import org.tasks.data.AlarmDao
|
||||
import org.tasks.data.TaskDao
|
||||
import org.tasks.date.DateTimeUtils.newDateTime
|
||||
import org.tasks.SuspendFreeze.Companion.freezeAt
|
||||
import org.tasks.data.createDueDate
|
||||
import org.tasks.data.dao.TaskDao
|
||||
import org.tasks.data.entity.Alarm
|
||||
import org.tasks.data.entity.Notification
|
||||
import org.tasks.data.entity.Task
|
||||
import org.tasks.injection.InjectingTestCase
|
||||
import org.tasks.injection.ProductionModule
|
||||
import org.tasks.jobs.AlarmEntry
|
||||
import org.tasks.jobs.NotificationQueue
|
||||
import org.tasks.makers.TaskMaker.COMPLETION_TIME
|
||||
import org.tasks.makers.TaskMaker.DELETION_TIME
|
||||
import org.tasks.makers.TaskMaker.DUE_DATE
|
||||
import org.tasks.makers.TaskMaker.DUE_TIME
|
||||
import org.tasks.makers.TaskMaker.REMINDER_LAST
|
||||
import org.tasks.makers.TaskMaker.newTask
|
||||
import org.tasks.time.DateTime
|
||||
import org.tasks.time.DateTimeUtils2
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
@UninstallModules(ProductionModule::class)
|
||||
@HiltAndroidTest
|
||||
class AlarmJobServiceTest : InjectingTestCase() {
|
||||
@Inject lateinit var alarmDao: AlarmDao
|
||||
@Inject lateinit var taskDao: TaskDao
|
||||
@Inject lateinit var jobs: NotificationQueue
|
||||
@Inject lateinit var alarmService: AlarmService
|
||||
|
||||
@Test
|
||||
fun scheduleAlarm() = runBlocking {
|
||||
val task = taskDao.createNew(newTask())
|
||||
val alarm = insertAlarm(Alarm(task, DateTime(2017, 9, 24, 19, 57).millis, TYPE_DATE_TIME))
|
||||
fun testNoAlarms() = runBlocking {
|
||||
testResults(emptyList(), 0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun futureAlarmWithNoPastAlarm() = runBlocking {
|
||||
freezeAt(DateTime(2024, 5, 17, 23, 20)) {
|
||||
taskDao.insert(
|
||||
Task(
|
||||
dueDate = createDueDate(
|
||||
Task.URGENCY_SPECIFIC_DAY,
|
||||
DateTime(2024, 5, 18).millis
|
||||
)
|
||||
)
|
||||
)
|
||||
alarmService.synchronizeAlarms(1, mutableSetOf(Alarm(type = Alarm.TYPE_REL_END)))
|
||||
|
||||
verify(AlarmEntry(alarm, task, DateTime(2017, 9, 24, 19, 57).millis, TYPE_DATE_TIME))
|
||||
testResults(emptyList(), DateTime(2024, 5, 18, 18, 0).millis)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ignoreStaleAlarm() = runBlocking {
|
||||
val alarmTime = DateTime(2017, 9, 24, 19, 57)
|
||||
val task = taskDao.createNew(newTask(with(REMINDER_LAST, alarmTime.endOfMinute())))
|
||||
alarmDao.insert(Alarm(task, alarmTime.millis, TYPE_DATE_TIME))
|
||||
fun pastAlarmWithNoFutureAlarm() = runBlocking {
|
||||
freezeAt(DateTime(2024, 5, 17, 23, 20)) {
|
||||
taskDao.insert(
|
||||
Task(
|
||||
dueDate = createDueDate(
|
||||
Task.URGENCY_SPECIFIC_DAY,
|
||||
DateTime(2024, 5, 17).millis
|
||||
)
|
||||
)
|
||||
)
|
||||
alarmService.synchronizeAlarms(1, mutableSetOf(Alarm(type = Alarm.TYPE_REL_END)))
|
||||
|
||||
verify()
|
||||
testResults(
|
||||
listOf(
|
||||
Notification(
|
||||
taskId = 1L,
|
||||
timestamp = DateTimeUtils2.currentTimeMillis(),
|
||||
type = Alarm.TYPE_REL_END
|
||||
)
|
||||
),
|
||||
0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dontScheduleReminderForCompletedTask() = runBlocking {
|
||||
val task = taskDao.insert(
|
||||
newTask(
|
||||
with(DUE_DATE, newDateTime()),
|
||||
with(COMPLETION_TIME, newDateTime())
|
||||
fun pastRecurringAlarmWithFutureRecurrence() = runBlocking {
|
||||
freezeAt(DateTime(2024, 5, 17, 23, 20)) {
|
||||
taskDao.insert(
|
||||
Task(
|
||||
dueDate = createDueDate(
|
||||
Task.URGENCY_SPECIFIC_DAY,
|
||||
DateTime(2024, 5, 17).millis
|
||||
)
|
||||
)
|
||||
)
|
||||
alarmService.synchronizeAlarms(
|
||||
1,
|
||||
mutableSetOf(
|
||||
Alarm(
|
||||
type = Alarm.TYPE_REL_END,
|
||||
repeat = 1,
|
||||
interval = TimeUnit.HOURS.toMillis(6)
|
||||
)
|
||||
)
|
||||
)
|
||||
alarmDao.insert(whenDue(task))
|
||||
|
||||
verify()
|
||||
testResults(
|
||||
listOf(
|
||||
Notification(
|
||||
taskId = 1L,
|
||||
timestamp = DateTimeUtils2.currentTimeMillis(),
|
||||
type = Alarm.TYPE_REL_END
|
||||
)
|
||||
),
|
||||
DateTime(2024, 5, 18, 0, 0).millis
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun pastAlarmsRemoveSnoozed() = runBlocking {
|
||||
freezeAt(DateTime(2024, 5, 17, 23, 20)) {
|
||||
taskDao.insert(
|
||||
Task(
|
||||
dueDate = createDueDate(
|
||||
Task.URGENCY_SPECIFIC_DAY,
|
||||
DateTime(2024, 5, 17).millis
|
||||
)
|
||||
)
|
||||
)
|
||||
alarmService.synchronizeAlarms(
|
||||
1,
|
||||
mutableSetOf(
|
||||
Alarm(type = Alarm.TYPE_REL_END),
|
||||
Alarm(time = DateTimeUtils2.currentTimeMillis(), type = Alarm.TYPE_SNOOZE)
|
||||
)
|
||||
)
|
||||
|
||||
testResults(
|
||||
listOf(
|
||||
Notification(
|
||||
taskId = 1L,
|
||||
timestamp = DateTimeUtils2.currentTimeMillis(),
|
||||
type = Alarm.TYPE_REL_END
|
||||
)
|
||||
),
|
||||
0
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
listOf(Alarm(id = 1, task = 1, time = 0, type = Alarm.TYPE_REL_END)),
|
||||
alarmService.getAlarms(1)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dontScheduleReminderForDeletedTask() = runBlocking {
|
||||
val task = taskDao.insert(
|
||||
newTask(
|
||||
with(DUE_DATE, newDateTime()),
|
||||
with(DELETION_TIME, newDateTime())
|
||||
fun alarmsOneMinuteApart() = runBlocking {
|
||||
freezeAt(DateTime(2024, 5, 17, 23, 20)) {
|
||||
taskDao.insert(
|
||||
Task(
|
||||
dueDate = createDueDate(
|
||||
Task.URGENCY_SPECIFIC_DAY_TIME,
|
||||
DateTime(2024, 5, 17, 23, 20).millis
|
||||
)
|
||||
)
|
||||
)
|
||||
alarmService.synchronizeAlarms(1, mutableSetOf(Alarm(type = Alarm.TYPE_REL_END)))
|
||||
taskDao.insert(Task())
|
||||
alarmService.synchronizeAlarms(
|
||||
taskId = 2,
|
||||
alarms = mutableSetOf(
|
||||
Alarm(
|
||||
type = Alarm.TYPE_SNOOZE,
|
||||
time = DateTime(2024, 5, 17, 23, 21).millis)
|
||||
)
|
||||
)
|
||||
alarmDao.insert(whenDue(task))
|
||||
|
||||
verify()
|
||||
testResults(
|
||||
listOf(
|
||||
Notification(
|
||||
taskId = 1L,
|
||||
timestamp = DateTimeUtils2.currentTimeMillis(),
|
||||
type = Alarm.TYPE_REL_END
|
||||
)
|
||||
),
|
||||
DateTime(2024, 5, 17, 23, 21).millis
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun snoozeOverridesAll() = runBlocking {
|
||||
val now = newDateTime()
|
||||
val task = taskDao.insert(newTask(with(DUE_TIME, now)))
|
||||
fun futureSnoozeOverrideOverdue() = runBlocking {
|
||||
freezeAt(DateTime(2024, 5, 17, 23, 20)) {
|
||||
taskDao.insert(
|
||||
Task(
|
||||
dueDate = createDueDate(
|
||||
Task.URGENCY_SPECIFIC_DAY,
|
||||
DateTime(2024, 5, 17).millis
|
||||
)
|
||||
)
|
||||
)
|
||||
alarmService.synchronizeAlarms(
|
||||
1,
|
||||
mutableSetOf(
|
||||
Alarm(type = Alarm.TYPE_REL_END),
|
||||
Alarm(
|
||||
time = DateTimeUtils2.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5),
|
||||
type = Alarm.TYPE_SNOOZE
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
alarmDao.insert(whenDue(task))
|
||||
alarmDao.insert(whenOverdue(task))
|
||||
alarmDao.insert(Alarm(task, DateUtilities.ONE_HOUR, TYPE_RANDOM))
|
||||
val alarm = alarmDao.insert(Alarm(task, now.plusMonths(12).millis, TYPE_SNOOZE))
|
||||
testResults(
|
||||
emptyList(),
|
||||
DateTimeUtils2.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ignoreStaleAlarm() = runBlocking {
|
||||
freezeAt(DateTime(2024, 5, 17, 23, 20)) {
|
||||
taskDao.insert(
|
||||
Task(
|
||||
dueDate = createDueDate(
|
||||
Task.URGENCY_SPECIFIC_DAY,
|
||||
DateTime(2024, 5, 17).millis
|
||||
),
|
||||
reminderLast = DateTime(2024, 5, 17, 18, 0).millis,
|
||||
)
|
||||
)
|
||||
alarmService.synchronizeAlarms(
|
||||
1,
|
||||
mutableSetOf(Alarm(type = Alarm.TYPE_REL_END))
|
||||
)
|
||||
|
||||
verify(AlarmEntry(alarm, task, now.plusMonths(12).millis, TYPE_SNOOZE))
|
||||
testResults(
|
||||
emptyList(),
|
||||
0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun insertAlarm(alarm: Alarm): Long {
|
||||
alarm.id = alarmDao.insert(alarm)
|
||||
return alarm.id
|
||||
@Test
|
||||
fun dontScheduleForCompletedTask() = runBlocking {
|
||||
freezeAt(DateTime(2024, 5, 17, 23, 20)) {
|
||||
taskDao.insert(
|
||||
Task(
|
||||
dueDate = createDueDate(
|
||||
Task.URGENCY_SPECIFIC_DAY,
|
||||
DateTime(2024, 5, 17).millis
|
||||
),
|
||||
completionDate = DateTime(2024, 5, 17, 14, 0).millis,
|
||||
)
|
||||
)
|
||||
alarmService.synchronizeAlarms(
|
||||
1,
|
||||
mutableSetOf(Alarm(type = Alarm.TYPE_REL_END))
|
||||
)
|
||||
|
||||
testResults(
|
||||
emptyList(),
|
||||
0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun verify(vararg alarms: AlarmEntry) {
|
||||
alarmService.scheduleAllAlarms()
|
||||
@Test
|
||||
fun dontScheduleForDeletedTask() = runBlocking {
|
||||
freezeAt(DateTime(2024, 5, 17, 23, 20)) {
|
||||
taskDao.insert(
|
||||
Task(
|
||||
dueDate = createDueDate(
|
||||
Task.URGENCY_SPECIFIC_DAY,
|
||||
DateTime(2024, 5, 17).millis
|
||||
),
|
||||
deletionDate = DateTime(2024, 5, 17, 14, 0).millis,
|
||||
)
|
||||
)
|
||||
alarmService.synchronizeAlarms(
|
||||
1,
|
||||
mutableSetOf(Alarm(type = Alarm.TYPE_REL_END))
|
||||
)
|
||||
|
||||
assertEquals(alarms.toList(), jobs.getJobs())
|
||||
testResults(
|
||||
emptyList(),
|
||||
0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun testResults(notifications: List<Notification>, nextAlarm: Long) {
|
||||
val actualNextAlarm = alarmService.triggerAlarms {
|
||||
assertEquals(notifications, it)
|
||||
it.forEach { taskDao.setLastNotified(it.taskId, DateTimeUtils2.currentTimeMillis()) }
|
||||
}
|
||||
assertEquals(nextAlarm, actualNextAlarm)
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Todoroo Inc
|
||||
*
|
||||
* See the file "LICENSE" for the full license governing this code.
|
||||
*/
|
||||
package com.todoroo.astrid.gtasks
|
||||
|
||||
import com.todoroo.astrid.dao.TaskDao
|
||||
import com.todoroo.astrid.data.Task
|
||||
import dagger.hilt.android.testing.HiltAndroidTest
|
||||
import dagger.hilt.android.testing.UninstallModules
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertNotNull
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Test
|
||||
import org.tasks.data.GoogleTask
|
||||
import org.tasks.data.GoogleTaskDao
|
||||
import org.tasks.injection.InjectingTestCase
|
||||
import org.tasks.injection.ProductionModule
|
||||
import javax.inject.Inject
|
||||
|
||||
@UninstallModules(ProductionModule::class)
|
||||
@HiltAndroidTest
|
||||
class GtasksMetadataServiceTest : InjectingTestCase() {
|
||||
@Inject lateinit var taskDao: TaskDao
|
||||
@Inject lateinit var googleTaskDao: GoogleTaskDao
|
||||
|
||||
private var task: Task? = null
|
||||
private var metadata: GoogleTask? = null
|
||||
|
||||
@Test
|
||||
fun testMetadataFound() = runBlocking {
|
||||
givenTask(taskWithMetadata(null))
|
||||
whenSearchForMetadata()
|
||||
thenExpectMetadataFound()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMetadataDoesntExist() = runBlocking {
|
||||
givenTask(taskWithoutMetadata())
|
||||
whenSearchForMetadata()
|
||||
thenExpectNoMetadataFound()
|
||||
}
|
||||
|
||||
private fun thenExpectNoMetadataFound() {
|
||||
assertNull(metadata)
|
||||
}
|
||||
|
||||
private fun thenExpectMetadataFound() {
|
||||
assertNotNull(metadata)
|
||||
}
|
||||
|
||||
// --- helpers
|
||||
private suspend fun whenSearchForMetadata() {
|
||||
metadata = googleTaskDao.getByTaskId(task!!.id)
|
||||
}
|
||||
|
||||
private suspend fun taskWithMetadata(id: String?): Task {
|
||||
val task = Task()
|
||||
task.title = "cats"
|
||||
taskDao.createNew(task)
|
||||
val metadata = GoogleTask(task.id, "")
|
||||
if (id != null) {
|
||||
metadata.remoteId = id
|
||||
}
|
||||
metadata.task = task.id
|
||||
googleTaskDao.insert(metadata)
|
||||
return task
|
||||
}
|
||||
|
||||
private fun givenTask(taskToTest: Task) {
|
||||
task = taskToTest
|
||||
}
|
||||
|
||||
private suspend fun taskWithoutMetadata(): Task {
|
||||
val task = Task()
|
||||
task.title = "dogs"
|
||||
taskDao.createNew(task)
|
||||
return task
|
||||
}
|
||||
}
|
@ -1,50 +1,68 @@
|
||||
package com.todoroo.astrid.repeats
|
||||
|
||||
import com.natpryce.makeiteasy.MakeItEasy.with
|
||||
import org.tasks.data.entity.Task
|
||||
import com.todoroo.astrid.service.TaskCompleter
|
||||
import dagger.hilt.android.testing.HiltAndroidTest
|
||||
import dagger.hilt.android.testing.UninstallModules
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import org.tasks.data.TaskDao
|
||||
import org.tasks.data.dao.TaskDao
|
||||
import org.tasks.injection.InjectingTestCase
|
||||
import org.tasks.injection.ProductionModule
|
||||
import org.tasks.makers.TaskMaker.COMPLETION_TIME
|
||||
import org.tasks.makers.TaskMaker.PARENT
|
||||
import org.tasks.makers.TaskMaker.RECUR
|
||||
import org.tasks.makers.TaskMaker.newTask
|
||||
import org.tasks.time.DateTime
|
||||
import org.tasks.time.DateTimeUtils2.currentTimeMillis
|
||||
import javax.inject.Inject
|
||||
|
||||
@UninstallModules(ProductionModule::class)
|
||||
@HiltAndroidTest
|
||||
class RepeatWithSubtasksTests : InjectingTestCase() {
|
||||
@Inject lateinit var taskDao: TaskDao
|
||||
@Inject lateinit var repeat: RepeatTaskHelper
|
||||
@Inject lateinit var taskCompleter: TaskCompleter
|
||||
|
||||
@Test
|
||||
fun uncompleteGrandchildren() = runBlocking {
|
||||
val grandparent = taskDao.createNew(newTask(with(RECUR, "RRULE:FREQ=DAILY")))
|
||||
val parent = taskDao.createNew(newTask(with(PARENT, grandparent)))
|
||||
val child = taskDao.createNew(newTask(
|
||||
with(PARENT, parent),
|
||||
with(COMPLETION_TIME, DateTime())
|
||||
))
|
||||
val grandparent = taskDao.createNew(
|
||||
Task(
|
||||
recurrence = "RRULE:FREQ=DAILY"
|
||||
)
|
||||
)
|
||||
val parent = taskDao.createNew(
|
||||
Task(
|
||||
parent = grandparent
|
||||
)
|
||||
)
|
||||
val child = taskDao.createNew(
|
||||
Task(
|
||||
parent = parent,
|
||||
completionDate = currentTimeMillis(),
|
||||
)
|
||||
)
|
||||
|
||||
repeat.handleRepeat(taskDao.fetch(grandparent)!!)
|
||||
assertTrue(taskDao.fetch(child)!!.isCompleted)
|
||||
|
||||
taskCompleter.setComplete(grandparent)
|
||||
|
||||
assertFalse(taskDao.fetch(child)!!.isCompleted)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun uncompleteGoogleTaskChildren() = runBlocking {
|
||||
val parent = taskDao.createNew(newTask(with(RECUR, "RRULE:FREQ=DAILY")))
|
||||
val child = taskDao.createNew(newTask(
|
||||
with(PARENT, parent),
|
||||
with(COMPLETION_TIME, DateTime())
|
||||
))
|
||||
val parent = taskDao.createNew(
|
||||
Task(
|
||||
recurrence = "RRULE:FREQ=DAILY"
|
||||
)
|
||||
)
|
||||
val child = taskDao.createNew(
|
||||
Task(
|
||||
parent = parent,
|
||||
completionDate = currentTimeMillis(),
|
||||
)
|
||||
)
|
||||
|
||||
assertTrue(taskDao.fetch(child)!!.isCompleted)
|
||||
|
||||
repeat.handleRepeat(taskDao.fetch(parent)!!)
|
||||
taskCompleter.setComplete(parent)
|
||||
|
||||
assertFalse(taskDao.fetch(child)!!.isCompleted)
|
||||
}
|
||||
|
@ -1,53 +1,31 @@
|
||||
package org.tasks.data
|
||||
|
||||
import com.natpryce.makeiteasy.MakeItEasy.with
|
||||
import dagger.hilt.android.testing.HiltAndroidTest
|
||||
import dagger.hilt.android.testing.UninstallModules
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import org.tasks.data.dao.CaldavDao
|
||||
import org.tasks.data.dao.GoogleTaskListDao
|
||||
import org.tasks.data.entity.CaldavAccount
|
||||
import org.tasks.injection.InjectingTestCase
|
||||
import org.tasks.injection.ProductionModule
|
||||
import org.tasks.makers.GoogleTaskListMaker.ACCOUNT
|
||||
import org.tasks.makers.GoogleTaskListMaker.REMOTE_ID
|
||||
import org.tasks.makers.GoogleTaskListMaker.newGoogleTaskList
|
||||
import javax.inject.Inject
|
||||
|
||||
@UninstallModules(ProductionModule::class)
|
||||
@HiltAndroidTest
|
||||
class GoogleTaskListDaoTest : InjectingTestCase() {
|
||||
@Inject lateinit var googleTaskListDao: GoogleTaskListDao
|
||||
@Inject lateinit var caldavDao: CaldavDao
|
||||
|
||||
@Test
|
||||
fun noResultsForEmptyAccount() = runBlocking {
|
||||
val account = GoogleTaskAccount()
|
||||
account.account = "user@gmail.com"
|
||||
googleTaskListDao.insert(account)
|
||||
val account = CaldavAccount(
|
||||
uuid = "user@gmail.com",
|
||||
username = "user@gmail.com",
|
||||
)
|
||||
caldavDao.insert(account)
|
||||
|
||||
assertTrue(googleTaskListDao.getGoogleTaskFilters(account.account!!).isEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findListWithNullAccount() = runBlocking {
|
||||
val list = newGoogleTaskList(with(REMOTE_ID, "1234"), with(ACCOUNT, null as String?))
|
||||
list.id = googleTaskListDao.insert(list)
|
||||
|
||||
assertEquals(list, googleTaskListDao.findExistingList("1234"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findListWithEmptyAccount() = runBlocking {
|
||||
val list = newGoogleTaskList(with(REMOTE_ID, "1234"), with(ACCOUNT, ""))
|
||||
list.id = googleTaskListDao.insert(list)
|
||||
|
||||
assertEquals(list, googleTaskListDao.findExistingList("1234"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ignoreListWithAccount() = runBlocking {
|
||||
val list = newGoogleTaskList(with(REMOTE_ID, "1234"), with(ACCOUNT, "user@gmail.com"))
|
||||
googleTaskListDao.insert(list)
|
||||
|
||||
assertNull(googleTaskListDao.findExistingList("1234"))
|
||||
assertTrue(googleTaskListDao.getGoogleTaskFilters(account.username!!).isEmpty())
|
||||
}
|
||||
}
|
@ -0,0 +1,161 @@
|
||||
package org.tasks.ui.editviewmodel
|
||||
|
||||
import com.todoroo.astrid.service.TaskDeleter
|
||||
import dagger.hilt.android.testing.HiltAndroidTest
|
||||
import dagger.hilt.android.testing.UninstallModules
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.tasks.LocalBroadcastManager
|
||||
import org.tasks.analytics.Firebase
|
||||
import org.tasks.billing.Inventory
|
||||
import org.tasks.data.dao.DeletionDao
|
||||
import org.tasks.data.dao.TaskDao
|
||||
import org.tasks.data.entity.Task
|
||||
import org.tasks.filters.MyTasksFilter
|
||||
import org.tasks.injection.InjectingTestCase
|
||||
import org.tasks.injection.ProductionModule
|
||||
import org.tasks.preferences.Preferences
|
||||
import org.tasks.time.DateTimeUtils2.currentTimeMillis
|
||||
import org.tasks.ui.TaskListViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
@UninstallModules(ProductionModule::class)
|
||||
@HiltAndroidTest
|
||||
class TaskListViewModelTest : InjectingTestCase() {
|
||||
private lateinit var viewModel: TaskListViewModel
|
||||
@Inject lateinit var preferences: Preferences
|
||||
@Inject lateinit var taskDao: TaskDao
|
||||
@Inject lateinit var taskDeleter: TaskDeleter
|
||||
@Inject lateinit var deletionDao: DeletionDao
|
||||
@Inject lateinit var localBroadcastManager: LocalBroadcastManager
|
||||
@Inject lateinit var inventory: Inventory
|
||||
@Inject lateinit var firebase: Firebase
|
||||
|
||||
@Before
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
viewModel = TaskListViewModel(
|
||||
context = context,
|
||||
preferences = preferences,
|
||||
taskDao = taskDao,
|
||||
deletionDao = deletionDao,
|
||||
taskDeleter = taskDeleter,
|
||||
localBroadcastManager = localBroadcastManager,
|
||||
inventory = inventory,
|
||||
firebase = firebase,
|
||||
)
|
||||
viewModel.setFilter(runBlocking { MyTasksFilter.create() })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun clearCompletedTask() = runBlocking {
|
||||
val task = taskDao.createNew(
|
||||
Task(completionDate = currentTimeMillis())
|
||||
)
|
||||
|
||||
clearCompleted()
|
||||
|
||||
assertTrue(taskDao.fetch(task)!!.isDeleted)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dontDeleteTaskWithRecurringParent() = runBlocking {
|
||||
val parent = taskDao.createNew(
|
||||
Task(
|
||||
recurrence = "RRULE:FREQ=DAILY;INTERVAL=1"
|
||||
)
|
||||
)
|
||||
val child = taskDao.createNew(
|
||||
Task(
|
||||
parent = parent,
|
||||
completionDate = currentTimeMillis(),
|
||||
)
|
||||
)
|
||||
|
||||
clearCompleted()
|
||||
|
||||
assertFalse(taskDao.fetch(child)!!.isDeleted)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dontDeleteTaskWithRecurringGrandparent() = runBlocking {
|
||||
val grandparent = taskDao.createNew(
|
||||
Task(recurrence = "RRULE:FREQ=DAILY;INTERVAL=1")
|
||||
)
|
||||
val parent = taskDao.createNew(
|
||||
Task(parent = grandparent)
|
||||
)
|
||||
val child = taskDao.createNew(
|
||||
Task(
|
||||
parent = parent,
|
||||
completionDate = currentTimeMillis(),
|
||||
)
|
||||
)
|
||||
|
||||
clearCompleted()
|
||||
|
||||
assertFalse(taskDao.fetch(child)!!.isDeleted)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun clearGrandchildWithNoRecurringAncestors() = runBlocking {
|
||||
val grandparent = taskDao.createNew(Task())
|
||||
val parent = taskDao.createNew(
|
||||
Task(parent = grandparent)
|
||||
)
|
||||
val child = taskDao.createNew(
|
||||
Task(
|
||||
parent = parent,
|
||||
completionDate = currentTimeMillis(),
|
||||
)
|
||||
)
|
||||
|
||||
clearCompleted()
|
||||
|
||||
assertTrue(taskDao.fetch(child)!!.isDeleted)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun clearGrandchildWithCompletedRecurringAncestor() = runBlocking {
|
||||
val grandparent = taskDao.createNew(
|
||||
Task(
|
||||
recurrence = "RRULE:FREQ=DAILY;INTERVAL=1",
|
||||
completionDate = currentTimeMillis(),
|
||||
)
|
||||
)
|
||||
val parent = taskDao.createNew(
|
||||
Task(parent = grandparent)
|
||||
)
|
||||
val child = taskDao.createNew(
|
||||
Task(
|
||||
parent = parent,
|
||||
completionDate = currentTimeMillis(),
|
||||
)
|
||||
)
|
||||
|
||||
clearCompleted()
|
||||
|
||||
assertTrue(taskDao.fetch(child)!!.isDeleted)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun clearHiddenSubtask() = runBlocking {
|
||||
preferences.showCompleted = false
|
||||
val parent = taskDao.createNew(Task())
|
||||
val child = taskDao.createNew(
|
||||
Task(
|
||||
parent = parent,
|
||||
completionDate = currentTimeMillis(),
|
||||
)
|
||||
)
|
||||
|
||||
clearCompleted()
|
||||
|
||||
assertTrue(taskDao.fetch(child)!!.isDeleted)
|
||||
}
|
||||
|
||||
private suspend fun clearCompleted() = viewModel.markDeleted(viewModel.getTasksToClear())
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config xmlns:tools="http://schemas.android.com/tools">
|
||||
<base-config
|
||||
cleartextTrafficPermitted="true"
|
||||
tools:ignore="InsecureBaseConfiguration" />
|
||||
</network-security-config>
|
@ -1,8 +0,0 @@
|
||||
package com.todoroo.andlib.data
|
||||
|
||||
import com.todoroo.andlib.sql.Field
|
||||
|
||||
class Property internal constructor(val name: String?, expression: String) : Field(expression) {
|
||||
|
||||
constructor(table: Table, columnName: String) : this(columnName, "${table.name()}.$columnName")
|
||||
}
|
@ -1,230 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Todoroo Inc
|
||||
*
|
||||
* See the file "LICENSE" for the full license governing this code.
|
||||
*/
|
||||
|
||||
package com.todoroo.andlib.utility;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.Build.VERSION;
|
||||
import android.os.Build.VERSION_CODES;
|
||||
import android.os.Looper;
|
||||
import android.text.InputType;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.tasks.BuildConfig;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* Android Utility Classes
|
||||
*
|
||||
* @author Tim Su <tim@todoroo.com>
|
||||
*/
|
||||
public class AndroidUtilities {
|
||||
|
||||
public static final String SEPARATOR_ESCAPE = "!PIPE!"; // $NON-NLS-1$
|
||||
public static final String SERIALIZATION_SEPARATOR = "|"; // $NON-NLS-1$
|
||||
|
||||
// --- utility methods
|
||||
|
||||
/** Suppress virtual keyboard until user's first tap */
|
||||
public static void suppressVirtualKeyboard(final TextView editor) {
|
||||
final int inputType = editor.getInputType();
|
||||
editor.setInputType(InputType.TYPE_NULL);
|
||||
editor.setOnTouchListener(
|
||||
(v, event) -> {
|
||||
editor.setInputType(inputType);
|
||||
editor.setOnTouchListener(null);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
// --- serialization
|
||||
|
||||
/** Serializes a content value into a string */
|
||||
public static String mapToSerializedString(Map<String, Object> source) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (Entry<String, Object> entry : source.entrySet()) {
|
||||
addSerialized(result, entry.getKey(), entry.getValue());
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/** add serialized helper */
|
||||
private static void addSerialized(StringBuilder result, String key, Object value) {
|
||||
result
|
||||
.append(key.replace(SERIALIZATION_SEPARATOR, SEPARATOR_ESCAPE))
|
||||
.append(SERIALIZATION_SEPARATOR);
|
||||
if (value instanceof Integer) {
|
||||
result.append('i').append(value);
|
||||
} else if (value instanceof Double) {
|
||||
result.append('d').append(value);
|
||||
} else if (value instanceof Long) {
|
||||
result.append('l').append(value);
|
||||
} else if (value instanceof String) {
|
||||
result
|
||||
.append('s')
|
||||
.append(value.toString().replace(SERIALIZATION_SEPARATOR, SEPARATOR_ESCAPE));
|
||||
} else if (value instanceof Boolean) {
|
||||
result.append('b').append(value);
|
||||
} else {
|
||||
throw new UnsupportedOperationException(value.getClass().toString());
|
||||
}
|
||||
result.append(SERIALIZATION_SEPARATOR);
|
||||
}
|
||||
|
||||
public static Map<String, Object> mapFromSerializedString(String string) {
|
||||
if (string == null) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
fromSerialized(
|
||||
string,
|
||||
result,
|
||||
(object, key, type, value) -> {
|
||||
switch (type) {
|
||||
case 'i':
|
||||
object.put(key, Integer.parseInt(value));
|
||||
break;
|
||||
case 'd':
|
||||
object.put(key, Double.parseDouble(value));
|
||||
break;
|
||||
case 'l':
|
||||
object.put(key, Long.parseLong(value));
|
||||
break;
|
||||
case 's':
|
||||
object.put(key, value.replace(SEPARATOR_ESCAPE, SERIALIZATION_SEPARATOR));
|
||||
break;
|
||||
case 'b':
|
||||
object.put(key, Boolean.parseBoolean(value));
|
||||
break;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
private static <T> void fromSerialized(String string, T object, SerializedPut<T> putter) {
|
||||
String[] pairs = string.split("\\" + SERIALIZATION_SEPARATOR); // $NON-NLS-1$
|
||||
for (int i = 0; i < pairs.length; i += 2) {
|
||||
try {
|
||||
String key = pairs[i].replaceAll(SEPARATOR_ESCAPE, SERIALIZATION_SEPARATOR);
|
||||
String value = pairs[i + 1].substring(1);
|
||||
try {
|
||||
putter.put(object, key, pairs[i + 1].charAt(0), value);
|
||||
} catch (NumberFormatException e) {
|
||||
// failed parse to number
|
||||
putter.put(object, key, 's', value);
|
||||
Timber.e(e);
|
||||
}
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
Timber.e(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int convertDpToPixels(DisplayMetrics displayMetrics, int dp) {
|
||||
// developer.android.com/guide/practices/screens_support.html#dips-pels
|
||||
return (int) (dp * displayMetrics.density + 0.5f);
|
||||
}
|
||||
|
||||
public static boolean preOreo() {
|
||||
return !atLeastOreo();
|
||||
}
|
||||
|
||||
public static boolean preTiramisu() {
|
||||
return VERSION.SDK_INT < VERSION_CODES.TIRAMISU;
|
||||
}
|
||||
|
||||
public static boolean atLeastNougatMR1() {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1;
|
||||
}
|
||||
|
||||
public static boolean atLeastOreo() {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
|
||||
}
|
||||
|
||||
public static boolean atLeastP() {
|
||||
return VERSION.SDK_INT >= Build.VERSION_CODES.P;
|
||||
}
|
||||
|
||||
public static boolean atLeastQ() {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q;
|
||||
}
|
||||
|
||||
public static boolean atLeastR() {
|
||||
return VERSION.SDK_INT >= VERSION_CODES.R;
|
||||
}
|
||||
|
||||
public static boolean atLeastS() {
|
||||
return VERSION.SDK_INT >= VERSION_CODES.S;
|
||||
}
|
||||
|
||||
public static boolean atLeastTiramisu() {
|
||||
return VERSION.SDK_INT >= VERSION_CODES.TIRAMISU;
|
||||
}
|
||||
|
||||
public static void assertMainThread() {
|
||||
if (BuildConfig.DEBUG && !isMainThread()) {
|
||||
throw new IllegalStateException("Should be called from main thread");
|
||||
}
|
||||
}
|
||||
|
||||
public static void assertNotMainThread() {
|
||||
if (BuildConfig.DEBUG && isMainThread()) {
|
||||
throw new IllegalStateException("Should not be called from main thread");
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isMainThread() {
|
||||
return Thread.currentThread() == Looper.getMainLooper().getThread();
|
||||
}
|
||||
|
||||
/** Capitalize the first character */
|
||||
public static String capitalize(String string) {
|
||||
return string.substring(0, 1).toUpperCase() + string.substring(1);
|
||||
}
|
||||
|
||||
public static void hideKeyboard(Activity activity) {
|
||||
try {
|
||||
View currentFocus = activity.getCurrentFocus();
|
||||
if (currentFocus != null) {
|
||||
InputMethodManager inputMethodManager =
|
||||
(InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
inputMethodManager.hideSoftInputFromWindow(currentFocus.getWindowToken(), 0);
|
||||
currentFocus.clearFocus();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Timber.e(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismiss the keyboard if it is displayed by any of the listed views
|
||||
*
|
||||
* @param views - a list of views that might potentially be displaying the keyboard
|
||||
*/
|
||||
public static void hideSoftInputForViews(Context context, View... views) {
|
||||
InputMethodManager imm =
|
||||
(InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
for (View v : views) {
|
||||
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
interface SerializedPut<T> {
|
||||
|
||||
void put(T object, String key, char type, String value) throws NumberFormatException;
|
||||
}
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Todoroo Inc
|
||||
*
|
||||
* See the file "LICENSE" for the full license governing this code.
|
||||
*/
|
||||
package com.todoroo.andlib.utility
|
||||
|
||||
import android.os.Build
|
||||
import android.os.Build.VERSION_CODES
|
||||
import android.os.Looper
|
||||
import android.text.InputType
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import org.tasks.BuildConfig
|
||||
|
||||
/**
|
||||
* Android Utility Classes
|
||||
*
|
||||
* @author Tim Su <tim></tim>@todoroo.com>
|
||||
*/
|
||||
object AndroidUtilities {
|
||||
// --- utility methods
|
||||
/** Suppress virtual keyboard until user's first tap */
|
||||
@JvmStatic
|
||||
fun suppressVirtualKeyboard(editor: TextView) {
|
||||
val inputType = editor.inputType
|
||||
editor.inputType = InputType.TYPE_NULL
|
||||
editor.setOnTouchListener { v: View?, event: MotionEvent? ->
|
||||
editor.inputType = inputType
|
||||
editor.setOnTouchListener(null)
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fun convertDpToPixels(displayMetrics: DisplayMetrics, dp: Int): Int {
|
||||
// developer.android.com/guide/practices/screens_support.html#dips-pels
|
||||
return (dp * displayMetrics.density + 0.5f).toInt()
|
||||
}
|
||||
|
||||
fun preOreo(): Boolean {
|
||||
return !atLeastOreo()
|
||||
}
|
||||
|
||||
fun preS(): Boolean {
|
||||
return !atLeastS()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun preTiramisu(): Boolean {
|
||||
return !atLeastTiramisu()
|
||||
}
|
||||
|
||||
fun preUpsideDownCake(): Boolean {
|
||||
return Build.VERSION.SDK_INT <= VERSION_CODES.TIRAMISU
|
||||
}
|
||||
|
||||
fun atLeastNougatMR1(): Boolean {
|
||||
return Build.VERSION.SDK_INT >= VERSION_CODES.N_MR1
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun atLeastOreo(): Boolean {
|
||||
return Build.VERSION.SDK_INT >= VERSION_CODES.O
|
||||
}
|
||||
|
||||
fun atLeastOreoMR1(): Boolean {
|
||||
return Build.VERSION.SDK_INT >= VERSION_CODES.O_MR1
|
||||
}
|
||||
|
||||
fun atLeastP(): Boolean {
|
||||
return Build.VERSION.SDK_INT >= VERSION_CODES.P
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun atLeastQ(): Boolean {
|
||||
return Build.VERSION.SDK_INT >= VERSION_CODES.Q
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun atLeastR(): Boolean {
|
||||
return Build.VERSION.SDK_INT >= VERSION_CODES.R
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun atLeastS(): Boolean {
|
||||
return Build.VERSION.SDK_INT >= VERSION_CODES.S
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun atLeastTiramisu(): Boolean {
|
||||
return Build.VERSION.SDK_INT >= VERSION_CODES.TIRAMISU
|
||||
}
|
||||
|
||||
fun assertMainThread() {
|
||||
check(!(BuildConfig.DEBUG && !isMainThread)) { "Should be called from main thread" }
|
||||
}
|
||||
|
||||
fun assertNotMainThread() {
|
||||
check(!(BuildConfig.DEBUG && isMainThread)) { "Should not be called from main thread" }
|
||||
}
|
||||
|
||||
private val isMainThread: Boolean
|
||||
get() = Thread.currentThread() === Looper.getMainLooper().thread
|
||||
}
|
@ -0,0 +1,217 @@
|
||||
package com.todoroo.astrid.activity
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.datastore.preferences.core.booleanPreferencesKey
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.todoroo.astrid.activity.MainActivity.Companion.LOAD_FILTER
|
||||
import com.todoroo.astrid.activity.MainActivity.Companion.OPEN_FILTER
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.tasks.LocalBroadcastManager
|
||||
import org.tasks.Tasks.Companion.IS_GENERIC
|
||||
import org.tasks.billing.Inventory
|
||||
import org.tasks.compose.drawer.DrawerItem
|
||||
import org.tasks.data.NO_COUNT
|
||||
import org.tasks.data.count
|
||||
import org.tasks.data.dao.CaldavDao
|
||||
import org.tasks.data.dao.TaskDao
|
||||
import org.tasks.data.entity.Task
|
||||
import org.tasks.filters.CaldavFilter
|
||||
import org.tasks.filters.Filter
|
||||
import org.tasks.filters.FilterProvider
|
||||
import org.tasks.filters.NavigationDrawerSubheader
|
||||
import org.tasks.filters.getIcon
|
||||
import org.tasks.preferences.TasksPreferences
|
||||
import org.tasks.preferences.DefaultFilterProvider
|
||||
import org.tasks.themes.ColorProvider
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class MainActivityViewModel @Inject constructor(
|
||||
savedStateHandle: SavedStateHandle,
|
||||
private val defaultFilterProvider: DefaultFilterProvider,
|
||||
private val filterProvider: FilterProvider,
|
||||
private val taskDao: TaskDao,
|
||||
private val localBroadcastManager: LocalBroadcastManager,
|
||||
private val inventory: Inventory,
|
||||
private val colorProvider: ColorProvider,
|
||||
private val caldavDao: CaldavDao,
|
||||
private val tasksPreferences: TasksPreferences,
|
||||
) : ViewModel() {
|
||||
|
||||
data class State(
|
||||
val begForMoney: Boolean = false,
|
||||
val filter: Filter,
|
||||
val task: Task? = null,
|
||||
val drawerItems: ImmutableList<DrawerItem> = persistentListOf(),
|
||||
val searchItems: ImmutableList<DrawerItem> = persistentListOf(),
|
||||
val menuQuery: String = "",
|
||||
)
|
||||
|
||||
private val _drawerOpen = MutableStateFlow(false)
|
||||
val drawerOpen = _drawerOpen.asStateFlow()
|
||||
|
||||
private val _state = MutableStateFlow(
|
||||
State(
|
||||
filter = savedStateHandle.get<Filter>(OPEN_FILTER)
|
||||
?: savedStateHandle.get<String>(LOAD_FILTER)?.let {
|
||||
runBlocking { defaultFilterProvider.getFilterFromPreference(it) }
|
||||
}
|
||||
?: runBlocking { defaultFilterProvider.getStartupFilter() },
|
||||
begForMoney = if (IS_GENERIC) !inventory.hasTasksAccount else !inventory.hasPro,
|
||||
)
|
||||
)
|
||||
val state = _state.asStateFlow()
|
||||
|
||||
private val refreshReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
when (intent?.action) {
|
||||
LocalBroadcastManager.REFRESH,
|
||||
LocalBroadcastManager.REFRESH_LIST -> updateFilters()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun resetFilter() {
|
||||
setFilter(defaultFilterProvider.getDefaultOpenFilter())
|
||||
}
|
||||
|
||||
fun setFilter(
|
||||
filter: Filter,
|
||||
task: Task? = null,
|
||||
) {
|
||||
if (filter == _state.value.filter && task == null) {
|
||||
return
|
||||
}
|
||||
_state.update {
|
||||
it.copy(
|
||||
filter = filter,
|
||||
task = task,
|
||||
)
|
||||
}
|
||||
updateFilters()
|
||||
defaultFilterProvider.setLastViewedFilter(filter)
|
||||
}
|
||||
|
||||
fun closeDrawer() {
|
||||
_drawerOpen.update { false }
|
||||
_state.update { it.copy(menuQuery = "") }
|
||||
}
|
||||
|
||||
fun openDrawer() {
|
||||
_drawerOpen.update { true }
|
||||
}
|
||||
|
||||
init {
|
||||
localBroadcastManager.registerRefreshListReceiver(refreshReceiver)
|
||||
updateFilters()
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
localBroadcastManager.unregisterReceiver(refreshReceiver)
|
||||
}
|
||||
|
||||
fun updateFilters() = viewModelScope.launch(Dispatchers.Default) {
|
||||
val selected = state.value.filter
|
||||
filterProvider
|
||||
.drawerItems()
|
||||
.map { item ->
|
||||
when (item) {
|
||||
is Filter ->
|
||||
DrawerItem.Filter(
|
||||
title = item.title ?: "",
|
||||
icon = item.getIcon(inventory),
|
||||
color = getColor(item),
|
||||
count = item.count.takeIf { it != NO_COUNT } ?: try {
|
||||
taskDao.count(item)
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e)
|
||||
0
|
||||
},
|
||||
selected = item.areItemsTheSame(selected),
|
||||
shareCount = if (item is CaldavFilter) item.principals else 0,
|
||||
filter = item,
|
||||
)
|
||||
is NavigationDrawerSubheader ->
|
||||
DrawerItem.Header(
|
||||
title = item.title ?: "",
|
||||
collapsed = item.isCollapsed,
|
||||
hasError = item.error,
|
||||
canAdd = item.addIntentRc != 0,
|
||||
header = item,
|
||||
)
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
}
|
||||
.let { filters -> _state.update { it.copy(drawerItems = filters.toPersistentList()) } }
|
||||
val query = _state.value.menuQuery
|
||||
filterProvider
|
||||
.allFilters()
|
||||
.filter { it.title!!.contains(query, ignoreCase = true) }
|
||||
.map { item ->
|
||||
DrawerItem.Filter(
|
||||
title = item.title ?: "",
|
||||
icon = item.getIcon(inventory),
|
||||
color = getColor(item),
|
||||
count = item.count.takeIf { it != NO_COUNT } ?: try {
|
||||
taskDao.count(item)
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e)
|
||||
0
|
||||
},
|
||||
selected = item.areItemsTheSame(selected),
|
||||
shareCount = if (item is CaldavFilter) item.principals else 0,
|
||||
filter = item,
|
||||
)
|
||||
}
|
||||
.let { filters -> _state.update { it.copy(searchItems = filters.toPersistentList()) } }
|
||||
}
|
||||
|
||||
private fun getColor(filter: Filter): Int {
|
||||
if (filter.tint != 0) {
|
||||
val color = colorProvider.getThemeColor(filter.tint, true)
|
||||
if (color.isFree || inventory.purchasedThemes()) {
|
||||
return color.primaryColor
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
fun toggleCollapsed(subheader: NavigationDrawerSubheader) = viewModelScope.launch {
|
||||
val collapsed = !subheader.isCollapsed
|
||||
when (subheader.subheaderType) {
|
||||
NavigationDrawerSubheader.SubheaderType.PREFERENCE -> {
|
||||
tasksPreferences.set(booleanPreferencesKey(subheader.id), collapsed)
|
||||
localBroadcastManager.broadcastRefreshList()
|
||||
}
|
||||
NavigationDrawerSubheader.SubheaderType.GOOGLE_TASKS,
|
||||
NavigationDrawerSubheader.SubheaderType.CALDAV,
|
||||
NavigationDrawerSubheader.SubheaderType.TASKS -> {
|
||||
caldavDao.setCollapsed(subheader.id, collapsed)
|
||||
localBroadcastManager.broadcastRefreshList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setTask(task: Task?) {
|
||||
_state.update { it.copy(task = task) }
|
||||
}
|
||||
|
||||
fun queryMenu(query: String) {
|
||||
_state.update { it.copy(menuQuery = query) }
|
||||
updateFilters()
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,38 +0,0 @@
|
||||
package com.todoroo.astrid.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.todoroo.astrid.api.FilterListItem
|
||||
import org.tasks.databinding.FilterAdapterActionBinding
|
||||
import org.tasks.themes.DrawableUtil
|
||||
|
||||
class ActionViewHolder internal constructor(
|
||||
private val context: Context,
|
||||
itemView: View,
|
||||
private val onClick: ((FilterListItem?) -> Unit)?) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
private val row: View
|
||||
private val text: TextView
|
||||
private val icon: ImageView
|
||||
|
||||
init {
|
||||
FilterAdapterActionBinding.bind(itemView).let {
|
||||
row = it.row
|
||||
text = it.text
|
||||
icon = it.icon
|
||||
}
|
||||
}
|
||||
|
||||
fun bind(filter: FilterListItem) {
|
||||
text.text = filter.listingTitle
|
||||
icon.setImageDrawable(DrawableUtil.getWrapped(context, filter.icon))
|
||||
if (onClick != null) {
|
||||
row.setOnClickListener {
|
||||
onClick.invoke(filter)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,61 +1,20 @@
|
||||
package com.todoroo.astrid.adapter
|
||||
|
||||
import com.todoroo.astrid.dao.TaskDao
|
||||
import com.todoroo.astrid.service.TaskMover
|
||||
import org.tasks.LocalBroadcastManager
|
||||
import org.tasks.data.CaldavDao
|
||||
import org.tasks.data.GoogleTaskDao
|
||||
import org.tasks.data.TaskContainer
|
||||
import org.tasks.data.dao.CaldavDao
|
||||
import org.tasks.data.dao.GoogleTaskDao
|
||||
|
||||
class CaldavManualSortTaskAdapter internal constructor(
|
||||
googleTaskDao: GoogleTaskDao,
|
||||
private val caldavDao: CaldavDao,
|
||||
private val taskDao: TaskDao,
|
||||
private val localBroadcastManager: LocalBroadcastManager)
|
||||
: TaskAdapter(false, googleTaskDao, caldavDao, taskDao, localBroadcastManager) {
|
||||
caldavDao: CaldavDao,
|
||||
taskDao: TaskDao,
|
||||
localBroadcastManager: LocalBroadcastManager,
|
||||
taskMover: TaskMover,
|
||||
) : TaskAdapter(false, googleTaskDao, caldavDao, taskDao, localBroadcastManager, taskMover) {
|
||||
|
||||
override suspend fun moved(from: Int, to: Int, indent: Int) {
|
||||
val task = getTask(from)
|
||||
val oldParent = task.parent
|
||||
val newParent = changeParent(task, indent, to)
|
||||
|
||||
if (oldParent == newParent && from == to) {
|
||||
return
|
||||
}
|
||||
|
||||
val previous = if (to > 0) getTask(to - 1) else null
|
||||
val next = if (to < count) getTask(to) else null
|
||||
|
||||
val newPosition = when {
|
||||
previous == null -> next!!.caldavSortOrder - 1
|
||||
indent > previous.getIndent() && next?.indent == indent -> next.caldavSortOrder - 1
|
||||
indent > previous.getIndent() -> null
|
||||
indent == previous.getIndent() -> previous.caldavSortOrder + 1
|
||||
else -> getTask((to - 1 downTo 0).find { getTask(it).indent == indent }!!).caldavSortOrder + 1
|
||||
}
|
||||
caldavDao.move(task, newParent, newPosition)
|
||||
taskDao.touch(task.id)
|
||||
localBroadcastManager.broadcastRefresh()
|
||||
}
|
||||
|
||||
private suspend fun changeParent(task: TaskContainer, indent: Int, to: Int): Long {
|
||||
val newParent = findParent(indent, to)?.id ?: 0
|
||||
if (task.parent != newParent) {
|
||||
changeParent(task, newParent)
|
||||
}
|
||||
return newParent
|
||||
}
|
||||
|
||||
private suspend fun changeParent(task: TaskContainer, newParent: Long) {
|
||||
val caldavTask = task.getCaldavTask()
|
||||
if (newParent == 0L) {
|
||||
caldavTask.cd_remote_parent = ""
|
||||
task.parent = 0
|
||||
} else {
|
||||
val parentTask = caldavDao.getTask(newParent) ?: return
|
||||
caldavTask.cd_remote_parent = parentTask.remoteId
|
||||
task.parent = newParent
|
||||
}
|
||||
caldavDao.update(caldavTask.cd_id, caldavTask.cd_remote_parent)
|
||||
taskDao.save(task.getTask(), null)
|
||||
moveCaldavTask(from, to, indent)
|
||||
}
|
||||
}
|
@ -1,43 +1,20 @@
|
||||
package com.todoroo.astrid.adapter
|
||||
|
||||
import com.todoroo.astrid.dao.TaskDao
|
||||
import org.tasks.BuildConfig
|
||||
import com.todoroo.astrid.service.TaskMover
|
||||
import org.tasks.LocalBroadcastManager
|
||||
import org.tasks.data.CaldavDao
|
||||
import org.tasks.data.GoogleTaskDao
|
||||
import org.tasks.data.dao.CaldavDao
|
||||
import org.tasks.data.dao.GoogleTaskDao
|
||||
|
||||
class GoogleTaskManualSortAdapter internal constructor(
|
||||
private val googleTaskDao: GoogleTaskDao,
|
||||
googleTaskDao: GoogleTaskDao,
|
||||
caldavDao: CaldavDao,
|
||||
private val taskDao: TaskDao,
|
||||
private val localBroadcastManager: LocalBroadcastManager)
|
||||
: TaskAdapter(false, googleTaskDao, caldavDao, taskDao, localBroadcastManager) {
|
||||
taskDao: TaskDao,
|
||||
localBroadcastManager: LocalBroadcastManager,
|
||||
taskMover: TaskMover,
|
||||
) : TaskAdapter(false, googleTaskDao, caldavDao, taskDao, localBroadcastManager, taskMover) {
|
||||
|
||||
override suspend fun moved(from: Int, to: Int, indent: Int) {
|
||||
val task = getTask(from)
|
||||
val googleTask = task.googleTask
|
||||
val previous = if (to > 0) getTask(to - 1) else null
|
||||
if (previous == null) {
|
||||
googleTaskDao.move(googleTask, 0, 0)
|
||||
} else if (to == count || to <= from) {
|
||||
when {
|
||||
indent == 0 -> googleTaskDao.move(googleTask, 0, previous.getPrimarySort() + if (to == count) 0 else 1)
|
||||
previous.hasParent() && previous.parent == googleTask.parent -> googleTaskDao.move(googleTask, previous.parent, previous.getSecondarySort() + if (to == count) 0 else 1)
|
||||
previous.hasParent() -> googleTaskDao.move(googleTask, previous.parent, previous.getSecondarySort() + 1)
|
||||
else -> googleTaskDao.move(googleTask, previous.id, 0)
|
||||
}
|
||||
} else {
|
||||
when {
|
||||
indent == 0 -> googleTaskDao.move(googleTask, 0, previous.getPrimarySort() + if (task.hasParent()) 1 else 0)
|
||||
previous.hasParent() && previous.parent == googleTask.parent -> googleTaskDao.move(googleTask, previous.parent, previous.getSecondarySort())
|
||||
previous.hasParent() -> googleTaskDao.move(googleTask, previous.parent, previous.getSecondarySort() + 1)
|
||||
else -> googleTaskDao.move(googleTask, previous.id, 0)
|
||||
}
|
||||
}
|
||||
taskDao.touch(task.id)
|
||||
localBroadcastManager.broadcastRefresh()
|
||||
if (BuildConfig.DEBUG) {
|
||||
googleTaskDao.validateSorting(task.googleTaskList!!)
|
||||
}
|
||||
moveGoogleTask(from, to, indent)
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue