Compare commits
767 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4cc96de806 | |||
| d27ef12039 | |||
| f3c2ee4c40 | |||
| 555f73b478 | |||
| 544bf2ea21 | |||
| 54bbb5e384 | |||
| b10062c73d | |||
| a027d6df1b | |||
| 926a53a4b0 | |||
| 406cb46170 | |||
| acc58dc892 | |||
| 55894c22a4 | |||
| 476b10b862 | |||
| 3cbbe446ab | |||
| 4cf7512ee0 | |||
| ee8ec460a1 | |||
| deecab3cca | |||
| d2f5c1a195 | |||
| dba77e26a3 | |||
| fa48bafbc6 | |||
| 73c48694c7 | |||
| 0ff89d039b | |||
| 7a7081ee13 | |||
| 874aaf4e93 | |||
| ebf076d9f6 | |||
| 073a041d4c | |||
| 96a9b4dabd | |||
| 8e4cdf2386 | |||
| ab4d925a5a | |||
| d9c6f52e21 | |||
| 0a748cd53b | |||
| 07314ef018 | |||
| 5eaebf678f | |||
| 80fbfa60de | |||
| fbbcc9e9b6 | |||
| f47dc6b9de | |||
| 5f8e74f017 | |||
| 8c1ca0ac7e | |||
| 9018de3c4c | |||
| e7cb88c757 | |||
| d6127d6811 | |||
| 67e09e2e1d | |||
| 8fbc24c751 | |||
| c0948209be | |||
| 7237161d52 | |||
| 94c2e21e2b | |||
| 65067e6e01 | |||
| 39490ce7ba | |||
| 2f3f47c745 | |||
| 2195c3df76 | |||
| 119b9db6b4 | |||
| fcbc598732 | |||
| e850049e8e | |||
| 907adea73f | |||
| 2ac5c1362c | |||
| 8b20e2b48f | |||
| c2a9820fc1 | |||
| a9e5bc0c95 | |||
| 0fa2834d25 | |||
| 23f0876c00 | |||
| 6d88d90659 | |||
| a3c366c360 | |||
| 3bef07eeab | |||
| d029e65b8e | |||
| f305ac6905 | |||
| 4d4a46d2a5 | |||
| 8218f2f830 | |||
| b1bf901eac | |||
| 06eff55210 | |||
| 71730fddad | |||
| f2d1c6e3cb | |||
| 7ae837ca3c | |||
| b10908df5e | |||
| 4dd4d38d5b | |||
| 447c286b56 | |||
| c71898ece9 | |||
| 9473e88ea9 | |||
| d7663ed56e | |||
| da7569e2f5 | |||
| d989940a4d | |||
| bd6a86b135 | |||
| b38eb11503 | |||
| 7aef32c13d | |||
| fab64b147c | |||
| cc5a63205c | |||
| 814166a884 | |||
| 55240d9e9b | |||
| 9dc598150f | |||
| 21c087e273 | |||
| bdf3a7014f | |||
| dfea6e9b1b | |||
| 50eef1190e | |||
| ed180121ff | |||
| bdb0ad89d4 | |||
| 7195a30d55 | |||
| 5b0426a94c | |||
| a6d012abd9 | |||
| 86f0b3f29f | |||
| 85e3aa34ac | |||
| 5bbc1dedef | |||
| 39b468ef06 | |||
| fe17176b31 | |||
| 84f701c4ab | |||
| 047f8c176f | |||
| d82e79b680 | |||
| 320d1ae9d8 | |||
| a8892143a2 | |||
| 50f4532406 | |||
| 844454053d | |||
| db5c5ed534 | |||
| a26b8ecca0 | |||
| 5a32ccfa7a | |||
| f51818b157 | |||
| 31a624db51 | |||
| f045b18762 | |||
| f5006cac7d | |||
| 152b193ad5 | |||
| a27af0b642 | |||
| 44ffed3f7c | |||
| fa035ad9be | |||
| 186ace4343 | |||
| 8fb1a0bb1f | |||
| 05513bf8b9 | |||
| 858784857e | |||
| 291a23949a | |||
| 454de23844 | |||
| 1176092fc6 | |||
| 0fc2c57395 | |||
| 0b292f8d74 | |||
| 4bbe51331f | |||
| c289786dfa | |||
| 9a9752a6a1 | |||
| c43b688f8e | |||
| a6272d5221 | |||
| b440a58d95 | |||
| ec1589aa2d | |||
| 8d48e56fa0 | |||
| df7938037e | |||
| c908ee2d49 | |||
| b714abddae | |||
| 63ca189907 | |||
| 6130fb9ba2 | |||
| f0edc676fc | |||
| b68fdb0772 | |||
| 76c7bdd604 | |||
| 205101568e | |||
| efff68c49b | |||
| f74f60bb1d | |||
| 63ea28a620 | |||
| 2c6d043277 | |||
| 9a226f7b64 | |||
| 3b73a0fd72 | |||
| 2478aa77cd | |||
| a41068dbc9 | |||
| 5e47b7ae6b | |||
| debf45a7d5 | |||
| e7041e8c8c | |||
| bd960992bc | |||
| 0c5f6b432c | |||
| 49232edbd5 | |||
| b02884f58d | |||
| 845b588426 | |||
| 3a97d7c8be | |||
| 2cb2ded2d9 | |||
| 14e02bee6c | |||
| 30f7cdc1ba | |||
| 420d14fc37 | |||
| 3d7953d977 | |||
| 35238b3da1 | |||
| 446f4283e0 | |||
| 8062dd3709 | |||
| 41c8fde8c5 | |||
| d90b986d19 | |||
| 64ea8416b2 | |||
| 100a4c9d35 | |||
| 4ef6dec89a | |||
| a14cdc48bd | |||
| 8a4ddbc6df | |||
| ee33acc561 | |||
| 5fe69becf3 | |||
| d460d3ccdf | |||
| 0ee74943e8 | |||
| 82837e38d2 | |||
| 91df90d760 | |||
| 1ee37da720 | |||
| 6f8fc5b69d | |||
| be1918c769 | |||
| 0057b35a0a | |||
| d12974702a | |||
| 921c41689d | |||
| 6389899507 | |||
| 92ede2a2b3 | |||
| 826a63ed71 | |||
| d1576a2a72 | |||
| 95f218d704 | |||
| 315d3a0ac0 | |||
| 954818cef2 | |||
| 5a95ca9b1b | |||
| c1e6f4c26e | |||
| 7c603258fb | |||
| fcbc582686 | |||
| 9c4906b90b | |||
| d35e31e02d | |||
| 6c4ca36c09 | |||
| 70355dc505 | |||
| 20aeaf2a05 | |||
| 1f13e1d08b | |||
| eb9d35c123 | |||
| 45808cd530 | |||
| fd715a3f92 | |||
| e3b32367a7 | |||
| bf9554a746 | |||
| b9f8ca1488 | |||
| e8c4159678 | |||
| e57e71629e | |||
| 2bfd9d24a4 | |||
| b18b8fe22f | |||
| b154ff2f9d | |||
| e9b764b63c | |||
| 7216b97d92 | |||
| 0e9d93b194 | |||
| 2cbee62f0a | |||
| 379e9da5fe | |||
| ae7caa4901 | |||
| cd8b4c9dd7 | |||
| 60cd61dfd2 | |||
| 5a6637d9fc | |||
| dca7ed23f5 | |||
| 8cb5791f3b | |||
| 9b67f2c58f | |||
| 3815810d4f | |||
| 819ceba17d | |||
| 0aa0d62e03 | |||
| b3e2a35880 | |||
| 15ec20c65d | |||
| d4d6d7e12f | |||
| 2e7a4f1421 | |||
| ab8a52faf3 | |||
| bd465559fb | |||
| 13ec45a95c | |||
| 13b034875b | |||
| bb701fb088 | |||
| b367414865 | |||
| 4b00eec608 | |||
| 5e11b51152 | |||
| 9fb43b996e | |||
| bc2072e81f | |||
| f36bc3f643 | |||
| f7901ad843 | |||
| 3771030ed6 | |||
| 57197e58b5 | |||
| ac601399ac | |||
| 6a0e221153 | |||
| 6a949fc851 | |||
| f1a077dc2f | |||
| f20962b02b | |||
| 77e057f244 | |||
| 2c5114c770 | |||
| a30895a199 | |||
| 6d46d4b3da | |||
| 006efbbb77 | |||
| 52334087ad | |||
| ea8fb2c70a | |||
| 531d148718 | |||
| d83ddea323 | |||
| b5dea34090 | |||
| 7d8e3202b5 | |||
| d956e0af4b | |||
| 9ad70990b5 | |||
| 82d711f077 | |||
| 5fc28ef711 | |||
| 1f3dc682e2 | |||
| cce7768246 | |||
| 01172b0664 | |||
| 1ca11fdd34 | |||
| 52a064ae45 | |||
| 6c62ddf927 | |||
| 47e04c08d0 | |||
| d1601874b4 | |||
| 6bc19af041 | |||
| 4e72a3886f | |||
| 8e6b219eea | |||
| bd638251e4 | |||
| 0173d5e4b3 | |||
| 4f364e134b | |||
| 94d2519717 | |||
| 6a11d2e357 | |||
| 0a9e0bc9e4 | |||
| 5914e367d1 | |||
| aeaed888d4 | |||
| a0f054b005 | |||
| 4498e9d444 | |||
| 43e0763fef | |||
| a519c8a482 | |||
| 19bc595a2a | |||
| db07825c58 | |||
| b199e3bf0e | |||
| 1f9ea0891e | |||
| 0a7aa48f1e | |||
| 4b65b7da6c | |||
| 183a7dac4b | |||
| 6726f008c1 | |||
| 89cf0c140f | |||
| 504025ce80 | |||
| fee9e914f1 | |||
| 76efa71c68 | |||
| 26e61959ae | |||
| 9a8956ef9d | |||
| 10d3ffc2f6 | |||
| 090399f61d | |||
| ae7d975a92 | |||
| 55ec6bcafe | |||
| f0566d15af | |||
| a730b692bc | |||
| 826d767423 | |||
| 6d227c7fcd | |||
| 7d9d97840e | |||
| 110ded45a0 | |||
| 7872b593c7 | |||
| 90be30bddb | |||
| a298c61dab | |||
| eb416c45bd | |||
| b05b817aeb | |||
| 666602283a | |||
| ac040a4bae | |||
| b4982c8f22 | |||
| ce3ad92095 | |||
| 8e1ac8698c | |||
| b60a39c7cb | |||
| 3b3e8ba4c8 | |||
| e387f6d3be | |||
| 799d469cb6 | |||
| a54a596fa7 | |||
| 92d73d0285 | |||
| acb752e4e8 | |||
| 9e377abba6 | |||
| 04552c0923 | |||
| 2e1fb85b73 | |||
| 50db32d9b4 | |||
| 28743d953e | |||
| b109d26aa7 | |||
| 7fd21bd06d | |||
| 12e0ffb466 | |||
| 9259341df8 | |||
| 8e8aca7e7b | |||
| 7f0bcd987b | |||
| ef21de95cb | |||
| ca3246de02 | |||
| f0940b7926 | |||
| 0066e0b901 | |||
| 9771f566b0 | |||
| 38ad4c6dec | |||
| 37cf80a188 | |||
| c86ee53f66 | |||
| c2cea7e797 | |||
| a8ef6cdd4f | |||
| 53d157fee8 | |||
| c2e07b13f6 | |||
| 2e8cc48311 | |||
| f6f811eb77 | |||
| ac5528fb15 | |||
| 940d2b7862 | |||
| 835fe3dad3 | |||
| dfaecc08c5 | |||
| 87f5e9b847 | |||
| 3d3939e808 | |||
| 90822e3858 | |||
| 14eec47e9c | |||
| 15ed3fcc69 | |||
| fd8fa9f3ef | |||
| b81075f4a7 | |||
| f11a52e8e1 | |||
| 9c007483d4 | |||
| ff4e818e4c | |||
| 45a50ca0c1 | |||
| 65d9021c37 | |||
| 66481a0391 | |||
| a14a82bc9a | |||
| 756c57a16e | |||
| 8b19e34dc5 | |||
| 50083019ee | |||
| 155272e638 | |||
| 08443ceb3d | |||
| c215696f04 | |||
| 5ca42bf9b6 | |||
| 3272b9dec5 | |||
| 2ebd5da4aa | |||
| 34f024ace2 | |||
| b31f2d50f6 | |||
| da44d3b2b4 | |||
| 99ec2aca6a | |||
| 6c278604ec | |||
| 1e094a467a | |||
| 978ccfeeba | |||
| e93d66d8a1 | |||
| c29a749833 | |||
| b08d5d1261 | |||
| 9b129789e9 | |||
| a76a6d2798 | |||
| 086a760378 | |||
| f78c8d4fd8 | |||
| 7b91489997 | |||
| 36a8980c95 | |||
| 7c65640cb7 | |||
| d70e68495a | |||
| 2586202772 | |||
| b5f771368a | |||
| 0c28320ce3 | |||
| c8b4fbc36b | |||
| e9b07849fe | |||
| 409260af6f | |||
| d3d53d1a4e | |||
| e2db191f70 | |||
| d61816734d | |||
| f4dad8058f | |||
| 70bdb375c3 | |||
| e724ab0a29 | |||
| 7d0ee2ac11 | |||
| 59b7e852e2 | |||
| b2eb1a391d | |||
| 9b3aee98d3 | |||
| 0476f4144c | |||
| ed77f45fae | |||
| 0cd529e746 | |||
| 5969048318 | |||
| d1a7f8baa0 | |||
| 18dc936002 | |||
| b4b7b5d572 | |||
| 291c2e692d | |||
| 8a9a4f21b1 | |||
| cd31332b39 | |||
| cc8d2162a0 | |||
| e6313cdc67 | |||
| 5af64892e7 | |||
| a5578a7ac7 | |||
| fcdda6406e | |||
| 9bdd9f8aa6 | |||
| f3856f051b | |||
| d3a6662c60 | |||
| 5474eddf84 | |||
| b666cd47d4 | |||
| 8a986383fe | |||
| 9fa17f617e | |||
| e46e165704 | |||
| a6af423fb4 | |||
| 3397e694c0 | |||
| 77ff82505e | |||
| c3f2838270 | |||
| aed7f205b6 | |||
| 95b3587f7a | |||
| a4baeb995a | |||
| 032ab54206 | |||
| 1f9c1eb1c0 | |||
| a213e568ba | |||
| 7aeaeb4b86 | |||
| 81aef4b8fa | |||
| 31f0b6a16c | |||
| 44e3a682fd | |||
| 70402a6d3a | |||
| 5c4143224a | |||
| f943e924f7 | |||
| 7d2f542f8a | |||
| fb1f88e971 | |||
| f566f13423 | |||
| 0f88baf1c1 | |||
| a04cbcd814 | |||
| a17d6a2ea4 | |||
| 08f49e0ac4 | |||
| 7787dd1ecc | |||
| 3d0765d4ab | |||
| b51651ace4 | |||
| 568fa56d59 | |||
| 50dee9251c | |||
| e575aaf4fb | |||
| bdd5caae1a | |||
| 3af7de3460 | |||
| caa219f8d6 | |||
| afabaccf1d | |||
| 53cc73701c | |||
| c69b954ffd | |||
| d05c447fe4 | |||
| 5810a24cb0 | |||
| e04c6a9f4d | |||
| e3a9f7af42 | |||
| 5eb58a73ee | |||
| 68ad1f72ce | |||
| 704a52d943 | |||
| 67ec9ccc4e | |||
| c7112ec67f | |||
| 1e1e2034eb | |||
| 5f316c6f44 | |||
| 0c39718f82 | |||
| 8a5ac4a0af | |||
| 492d5f5e84 | |||
| 5a3621fe39 | |||
| fb862e23e5 | |||
| 3d69348301 | |||
| 30787846a2 | |||
| 345ca27f85 | |||
| b7a6d6cae8 | |||
| dadb686514 | |||
| 75f635a28b | |||
| f2bd5b8149 | |||
| 6ed4c79ca4 | |||
| 333f954919 | |||
| 2494d0821d | |||
| e349d0cef3 | |||
| eddad2ba89 | |||
| bfaf88afd6 | |||
| cd59aed8c7 | |||
| f18ca5811f | |||
| 1ed9bcf7c8 | |||
| 29a79ab079 | |||
| 7c03c73419 | |||
| 74f3b9b609 | |||
| a3953d530e | |||
| 2280e8c725 | |||
| b327df732c | |||
| 21d7cf5d6a | |||
| 5b64bdc5b7 | |||
| a3a25b6263 | |||
| c7611c8024 | |||
| f08170504c | |||
| 863dccb5ea | |||
| fc8bb10ca3 | |||
| d06c3586fd | |||
| 395989b528 | |||
| a325440f24 | |||
| 14072bb5a0 | |||
| 7fc33ba8db | |||
| 47e51b6615 | |||
| 857562eaff | |||
| bace854b50 | |||
| e4a404472d | |||
| 7bfa215b4c | |||
| ab7af4b80b | |||
| 2c7ebd8ece | |||
| c96da79058 | |||
| 8f09ebacf5 | |||
| e21f3b9c75 | |||
| 37eeef06e2 | |||
| b7fe56687c | |||
| 60565729ca | |||
| 36f4e1c340 | |||
| abc2a5214b | |||
| a29010e0d7 | |||
| db99ab66ae | |||
| 84cc73c149 | |||
| 10a29cab33 | |||
| 849e2f103a | |||
| 6c22fe193a | |||
| e69dbbf418 | |||
| dfa59a1691 | |||
| 5023e96301 | |||
| 224c24ee9f | |||
| e3b154cf9e | |||
| d249867c4c | |||
| b56045e984 | |||
| 3777cc646e | |||
| aa5a1083d0 | |||
| 2ae5e0742e | |||
| e5e875c54a | |||
| 1a99ec76e4 | |||
| 1b122d1157 | |||
| 77f2f8cc18 | |||
| f0a99980b6 | |||
| b0d43ffe69 | |||
| 16cb0184a4 | |||
| f211a33ea3 | |||
| 440c815189 | |||
| 25829aacfd | |||
| 700a739f95 | |||
| d9620bec05 | |||
| 4b6c51b1f8 | |||
| bd02edf0b1 | |||
| 5c7123a997 | |||
| c17e3bd04f | |||
| 994ae97256 | |||
| 781428a690 | |||
| c23ac5faa8 | |||
| e8d41f83c2 | |||
| 921a0a3361 | |||
| dda5a2df93 | |||
| 155f9f107d | |||
| 24f68b8f1a | |||
| 0ffbe194fa | |||
| 0b41e2b72b | |||
| ef07b9b4ce | |||
| f3999cf2d9 | |||
| 1729847937 | |||
| 37bff6c76c | |||
| 4ef32d8037 | |||
| d2f6a33f0a | |||
| 31d9903251 | |||
| e97642d92a | |||
| c49fc0ff5f | |||
| deb2ab1ff4 | |||
| 23466cf853 | |||
| 16b34f874d | |||
| 0e0d08ae5a | |||
| 986b4c2c27 | |||
| 0bf9ccfcbd | |||
| 5e8c47928d | |||
| ffae7f911f | |||
| e37fdf6d79 | |||
| b359116745 | |||
| 60073aace3 | |||
| 874b13fa14 | |||
| b146d1024b | |||
| 332e95c021 | |||
| 1f68141df5 | |||
| dd731cd306 | |||
| 38d8d03cae | |||
| ec7d840f37 | |||
| 2813dbb897 | |||
| 77d1402b8a | |||
| 08e8a9d105 | |||
| 71661f70b6 | |||
| ac1e79ba83 | |||
| d082809776 | |||
| a458a696db | |||
| 75786a91b0 | |||
| 6ddb5db57b | |||
| 4f70cc9283 | |||
| 23b643d637 | |||
| fdfc256c4d | |||
| fba56c1b75 | |||
| 4743bfacf7 | |||
| 2356537f7c | |||
| fa071aee84 | |||
| c00ca23a8b | |||
| 733b017936 | |||
| 4147f2e368 | |||
| 154b9992eb | |||
| 88b881b043 | |||
| 5d1491fb8c | |||
| 3a33196cf1 | |||
| fa8e0478da | |||
| 7e7e069244 | |||
| 18e0d34af0 | |||
| 3fe3f35483 | |||
| cf8e274883 | |||
| 10dee8b345 | |||
| ae8d30593f | |||
| 9cde46b5da | |||
| 8e61632155 | |||
| e2c4b4cb57 | |||
| 326da504ea | |||
| c5874a3f10 | |||
| 02802fab97 | |||
| 29dea10be2 | |||
| 6bc36193dc | |||
| 81e123388e | |||
| 8ebd7869a5 | |||
| 7a2f5f13f1 | |||
| 25d7dad39f | |||
| c8f8795920 | |||
| 84206a7074 | |||
| 6fd8b36dca | |||
| d1500baae1 | |||
| 045801dd1a | |||
| 14a2cbc793 | |||
| fd385017df | |||
| 9b05954cf2 | |||
| 6aaf636069 | |||
| d30e89e5ec | |||
| 7acc745478 | |||
| 5a9a2d816e | |||
| 105f11ed02 | |||
| 3021437a05 | |||
| 439602fc03 | |||
| 34e13b9589 | |||
| 2aab4ae918 | |||
| 7ef67671a4 | |||
| e8df84416c | |||
| be930bb68b | |||
| db52948865 | |||
| d2a72526f6 | |||
| 0a9f57b32b | |||
| 180f210536 | |||
| c1baa31eed | |||
| cacc97cec7 | |||
| d5691fd81c | |||
| 49dc9fe5f6 | |||
| c0b49c7428 | |||
| fa345af42d | |||
| db3cc786a1 | |||
| fe879ae51d | |||
| 2f55460ffb | |||
| fbc5bd4642 | |||
| 5e0c7d3c9d | |||
| 083996a48d | |||
| 9d38f478e3 | |||
| 57274a0a01 | |||
| b3b56b7fc8 | |||
| 0b690577da | |||
| e9683a3a37 | |||
| f8f67b3eba | |||
| 7b16b082d8 | |||
| 2a783f0d8e | |||
| 42ae32de33 | |||
| cec7ddc486 | |||
| 9c55fc3868 | |||
| 104c5a8d83 | |||
| 7450b16742 | |||
| 3ecd0931a1 | |||
| 2f2a52ae2f | |||
| f464087c30 | |||
| 2364960388 | |||
| 76be4d64cd | |||
| 7d98e8ce47 | |||
| 40831fc681 | |||
| e38e7ccf26 | |||
| 98b9e2f2cf | |||
| 4bf3c12f76 | |||
| bab25f9ad9 | |||
| a62ee8f8c3 | |||
| 5f23691e20 | |||
| 3de9ccc62f | |||
| 1896f7f37b | |||
| 490643dc02 | |||
| 9808976088 | |||
| 5a73068a10 | |||
| 01d5c2540d | |||
| 866b01f865 | |||
| da6a953099 | |||
| bce8d58845 | |||
| 3cfce2db04 | |||
| 327aae5dd9 | |||
| 1bdfde7032 | |||
| 295a0817b0 | |||
| a02dc02d52 | |||
| dc012edf7d | |||
| 1e2eb11c13 | |||
| 3a825f4f25 | |||
| b9ea8c5f74 | |||
| 320d7e2536 | |||
| c200785479 | |||
| 8abb132ad6 | |||
| 8bb2269f36 | |||
| 9d17b26283 | |||
| 5909f15db7 | |||
| 11672ca576 | |||
| e09773def3 | |||
| f6d4432e6f | |||
| 45a6abc5c2 | |||
| dc5e677a38 | |||
| a82549dc17 | |||
| a002e19d9d | |||
| cdf1f98d28 | |||
| 0ff1ebdeb7 | |||
| 17f4a396f8 | |||
| 8aa3cf4368 | |||
| 0136c5e493 | |||
| 8b94b9ee80 | |||
| bed63f19f2 | |||
| e2a6545a84 | |||
| e3d3ec6895 | |||
| 7ba476bd79 | |||
| 2dd41ebd27 | |||
| 038df78171 | |||
| 6e5ff2b508 | |||
| ec8d1e8680 | |||
| 1f0f0c33b7 | |||
| 825940fcac | |||
| 4618834af2 | |||
| 55d968df5e |
+3
-2
@@ -9,7 +9,7 @@
|
|||||||
# Gradle wrapper
|
# Gradle wrapper
|
||||||
*.jar binary
|
*.jar binary
|
||||||
|
|
||||||
# Images
|
# Binary files types
|
||||||
*.webp binary
|
*.webp binary
|
||||||
*.png binary
|
*.png binary
|
||||||
*.jpg binary
|
*.jpg binary
|
||||||
@@ -24,4 +24,5 @@
|
|||||||
*.woff binary
|
*.woff binary
|
||||||
*.pyc binary
|
*.pyc binary
|
||||||
*.swp binary
|
*.swp binary
|
||||||
*.pdf binary
|
*.pdf binary
|
||||||
|
*.exe binary
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
cp master/server/build/Tachidesk-*.jar preview
|
|
||||||
cd preview
|
|
||||||
|
|
||||||
new_jar_build=$(ls *.jar| tail -1)
|
|
||||||
echo "last jar build file name: $new_jar_build"
|
|
||||||
|
|
||||||
cp -f $new_jar_build Tachidesk-latest.jar
|
|
||||||
|
|
||||||
rm -rf latest_pointer/*
|
|
||||||
cp $new_jar_build latest_pointer
|
|
||||||
|
|
||||||
latest=$(ls *.jar | tail -n1 | cut -d"-" -f3 | cut -d"." -f1)
|
|
||||||
echo "{ \"latest\": \"$latest\" }" > index.json
|
|
||||||
|
|
||||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
||||||
git config --global user.name "github-actions[bot]"
|
|
||||||
git status
|
|
||||||
if [ -n "$(git status --porcelain)" ]; then
|
|
||||||
git add .
|
|
||||||
git commit -m "Update preview repository"
|
|
||||||
git push
|
|
||||||
else
|
|
||||||
echo "No changes to commit"
|
|
||||||
fi
|
|
||||||
@@ -10,24 +10,24 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clone repo
|
- name: Clone repo
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Validate Gradle Wrapper
|
- name: Validate Gradle Wrapper
|
||||||
uses: gradle/wrapper-validation-action@v1
|
uses: gradle/wrapper-validation-action@v1
|
||||||
|
|
||||||
build:
|
build:
|
||||||
name: Build FatJar
|
name: Build pull request
|
||||||
needs: check_wrapper
|
needs: check_wrapper
|
||||||
if: "!startsWith(github.event.head_commit.message, '[SKIP CI]')"
|
if: "!startsWith(github.event.head_commit.message, '[SKIP CI]')"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Cancel previous runs
|
- name: Cancel previous runs
|
||||||
uses: styfle/cancel-workflow-action@0.5.0
|
uses: styfle/cancel-workflow-action@0.10.0
|
||||||
with:
|
with:
|
||||||
access_token: ${{ github.token }}
|
access_token: ${{ github.token }}
|
||||||
|
|
||||||
- name: Checkout master branch
|
- name: Checkout pull request
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
@@ -45,24 +45,9 @@ jobs:
|
|||||||
mkdir -p ~/.gradle
|
mkdir -p ~/.gradle
|
||||||
cp .github/runner-files/ci-gradle.properties ~/.gradle/gradle.properties
|
cp .github/runner-files/ci-gradle.properties ~/.gradle/gradle.properties
|
||||||
|
|
||||||
- name: Download android.jar
|
- name: Build Jar
|
||||||
run: |
|
uses: gradle/gradle-build-action@v2
|
||||||
cd master
|
|
||||||
curl https://raw.githubusercontent.com/AriaMoradi/Tachidesk/android-jar/android.jar -o AndroidCompat/lib/android.jar
|
|
||||||
|
|
||||||
- name: Cache node_modules
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
**/react/node_modules
|
|
||||||
key: ${{ runner.os }}-${{ hashFiles('**/react/yarn.lock') }}
|
|
||||||
|
|
||||||
- name: Build and copy webUI, Build Jar and launch4j
|
|
||||||
uses: eskatos/gradle-command-action@v1
|
|
||||||
with:
|
with:
|
||||||
build-root-directory: master
|
build-root-directory: master
|
||||||
wrapper-directory: master
|
arguments: :server:shadowJar --stacktrace
|
||||||
arguments: :webUI:copyBuild :server:windowsPackage --stacktrace
|
|
||||||
wrapper-cache-enabled: true
|
|
||||||
dependencies-cache-enabled: true
|
|
||||||
configuration-cache-enabled: true
|
|
||||||
|
|||||||
@@ -9,28 +9,26 @@ jobs:
|
|||||||
check_wrapper:
|
check_wrapper:
|
||||||
name: Validate Gradle Wrapper
|
name: Validate Gradle Wrapper
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clone repo
|
- name: Clone repo
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Validate Gradle Wrapper
|
- name: Validate Gradle Wrapper
|
||||||
uses: gradle/wrapper-validation-action@v1
|
uses: gradle/wrapper-validation-action@v1
|
||||||
|
|
||||||
build:
|
build:
|
||||||
name: Build FatJar
|
name: Build Jar
|
||||||
needs: check_wrapper
|
needs: check_wrapper
|
||||||
if: "!startsWith(github.event.head_commit.message, '[SKIP CI]')"
|
if: "!startsWith(github.event.head_commit.message, '[SKIP CI]')"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Cancel previous runs
|
- name: Cancel previous runs
|
||||||
uses: styfle/cancel-workflow-action@0.5.0
|
uses: styfle/cancel-workflow-action@0.10.0
|
||||||
with:
|
with:
|
||||||
access_token: ${{ github.token }}
|
access_token: ${{ github.token }}
|
||||||
|
|
||||||
- name: Checkout master branch
|
- name: Checkout master branch
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
ref: master
|
ref: master
|
||||||
path: master
|
path: master
|
||||||
@@ -47,34 +45,158 @@ jobs:
|
|||||||
mkdir -p ~/.gradle
|
mkdir -p ~/.gradle
|
||||||
cp .github/runner-files/ci-gradle.properties ~/.gradle/gradle.properties
|
cp .github/runner-files/ci-gradle.properties ~/.gradle/gradle.properties
|
||||||
|
|
||||||
- name: Download android.jar
|
- name: Build Jar
|
||||||
run: |
|
uses: gradle/gradle-build-action@v2
|
||||||
cd master
|
env:
|
||||||
curl https://raw.githubusercontent.com/AriaMoradi/Tachidesk/android-jar/android.jar -o AndroidCompat/lib/android.jar
|
ProductBuildType: "Preview"
|
||||||
|
|
||||||
- name: Cache node_modules
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
**/react/node_modules
|
|
||||||
key: ${{ runner.os }}-${{ hashFiles('**/react/yarn.lock') }}
|
|
||||||
|
|
||||||
- name: Build and copy webUI, Build Jar and launch4j
|
|
||||||
uses: eskatos/gradle-command-action@v1
|
|
||||||
with:
|
with:
|
||||||
build-root-directory: master
|
build-root-directory: master
|
||||||
wrapper-directory: master
|
arguments: :server:shadowJar --stacktrace
|
||||||
arguments: :webUI:copyBuild :server:windowsPackage --stacktrace
|
|
||||||
wrapper-cache-enabled: true
|
|
||||||
dependencies-cache-enabled: true
|
|
||||||
configuration-cache-enabled: true
|
|
||||||
|
|
||||||
- name: Checkout preview branch
|
- name: Upload Jar
|
||||||
uses: actions/checkout@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
ref: preview
|
name: jar
|
||||||
path: preview
|
path: master/server/build/*.jar
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Deploy preview
|
- name: Upload icons
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: icon
|
||||||
|
path: master/server/src/main/resources/icon
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
- name: Tar scripts dir to maintain file permissions
|
||||||
|
run: tar -cvzf scripts.tar.gz -C master/ scripts/
|
||||||
|
- name: Upload scripts.tar.gz
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: scripts
|
||||||
|
path: scripts.tar.gz
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
bundle:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os:
|
||||||
|
- debian-all
|
||||||
|
- linux-assets
|
||||||
|
- linux-x64
|
||||||
|
- macOS-x64
|
||||||
|
- macOS-arm64
|
||||||
|
- windows-x64
|
||||||
|
- windows-x86
|
||||||
|
|
||||||
|
name: Make ${{ matrix.os }} release
|
||||||
|
needs: build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Download Jar
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: jar
|
||||||
|
path: server/build
|
||||||
|
|
||||||
|
- name: Download icons
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: icon
|
||||||
|
path: server/src/main/resources/icon
|
||||||
|
|
||||||
|
- name: Download scripts.tar.gz
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: scripts
|
||||||
|
|
||||||
|
- name: Make ${{ matrix.os }} release
|
||||||
run: |
|
run: |
|
||||||
./master/.github/scripts/commit-repo.sh
|
mkdir upload
|
||||||
|
tar -xvpf scripts.tar.gz
|
||||||
|
scripts/bundler.sh -o upload/ ${{ matrix.os }}
|
||||||
|
|
||||||
|
- name: Upload ${{ matrix.os }} release
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.os }}
|
||||||
|
path: upload/*
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
release:
|
||||||
|
needs: bundle
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: jar
|
||||||
|
path: release
|
||||||
|
- uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: debian-all
|
||||||
|
path: release
|
||||||
|
- uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: linux-assets
|
||||||
|
path: release
|
||||||
|
- uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: linux-x64
|
||||||
|
path: release
|
||||||
|
- uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: macOS-x64
|
||||||
|
path: release
|
||||||
|
- uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: macOS-arm64
|
||||||
|
path: release
|
||||||
|
- uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: windows-x64
|
||||||
|
path: release
|
||||||
|
- uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: windows-x86
|
||||||
|
path: release
|
||||||
|
|
||||||
|
- name: Checkout Preview branch
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
repository: "Suwayomi/Tachidesk-Server-preview"
|
||||||
|
ref: main
|
||||||
|
path: preview
|
||||||
|
token: ${{ secrets.DEPLOY_PREVIEW_TOKEN }}
|
||||||
|
|
||||||
|
- name: Generate Tag Name
|
||||||
|
id: GenTagName
|
||||||
|
run: |
|
||||||
|
cd release
|
||||||
|
genTag=$(ls *.jar | sed -e's/Tachidesk-Server-\|.jar//g')
|
||||||
|
echo "$genTag"
|
||||||
|
echo "::set-output name=value::$genTag"
|
||||||
|
|
||||||
|
- name: Create Tag
|
||||||
|
run: |
|
||||||
|
TAG="${{ steps.GenTagName.outputs.value }}"
|
||||||
|
echo "tag: $TAG"
|
||||||
|
cd preview
|
||||||
|
echo "{ \"latest\": \"$TAG\" }" > index.json
|
||||||
|
git add index.json
|
||||||
|
git config --global user.email \
|
||||||
|
"github-actions[bot]@users.noreply.github.com"
|
||||||
|
git config --global user.name "github-actions[bot]"
|
||||||
|
git commit -m "Updated to $TAG"
|
||||||
|
git push origin main
|
||||||
|
|
||||||
|
git tag $TAG
|
||||||
|
git push origin $TAG
|
||||||
|
|
||||||
|
- name: Upload Preview Release
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.DEPLOY_PREVIEW_TOKEN }}
|
||||||
|
repository: "Suwayomi/Tachidesk-Server-preview"
|
||||||
|
tag_name: ${{ steps.GenTagName.outputs.value }}
|
||||||
|
files: release/*
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
name: Docker Build Stable
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build_publish_docker_container:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: run docker build and publish script
|
||||||
|
run: |
|
||||||
|
curl -X POST -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.DEPLOY_PREVIEW_TOKEN }}" -d '{"ref":"main", "inputs":{"tachidesk_release_type": "stable"}}' https://api.github.com/repos/suwayomi/docker-tachidesk/actions/workflows/build_container_images.yml/dispatches
|
||||||
|
|
||||||
@@ -1,24 +1,35 @@
|
|||||||
name: Issue closer
|
name: Issue moderator
|
||||||
|
|
||||||
on:
|
on:
|
||||||
issues:
|
issues:
|
||||||
types: [opened, edited, reopened]
|
types: [opened, edited, reopened]
|
||||||
|
issue_comment:
|
||||||
|
types: [created]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
autoclose:
|
autoclose:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Autoclose issues
|
- name: Moderate issues
|
||||||
uses: arkon/issue-closer-action@v3.0
|
uses: tachiyomiorg/issue-moderator-action@v1
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ github.token }}
|
repo-token: ${{ github.token }}
|
||||||
rules: |
|
duplicate-check-enabled: true
|
||||||
|
duplicate-check-label: Source request
|
||||||
|
existing-check-enabled: true
|
||||||
|
existing-check-label: Source request
|
||||||
|
auto-close-rules: |
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"type": "title",
|
"type": "title",
|
||||||
"regex": ".*<short description>*",
|
"regex": ".*<short description>.*",
|
||||||
"message": "You did not fill out the description in the title"
|
"message": "You did not fill out the description in the title"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "title",
|
||||||
|
"regex": ".*(<|>)+.*",
|
||||||
|
"message": "You did not remove Angle brackets(< and >) from the title"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "body",
|
"type": "body",
|
||||||
"regex": ".*DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT.*",
|
"regex": ".*DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT.*",
|
||||||
@@ -26,7 +37,7 @@ jobs:
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "body",
|
"type": "body",
|
||||||
"regex": "(Tachidesk version|Server Operating System|Server Desktop Environment|Server JVM version|Client Operating System|Client Web Browser):.*(\\(Example:|<usually).*",
|
"regex": ".*(Tachidesk version|Server Operating System|Server Desktop Environment|Server JVM version|Client Operating System|Client Web Browser):.*(\\(Example:|<usually).*",
|
||||||
"message": "The requested information was not filled out"
|
"message": "The requested information was not filled out"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
+130
-66
@@ -1,37 +1,36 @@
|
|||||||
name: CI Publish
|
name: CI Publish
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
- 'v*'
|
- "v*"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check_wrapper:
|
check_wrapper:
|
||||||
name: Validate Gradle Wrapper
|
name: Validate Gradle Wrapper
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clone repo
|
- name: Clone repo
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Validate Gradle Wrapper
|
- name: Validate Gradle Wrapper
|
||||||
uses: gradle/wrapper-validation-action@v1
|
uses: gradle/wrapper-validation-action@v1
|
||||||
|
|
||||||
build:
|
build:
|
||||||
name: Build FatJar
|
name: Build Jar
|
||||||
needs: check_wrapper
|
needs: check_wrapper
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Cancel previous runs
|
- name: Cancel previous runs
|
||||||
uses: styfle/cancel-workflow-action@0.5.0
|
uses: styfle/cancel-workflow-action@0.10.0
|
||||||
with:
|
with:
|
||||||
access_token: ${{ github.token }}
|
access_token: ${{ github.token }}
|
||||||
|
|
||||||
- name: Checkout master branch
|
- name: Checkout ${{ github.ref }}
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
ref: master
|
ref: ${{ github.ref }}
|
||||||
path: master
|
path: master
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
@@ -44,66 +43,131 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
cd master
|
cd master
|
||||||
mkdir -p ~/.gradle
|
mkdir -p ~/.gradle
|
||||||
cp .github/runner-files/ci-gradle.properties ~/.gradle/gradle.properties
|
cp .github/runner-files/ci-gradle.properties \
|
||||||
|
~/.gradle/gradle.properties
|
||||||
|
|
||||||
- name: Download android.jar
|
- name: Build and copy webUI, Build Jar
|
||||||
run: |
|
uses: gradle/gradle-build-action@v2
|
||||||
cd master
|
env:
|
||||||
curl https://raw.githubusercontent.com/AriaMoradi/Tachidesk/android-jar/android.jar -o AndroidCompat/lib/android.jar
|
ProductBuildType: "Stable"
|
||||||
|
|
||||||
- name: Cache node_modules
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
**/react/node_modules
|
|
||||||
key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}
|
|
||||||
|
|
||||||
- name: Build and copy webUI, Build Jar and launch4j
|
|
||||||
uses: eskatos/gradle-command-action@v1
|
|
||||||
with:
|
with:
|
||||||
build-root-directory: master
|
build-root-directory: master
|
||||||
wrapper-directory: master
|
arguments: :server:downloadWebUI :server:shadowJar --stacktrace
|
||||||
arguments: :webUI:copyBuild :server:windowsPackage --stacktrace
|
|
||||||
wrapper-cache-enabled: true
|
|
||||||
dependencies-cache-enabled: true
|
|
||||||
configuration-cache-enabled: true
|
|
||||||
|
|
||||||
- name: Upload Release
|
- name: Upload Jar
|
||||||
uses: xresloader/upload-to-github-release@master
|
uses: actions/upload-artifact@v3
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
with:
|
||||||
file: "master/server/build/*.jar;master/server/build/*-win32.zip"
|
name: jar
|
||||||
tags: true
|
path: master/server/build/*.jar
|
||||||
draft: true
|
if-no-files-found: error
|
||||||
verbose: true
|
|
||||||
|
|
||||||
# - name: Create Release
|
- name: Upload icons
|
||||||
# id: create_release
|
uses: actions/upload-artifact@v3
|
||||||
# uses: actions/create-release@v1
|
with:
|
||||||
# env:
|
name: icon
|
||||||
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
path: master/server/src/main/resources/icon
|
||||||
# with:
|
if-no-files-found: error
|
||||||
# tag_name: ${{ github.ref }}
|
|
||||||
# release_name: Release ${{ github.ref }}
|
- name: Tar scripts dir to maintain file permissions
|
||||||
# body: |
|
run: tar -cvzf scripts.tar.gz -C master/ scripts/
|
||||||
# Release body
|
- name: Upload scripts.tar.gz
|
||||||
# draft: false
|
uses: actions/upload-artifact@v3
|
||||||
# prerelease: true
|
with:
|
||||||
#
|
name: scripts
|
||||||
# - name: Get the Ref
|
path: scripts.tar.gz
|
||||||
# id: get-ref
|
if-no-files-found: error
|
||||||
# uses: ankitvgupta/ref-to-tag-action@master
|
|
||||||
# with:
|
bundle:
|
||||||
# ref: ${{ github.ref }}
|
strategy:
|
||||||
# head_ref: ${{ github.head_ref }}
|
fail-fast: false
|
||||||
#
|
matrix:
|
||||||
# - name: Get the tag
|
os:
|
||||||
# run: echo "The tag was ${{ steps.get-ref.outputs.tag }}"
|
- debian-all
|
||||||
#
|
- linux-assets
|
||||||
# - name: Upload Release
|
- linux-x64
|
||||||
# uses: AButler/upload-release-assets@v2.0
|
- macOS-x64
|
||||||
# with:
|
- macOS-arm64
|
||||||
# files: 'master/repo/*'
|
- windows-x64
|
||||||
# repo-token: ${{ secrets.GITHUB_TOKEN }}
|
- windows-x86
|
||||||
# release-tag: ${{ steps.get-ref.outputs.tag }}
|
|
||||||
|
name: Make ${{ matrix.os }} release
|
||||||
|
needs: build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Download Jar
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: jar
|
||||||
|
path: server/build
|
||||||
|
|
||||||
|
- name: Download icons
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: icon
|
||||||
|
path: server/src/main/resources/icon
|
||||||
|
|
||||||
|
- name: Download scripts.tar.gz
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: scripts
|
||||||
|
|
||||||
|
- name: Make ${{ matrix.os }} release
|
||||||
|
run: |
|
||||||
|
mkdir upload/
|
||||||
|
tar -xvpf scripts.tar.gz
|
||||||
|
scripts/bundler.sh -o upload/ ${{ matrix.os }}
|
||||||
|
|
||||||
|
- name: Upload ${{ matrix.os }} files
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.os }}
|
||||||
|
path: upload/*
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
release:
|
||||||
|
if: startsWith(github.ref, 'refs/tags/v')
|
||||||
|
needs: bundle
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: jar
|
||||||
|
path: release
|
||||||
|
- uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: debian-all
|
||||||
|
path: release
|
||||||
|
- uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: linux-assets
|
||||||
|
path: release
|
||||||
|
- uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: linux-x64
|
||||||
|
path: release
|
||||||
|
- uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: macOS-x64
|
||||||
|
path: release
|
||||||
|
- uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: macOS-arm64
|
||||||
|
path: release
|
||||||
|
- uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: windows-x64
|
||||||
|
path: release
|
||||||
|
- uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: windows-x86
|
||||||
|
path: release
|
||||||
|
|
||||||
|
- name: Generate checksums
|
||||||
|
run: cd release && sha256sum * > Checksums.sha256
|
||||||
|
|
||||||
|
- name: Release
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.WINGET_PUBLISH_PAT }}
|
||||||
|
draft: true
|
||||||
|
files: release/*
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
name: Publish to WinGet
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [released]
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
runs-on: windows-latest # action can only be run on windows
|
||||||
|
steps:
|
||||||
|
- uses: vedantmgoyal2009/winget-releaser@v1
|
||||||
|
with:
|
||||||
|
identifier: Suwayomi.Tachidesk-Server
|
||||||
|
installers-regex: '.*x64.msi$'
|
||||||
|
token: ${{ secrets.WINGET_PUBLISH_PAT }}
|
||||||
+14
-4
@@ -1,11 +1,21 @@
|
|||||||
# Ignore Gradle project-specific cache directory
|
# Ignore project-specific local files and dirs
|
||||||
.gradle
|
.gradle
|
||||||
.idea
|
.idea
|
||||||
gradle.properties
|
gradle.properties
|
||||||
|
.fleet
|
||||||
|
# But we need these
|
||||||
|
!.idea/runConfigurations
|
||||||
|
|
||||||
# Ignore Gradle build output directory
|
# Ignore Gradle build output directory
|
||||||
build
|
build
|
||||||
|
server/out
|
||||||
|
AndroidCompat/out
|
||||||
|
|
||||||
server/src/main/resources/react
|
# WebUI is either to be downloaded on-demand or is a dynamic build asset
|
||||||
server/tmp/
|
server/src/main/resources/WebUI.zip
|
||||||
server/tachiserver-data/
|
|
||||||
|
# bundling stage downlaoded assets
|
||||||
|
scripts/OpenJDK*
|
||||||
|
scripts/zulu*
|
||||||
|
scripts/electron-*
|
||||||
|
scripts/rcedit-*
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
|
@Suppress("DSL_SCOPE_VIOLATION")
|
||||||
|
plugins {
|
||||||
|
id(libs.plugins.kotlin.jvm.get().pluginId)
|
||||||
|
id(libs.plugins.kotlin.serialization.get().pluginId)
|
||||||
|
id(libs.plugins.kotlinter.get().pluginId)
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// Config API, moved to the global build.gradle
|
// Shared
|
||||||
// implementation("com.typesafe:config:1.4.0")
|
implementation(libs.bundles.shared)
|
||||||
|
testImplementation(libs.bundles.sharedTest)
|
||||||
}
|
}
|
||||||
@@ -1,18 +1,20 @@
|
|||||||
package xyz.nulldev.ts.config
|
package xyz.nulldev.ts.config
|
||||||
|
|
||||||
import net.harawata.appdirs.AppDirsFactory
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import net.harawata.appdirs.AppDirsFactory
|
||||||
|
|
||||||
|
const val CONFIG_PREFIX = "suwayomi.tachidesk.config"
|
||||||
|
|
||||||
val ApplicationRootDir: String
|
val ApplicationRootDir: String
|
||||||
get(): String {
|
get(): String {
|
||||||
return System.getProperty(
|
return System.getProperty(
|
||||||
"ir.armor.tachidesk.rootDir",
|
"$CONFIG_PREFIX.server.rootDir",
|
||||||
AppDirsFactory.getInstance().getUserDataDir("Tachidesk", null, null)
|
AppDirsFactory.getInstance().getUserDataDir("Tachidesk", null, null)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import org.kodein.di.singleton
|
|||||||
|
|
||||||
class ConfigKodeinModule {
|
class ConfigKodeinModule {
|
||||||
fun create() = DI.Module("ConfigManager") {
|
fun create() = DI.Module("ConfigManager") {
|
||||||
//Config module
|
// Config module
|
||||||
bind<ConfigManager>() with singleton { GlobalConfigManager }
|
bind<ConfigManager>() with singleton { GlobalConfigManager }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ package xyz.nulldev.ts.config
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import ch.qos.logback.classic.Level
|
||||||
import com.typesafe.config.Config
|
import com.typesafe.config.Config
|
||||||
import com.typesafe.config.ConfigFactory
|
import com.typesafe.config.ConfigFactory
|
||||||
import com.typesafe.config.ConfigRenderOptions
|
import com.typesafe.config.ConfigRenderOptions
|
||||||
@@ -20,7 +21,7 @@ open class ConfigManager {
|
|||||||
private val generatedModules = mutableMapOf<Class<out ConfigModule>, ConfigModule>()
|
private val generatedModules = mutableMapOf<Class<out ConfigModule>, ConfigModule>()
|
||||||
val config by lazy { loadConfigs() }
|
val config by lazy { loadConfigs() }
|
||||||
|
|
||||||
//Public read-only view of modules
|
// Public read-only view of modules
|
||||||
val loadedModules: Map<Class<out ConfigModule>, ConfigModule>
|
val loadedModules: Map<Class<out ConfigModule>, ConfigModule>
|
||||||
get() = generatedModules
|
get() = generatedModules
|
||||||
|
|
||||||
@@ -34,27 +35,40 @@ open class ConfigManager {
|
|||||||
/**
|
/**
|
||||||
* Get a config module (Java API)
|
* Get a config module (Java API)
|
||||||
*/
|
*/
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
fun <T : ConfigModule> module(type: Class<T>): T = loadedModules[type] as T
|
fun <T : ConfigModule> module(type: Class<T>): T = loadedModules[type] as T
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load configs
|
* Load configs
|
||||||
*/
|
*/
|
||||||
fun loadConfigs(): Config {
|
fun loadConfigs(): Config {
|
||||||
//Load reference configs
|
// Load reference configs
|
||||||
val compatConfig = ConfigFactory.parseResources("compat-reference.conf")
|
val compatConfig = ConfigFactory.parseResources("compat-reference.conf")
|
||||||
val serverConfig = ConfigFactory.parseResources("server-reference.conf")
|
val serverConfig = ConfigFactory.parseResources("server-reference.conf")
|
||||||
|
val baseConfig =
|
||||||
|
ConfigFactory.parseMap(
|
||||||
|
mapOf(
|
||||||
|
"androidcompat.rootDir" to "$ApplicationRootDir/android-compat" // override AndroidCompat's rootDir
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
//Load user config
|
// Load user config
|
||||||
val userConfig =
|
val userConfig =
|
||||||
File(ApplicationRootDir, "server.conf").let {
|
File(ApplicationRootDir, "server.conf").let {
|
||||||
ConfigFactory.parseFile(it)
|
ConfigFactory.parseFile(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
val config = ConfigFactory.empty()
|
val config = ConfigFactory.empty()
|
||||||
.withFallback(userConfig)
|
.withFallback(baseConfig)
|
||||||
.withFallback(compatConfig)
|
.withFallback(userConfig)
|
||||||
.withFallback(serverConfig)
|
.withFallback(compatConfig)
|
||||||
.resolve()
|
.withFallback(serverConfig)
|
||||||
|
.resolve()
|
||||||
|
|
||||||
|
// set log level early
|
||||||
|
if (debugLogsEnabled(config)) {
|
||||||
|
setLogLevel(Level.DEBUG)
|
||||||
|
}
|
||||||
|
|
||||||
logger.debug {
|
logger.debug {
|
||||||
"Loaded config:\n" + config.root().render(ConfigRenderOptions.concise().setFormatted(true))
|
"Loaded config:\n" + config.root().render(ConfigRenderOptions.concise().setFormatted(true))
|
||||||
|
|||||||
@@ -1,8 +1,44 @@
|
|||||||
package xyz.nulldev.ts.config
|
package xyz.nulldev.ts.config
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
import com.typesafe.config.Config
|
import com.typesafe.config.Config
|
||||||
|
import io.github.config4k.getValue
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract config module.
|
* Abstract config module.
|
||||||
*/
|
*/
|
||||||
|
@Suppress("UNUSED_PARAMETER")
|
||||||
abstract class ConfigModule(config: Config)
|
abstract class ConfigModule(config: Config)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract jvm-commandline-argument-overridable config module.
|
||||||
|
*/
|
||||||
|
abstract class SystemPropertyOverridableConfigModule(config: Config, moduleName: String) : ConfigModule(config) {
|
||||||
|
val overridableConfig = SystemPropertyOverrideDelegate(config, moduleName)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Defines a config property that is overridable with jvm `-D` commandline arguments prefixed with [CONFIG_PREFIX] */
|
||||||
|
class SystemPropertyOverrideDelegate(val config: Config, val moduleName: String) {
|
||||||
|
inline operator fun <R, reified T> getValue(thisRef: R, property: KProperty<*>): T {
|
||||||
|
val configValue: T = config.getValue(thisRef, property)
|
||||||
|
|
||||||
|
val combined = System.getProperty(
|
||||||
|
"$CONFIG_PREFIX.$moduleName.${property.name}",
|
||||||
|
configValue.toString()
|
||||||
|
)
|
||||||
|
|
||||||
|
return when (T::class.simpleName) {
|
||||||
|
"Int" -> combined.toInt()
|
||||||
|
"Boolean" -> combined.toBoolean()
|
||||||
|
// add more types as needed
|
||||||
|
else -> combined // covers String
|
||||||
|
} as T
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package xyz.nulldev.ts.config
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import ch.qos.logback.classic.Level
|
||||||
|
import com.typesafe.config.Config
|
||||||
|
import mu.KotlinLogging
|
||||||
|
import org.slf4j.Logger
|
||||||
|
|
||||||
|
fun setLogLevel(level: Level) {
|
||||||
|
(KotlinLogging.logger(Logger.ROOT_LOGGER_NAME).underlyingLogger as ch.qos.logback.classic.Logger).level = level
|
||||||
|
}
|
||||||
|
|
||||||
|
fun debugLogsEnabled(config: Config) =
|
||||||
|
System.getProperty("suwayomi.tachidesk.config.server.debugLogsEnabled", config.getString("server.debugLogsEnabled")).toBoolean()
|
||||||
@@ -3,4 +3,4 @@ package xyz.nulldev.ts.config.util
|
|||||||
import com.typesafe.config.Config
|
import com.typesafe.config.Config
|
||||||
|
|
||||||
operator fun Config.get(key: String) = getString(key)
|
operator fun Config.get(key: String) = getString(key)
|
||||||
?: throw IllegalStateException("Could not find value for config entry: $key!")
|
?: throw IllegalStateException("Could not find value for config entry: $key!")
|
||||||
|
|||||||
-1
@@ -1 +0,0 @@
|
|||||||
xyz.nulldev.ts.api.v2.java.impl.ServerAPIImpl
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 6.9 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.2 KiB |
File diff suppressed because one or more lines are too long
@@ -1,22 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"label": "Sync",
|
|
||||||
"icon": "import_export",
|
|
||||||
"type": "nested",
|
|
||||||
"prefs": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Server",
|
|
||||||
"icon": "dns",
|
|
||||||
"type": "nested",
|
|
||||||
"prefs": [
|
|
||||||
{
|
|
||||||
"label": "Password authentication",
|
|
||||||
"type": "text-password",
|
|
||||||
"default": "",
|
|
||||||
"key": "pref_ts_server_password",
|
|
||||||
"hint": "Enter a password"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -1,62 +1,39 @@
|
|||||||
|
@Suppress("DSL_SCOPE_VIOLATION")
|
||||||
plugins {
|
plugins {
|
||||||
application
|
id(libs.plugins.kotlin.jvm.get().pluginId)
|
||||||
}
|
id(libs.plugins.kotlin.serialization.get().pluginId)
|
||||||
|
id(libs.plugins.kotlinter.get().pluginId)
|
||||||
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
maven {
|
|
||||||
url = uri("https://jitpack.io")
|
|
||||||
}
|
|
||||||
|
|
||||||
maven {
|
|
||||||
url = uri("https://maven.google.com")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
// Shared
|
||||||
|
implementation(libs.bundles.shared)
|
||||||
|
testImplementation(libs.bundles.sharedTest)
|
||||||
|
|
||||||
// Android stub library
|
// Android stub library
|
||||||
implementation(fileTree("lib/"))
|
implementation(libs.android.stubs)
|
||||||
|
|
||||||
|
|
||||||
// Android JAR libs
|
|
||||||
// compileOnly( fileTree(dir: new File(rootProject.rootDir, "libs/other"), include: "*.jar")
|
|
||||||
|
|
||||||
// JSON
|
|
||||||
compileOnly( "com.google.code.gson:gson:2.8.6")
|
|
||||||
|
|
||||||
// Javassist
|
|
||||||
compileOnly( "org.javassist:javassist:3.27.0-GA")
|
|
||||||
|
|
||||||
// XML
|
// XML
|
||||||
compileOnly( group= "xmlpull", name= "xmlpull", version= "1.1.3.1")
|
compileOnly(libs.xmlpull)
|
||||||
|
|
||||||
// Config API
|
// Config API
|
||||||
implementation(project(":AndroidCompat:Config"))
|
implementation(projects.androidCompat.config)
|
||||||
|
|
||||||
// APK sig verifier
|
// APK sig verifier
|
||||||
compileOnly("com.android.tools.build:apksig:4.2.0-alpha13")
|
compileOnly(libs.apksig)
|
||||||
|
|
||||||
// AndroidX annotations
|
// AndroidX annotations
|
||||||
compileOnly( "androidx.annotation:annotation:1.2.0-alpha01")
|
compileOnly(libs.android.annotations)
|
||||||
|
|
||||||
// substitute for duktape-android
|
// substitute for duktape-android
|
||||||
// 'org.mozilla:rhino' includes some code that we don't need so use 'org.mozilla:rhino-runtime' instead
|
implementation(libs.bundles.rhino)
|
||||||
implementation("org.mozilla:rhino-runtime:1.7.13")
|
|
||||||
// 'org.mozilla:rhino-engine' provides the same interface as 'javax.script' a.k.a Nashorn
|
|
||||||
implementation("org.mozilla:rhino-engine:1.7.13")
|
|
||||||
}
|
|
||||||
|
|
||||||
//def fatJarTask = tasks.getByPath(':AndroidCompat:JVMPatch:fatJar')
|
// Kotlin wrapper around Java Preferences, makes certain things easier
|
||||||
//
|
implementation(libs.bundles.settings)
|
||||||
//// Copy JVM core patches
|
|
||||||
//task copyJVMPatches(type: Copy) {
|
// Android version of SimpleDateFormat
|
||||||
// from fatJarTask.outputs.files
|
implementation(libs.icu4j)
|
||||||
// into 'src/main/resources/patches'
|
|
||||||
//}
|
// OpenJDK lacks native JPEG encoder and native WEBP decoder
|
||||||
//
|
implementation(libs.bundles.twelvemonkeys)
|
||||||
//compileOnly(Java.dependsOn gradle.includedBuild('dex2jar').task(':dex-translator:assemble')
|
}
|
||||||
//compileOnly(Java.dependsOn copyJVMPatches
|
|
||||||
//copyJVMPatches.dependsOn fatJarTask
|
|
||||||
//
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ Write-Output "Getting required Android.jar..."
|
|||||||
Remove-Item -Recurse -Force "tmp" -ErrorAction SilentlyContinue | Out-Null
|
Remove-Item -Recurse -Force "tmp" -ErrorAction SilentlyContinue | Out-Null
|
||||||
New-Item -ItemType Directory -Force -Path "tmp" | Out-Null
|
New-Item -ItemType Directory -Force -Path "tmp" | Out-Null
|
||||||
|
|
||||||
$androidEncoded = (Invoke-WebRequest -Uri "https://android.googlesource.com/platform/prebuilts/sdk/+/3b8a524d25fa6c3d795afb1eece3f24870c60988/27/public/android.jar?format=TEXT" -UseBasicParsing).content
|
$androidEncoded = (Invoke-WebRequest -Uri "https://android.googlesource.com/platform/prebuilts/sdk/+/6cd31be5e4e25901aadf838120d71a79b46d9add/30/public/android.jar?format=TEXT" -UseBasicParsing).content
|
||||||
|
|
||||||
$android_jar = (Get-Location).Path + "\tmp\android.jar"
|
$android_jar = (Get-Location).Path + "\tmp\android.jar"
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ $android_jar = (Get-Location).Path + "\tmp\android.jar"
|
|||||||
# We need to remove any stub classes that we have implementations for
|
# We need to remove any stub classes that we have implementations for
|
||||||
Write-Output "Patching JAR..."
|
Write-Output "Patching JAR..."
|
||||||
|
|
||||||
function Remove-Files-Zip($zipfile, $path)
|
function Remove-Files-Zip($zipfile, $paths)
|
||||||
{
|
{
|
||||||
[Reflection.Assembly]::LoadWithPartialName('System.IO.Compression') | Out-Null
|
[Reflection.Assembly]::LoadWithPartialName('System.IO.Compression') | Out-Null
|
||||||
|
|
||||||
@@ -32,7 +32,18 @@ function Remove-Files-Zip($zipfile, $path)
|
|||||||
$mode = [IO.Compression.ZipArchiveMode]::Update
|
$mode = [IO.Compression.ZipArchiveMode]::Update
|
||||||
$zip = New-Object IO.Compression.ZipArchive($stream, $mode)
|
$zip = New-Object IO.Compression.ZipArchive($stream, $mode)
|
||||||
|
|
||||||
($zip.Entries | Where-Object { $_.FullName -like $path }) | ForEach-Object { Write-Output "Deleting: $($_.FullName)"; $_.Delete() }
|
if ($paths.getType().Name -eq "Object[]")
|
||||||
|
{
|
||||||
|
$paths | ForEach-Object {
|
||||||
|
$path = $_
|
||||||
|
($zip.Entries | Where-Object { $_.FullName -like $path }) | ForEach-Object { Write-Output "Deleting: $($_.FullName)"; $_.Delete() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
($zip.Entries | Where-Object { $_.FullName -like $paths }) | ForEach-Object { Write-Output "Deleting: $($_.FullName)"; $_.Delete() }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$zip.Dispose()
|
$zip.Dispose()
|
||||||
$stream.Close()
|
$stream.Close()
|
||||||
@@ -78,16 +89,12 @@ function Dedupe($path)
|
|||||||
$classes = Get-ChildItem . *.* -Recurse | Where-Object { !$_.PSIsContainer }
|
$classes = Get-ChildItem . *.* -Recurse | Where-Object { !$_.PSIsContainer }
|
||||||
$classes | ForEach-Object {
|
$classes | ForEach-Object {
|
||||||
"Processing class: $($_.FullName)"
|
"Processing class: $($_.FullName)"
|
||||||
Remove-Files-Zip $android_jar "$($_.Name).class" | Out-Null
|
Remove-Files-Zip $android_jar ("$($_.Name).class","$($_.Name)$*.class","$($_.Name)Kt.class","$($_.Name)Kt$*.class") | Out-Null
|
||||||
Remove-Files-Zip $android_jar "$($_.Name)$*.class" | Out-Null
|
|
||||||
Remove-Files-Zip $android_jar "$($_.Name)Kt.class" | Out-Null
|
|
||||||
Remove-Files-Zip $android_jar "$($_.Name)Kt$*.class" | Out-Null
|
|
||||||
}
|
}
|
||||||
Pop-Location
|
Pop-Location
|
||||||
}
|
}
|
||||||
|
|
||||||
Dedupe "AndroidCompat/src/main/java"
|
Dedupe "AndroidCompat/src/main/java"
|
||||||
Dedupe "server/src/main/java"
|
|
||||||
Dedupe "server/src/main/kotlin"
|
Dedupe "server/src/main/kotlin"
|
||||||
|
|
||||||
Write-Output "Copying Android.jar to library folder..."
|
Write-Output "Copying Android.jar to library folder..."
|
||||||
|
|||||||
@@ -13,14 +13,14 @@ do
|
|||||||
which $dep >/dev/null 2>&1 || { echo >&2 "Error: This script needs $dep installed."; abort=yes; }
|
which $dep >/dev/null 2>&1 || { echo >&2 "Error: This script needs $dep installed."; abort=yes; }
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ $abort = yes ]; then
|
if [ "$abort" = yes ]; then
|
||||||
echo "Some of the dependencies didn't exist. Aborting."
|
echo "Some of the dependencies didn't exist. Aborting."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# foolproof against running from AndroidCompat dir instead of running from project root
|
# foolproof against running from AndroidCompat dir instead of running from project root
|
||||||
if [ "$(basename $(pwd))" = "AndroidCompat" ]; then
|
if [ "$(basename "$(pwd)")" = "AndroidCompat" ]; then
|
||||||
cd ..
|
cd ..
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ rm -rf "tmp"
|
|||||||
mkdir -p "tmp"
|
mkdir -p "tmp"
|
||||||
pushd "tmp"
|
pushd "tmp"
|
||||||
|
|
||||||
curl "https://android.googlesource.com/platform/prebuilts/sdk/+/3b8a524d25fa6c3d795afb1eece3f24870c60988/27/public/android.jar?format=TEXT" | base64 --decode > android.jar
|
curl "https://android.googlesource.com/platform/prebuilts/sdk/+/6cd31be5e4e25901aadf838120d71a79b46d9add/30/public/android.jar?format=TEXT" | base64 --decode > android.jar
|
||||||
|
|
||||||
# We need to remove any stub classes that we have implementations for
|
# We need to remove any stub classes that we have implementations for
|
||||||
echo "Patching JAR..."
|
echo "Patching JAR..."
|
||||||
@@ -59,7 +59,7 @@ zip --delete android.jar javax/*
|
|||||||
echo "Removing java..."
|
echo "Removing java..."
|
||||||
zip --delete android.jar java/*
|
zip --delete android.jar java/*
|
||||||
|
|
||||||
echo "Removing overriden classes..."
|
echo "Removing overridden classes..."
|
||||||
zip --delete android.jar android/app/Application.class
|
zip --delete android.jar android/app/Application.class
|
||||||
zip --delete android.jar android/app/Service.class
|
zip --delete android.jar android/app/Service.class
|
||||||
zip --delete android.jar android/net/Uri.class
|
zip --delete android.jar android/net/Uri.class
|
||||||
@@ -68,12 +68,12 @@ zip --delete android.jar android/os/Environment.class
|
|||||||
zip --delete android.jar android/text/format/Formatter.class
|
zip --delete android.jar android/text/format/Formatter.class
|
||||||
zip --delete android.jar android/text/Html.class
|
zip --delete android.jar android/text/Html.class
|
||||||
|
|
||||||
# Dedup overriden Android classes
|
# Dedup overridden Android classes
|
||||||
ABS_JAR="$(realpath android.jar)"
|
ABS_JAR="$(realpath android.jar)"
|
||||||
function dedup() {
|
function dedup() {
|
||||||
pushd "$1"
|
pushd "$1"
|
||||||
CLASSES="$(find * -type f)"
|
CLASSES="$(find ./* -type f)"
|
||||||
echo "$CLASSES" | while read class
|
echo "$CLASSES" | while read -r class
|
||||||
do
|
do
|
||||||
NAME="${class%.*}"
|
NAME="${class%.*}"
|
||||||
echo "Processing class: $NAME"
|
echo "Processing class: $NAME"
|
||||||
@@ -82,13 +82,10 @@ function dedup() {
|
|||||||
popd
|
popd
|
||||||
}
|
}
|
||||||
|
|
||||||
pushd ..
|
popd
|
||||||
dedup AndroidCompat/src/main/java
|
dedup AndroidCompat/src/main/java
|
||||||
dedup server/src/main/java
|
|
||||||
dedup server/src/main/kotlin
|
dedup server/src/main/kotlin
|
||||||
popd
|
|
||||||
|
|
||||||
popd
|
|
||||||
echo "Copying Android.jar to library folder..."
|
echo "Copying Android.jar to library folder..."
|
||||||
mv tmp/android.jar AndroidCompat/lib
|
mv tmp/android.jar AndroidCompat/lib
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
android.jar
|
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
package android.graphics;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import javax.imageio.IIOImage;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.imageio.ImageWriteParam;
|
||||||
|
import javax.imageio.ImageWriter;
|
||||||
|
import javax.imageio.stream.ImageOutputStream;
|
||||||
|
|
||||||
|
public final class Bitmap {
|
||||||
|
private int width;
|
||||||
|
private int height;
|
||||||
|
private BufferedImage image;
|
||||||
|
|
||||||
|
public Bitmap(BufferedImage image) {
|
||||||
|
this.image = image;
|
||||||
|
this.width = image.getWidth();
|
||||||
|
this.height = image.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferedImage getImage() {
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeight() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWidth() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CompressFormat {
|
||||||
|
JPEG (0),
|
||||||
|
PNG (1),
|
||||||
|
WEBP (2),
|
||||||
|
WEBP_LOSSY (3),
|
||||||
|
WEBP_LOSSLESS (4);
|
||||||
|
|
||||||
|
CompressFormat(int nativeInt) {
|
||||||
|
this.nativeInt = nativeInt;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int nativeInt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Config {
|
||||||
|
ALPHA_8(1),
|
||||||
|
RGB_565(3),
|
||||||
|
ARGB_4444(4),
|
||||||
|
ARGB_8888(5),
|
||||||
|
RGBA_F16(6),
|
||||||
|
HARDWARE(7),
|
||||||
|
RGBA_1010102(8);
|
||||||
|
|
||||||
|
final int nativeInt;
|
||||||
|
|
||||||
|
private static Config sConfigs[] = {
|
||||||
|
null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888, RGBA_F16, HARDWARE, RGBA_1010102
|
||||||
|
};
|
||||||
|
|
||||||
|
Config(int ni) {
|
||||||
|
this.nativeInt = ni;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Config nativeToConfig(int ni) {
|
||||||
|
return sConfigs[ni];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Bitmap createBitmap(int width, int height, Config config) {
|
||||||
|
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||||
|
return new Bitmap(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean compress(CompressFormat format, int quality, OutputStream stream) {
|
||||||
|
if (stream == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (quality < 0 || quality > 100) {
|
||||||
|
throw new IllegalArgumentException("quality must be 0..100");
|
||||||
|
}
|
||||||
|
float qualityFloat = ((float) quality) / 100;
|
||||||
|
|
||||||
|
String formatString = "";
|
||||||
|
if (format == Bitmap.CompressFormat.PNG) {
|
||||||
|
formatString = "png";
|
||||||
|
} else if (format == Bitmap.CompressFormat.JPEG) {
|
||||||
|
formatString = "jpg";
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("unsupported compression format!");
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(formatString);
|
||||||
|
if (!writers.hasNext()) {
|
||||||
|
throw new IllegalStateException("no image writers found for this format!");
|
||||||
|
}
|
||||||
|
ImageWriter writer = (ImageWriter) writers.next();
|
||||||
|
|
||||||
|
ImageOutputStream ios;
|
||||||
|
try {
|
||||||
|
ios = ImageIO.createImageOutputStream(stream);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
writer.setOutput(ios);
|
||||||
|
|
||||||
|
ImageWriteParam param = writer.getDefaultWriteParam();
|
||||||
|
if (formatString == "jpg") {
|
||||||
|
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
|
||||||
|
param.setCompressionQuality(qualityFloat);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
writer.write(null, new IIOImage(image, null, null), param);
|
||||||
|
ios.close();
|
||||||
|
writer.dispose();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package android.graphics;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.imageio.ImageReader;
|
||||||
|
import javax.imageio.stream.ImageInputStream;
|
||||||
|
|
||||||
|
public class BitmapFactory {
|
||||||
|
public static Bitmap decodeStream(InputStream inputStream) {
|
||||||
|
Bitmap bitmap = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
ImageInputStream imageInputStream = ImageIO.createImageInputStream(inputStream);
|
||||||
|
Iterator<ImageReader> imageReaders = ImageIO.getImageReaders(imageInputStream);
|
||||||
|
|
||||||
|
if (!imageReaders.hasNext()) {
|
||||||
|
throw new IllegalArgumentException("no reader for image");
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageReader imageReader = imageReaders.next();
|
||||||
|
imageReader.setInput(imageInputStream);
|
||||||
|
|
||||||
|
BufferedImage image = imageReader.read(0, imageReader.getDefaultReadParam());
|
||||||
|
bitmap = new Bitmap(image);
|
||||||
|
|
||||||
|
imageReader.dispose();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Bitmap decodeByteArray(byte[] data, int offset, int length) {
|
||||||
|
Bitmap bitmap = null;
|
||||||
|
|
||||||
|
ByteArrayInputStream byteArrayStream = new ByteArrayInputStream(data);
|
||||||
|
try {
|
||||||
|
BufferedImage image = ImageIO.read(byteArrayStream);
|
||||||
|
bitmap = new Bitmap(image);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package android.graphics;
|
||||||
|
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
|
public final class Canvas {
|
||||||
|
private BufferedImage canvasImage;
|
||||||
|
private Graphics2D canvas;
|
||||||
|
|
||||||
|
public Canvas(Bitmap bitmap) {
|
||||||
|
canvasImage = bitmap.getImage();
|
||||||
|
canvas = canvasImage.createGraphics();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawBitmap(Bitmap sourceBitmap, Rect src, Rect dst, Paint paint) {
|
||||||
|
BufferedImage sourceImage = sourceBitmap.getImage();
|
||||||
|
BufferedImage sourceImageCropped = sourceImage.getSubimage(src.left, src.top, src.getWidth(), src.getHeight());
|
||||||
|
canvas.drawImage(sourceImageCropped, null, dst.left, dst.top);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
package android.graphics;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public final class Rect {
|
||||||
|
int left;
|
||||||
|
int top;
|
||||||
|
int right;
|
||||||
|
int bottom;
|
||||||
|
|
||||||
|
private static final class UnflattenHelper {
|
||||||
|
private static final Pattern FLATTENED_PATTERN = Pattern.compile(
|
||||||
|
"(-?\\d+) (-?\\d+) (-?\\d+) (-?\\d+)");
|
||||||
|
|
||||||
|
static Matcher getMatcher(String str) {
|
||||||
|
return FLATTENED_PATTERN.matcher(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rect() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rect(int left, int top, int right, int bottom) {
|
||||||
|
this.left = left;
|
||||||
|
this.top = top;
|
||||||
|
this.right = right;
|
||||||
|
this.bottom = bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rect(Rect r) {
|
||||||
|
if (r == null) {
|
||||||
|
this.left = 0;
|
||||||
|
this.top = 0;
|
||||||
|
this.right = 0;
|
||||||
|
this.bottom = 0;
|
||||||
|
} else {
|
||||||
|
this.left = left;
|
||||||
|
this.top = top;
|
||||||
|
this.right = right;
|
||||||
|
this.bottom = bottom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int getWidth() {
|
||||||
|
return right - left;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int getHeight() {
|
||||||
|
return bottom - top;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Rect unflattenFromString(String str) {
|
||||||
|
if (str.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matcher matcher = UnflattenHelper.getMatcher(str);
|
||||||
|
if (!matcher.matches()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Rect(Integer.parseInt(matcher.group(1)),
|
||||||
|
Integer.parseInt(matcher.group(2)),
|
||||||
|
Integer.parseInt(matcher.group(3)),
|
||||||
|
Integer.parseInt(matcher.group(4)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toShortString() {
|
||||||
|
return toShortString(new StringBuilder(32));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toShortString(StringBuilder sb) {
|
||||||
|
sb.setLength(0);
|
||||||
|
sb.append('['); sb.append(left); sb.append(',');
|
||||||
|
sb.append(top); sb.append("]["); sb.append(right);
|
||||||
|
sb.append(','); sb.append(bottom); sb.append(']');
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String flattenToString() {
|
||||||
|
StringBuilder sb = new StringBuilder(32);
|
||||||
|
sb.append(left);
|
||||||
|
sb.append(' ');
|
||||||
|
sb.append(top);
|
||||||
|
sb.append(' ');
|
||||||
|
sb.append(right);
|
||||||
|
sb.append(' ');
|
||||||
|
sb.append(bottom);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeToParcel(Parcel out, int flags) {
|
||||||
|
out.writeInt(left);
|
||||||
|
out.writeInt(top);
|
||||||
|
out.writeInt(right);
|
||||||
|
out.writeInt(bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Parcelable.Creator<Rect> CREATOR = new Parcelable.Creator<Rect>() {
|
||||||
|
@Override
|
||||||
|
public Rect createFromParcel(Parcel in) {
|
||||||
|
Rect r = new Rect();
|
||||||
|
r.readFromParcel(in);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Rect[] newArray(int size) {
|
||||||
|
return new Rect[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public void readFromParcel(Parcel in) {
|
||||||
|
left = in.readInt();
|
||||||
|
top = in.readInt();
|
||||||
|
right = in.readInt();
|
||||||
|
bottom = in.readInt();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,8 +9,10 @@ import android.content.Context
|
|||||||
class PreferenceManager {
|
class PreferenceManager {
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getDefaultSharedPreferences(context: Context)
|
fun getDefaultSharedPreferences(context: Context) =
|
||||||
= context.getSharedPreferences(context.applicationInfo.packageName,
|
context.getSharedPreferences(
|
||||||
Context.MODE_PRIVATE)!!
|
context.applicationInfo.packageName,
|
||||||
|
Context.MODE_PRIVATE
|
||||||
|
)!!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,291 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package android.support.v4.content;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.StatFs;
|
|
||||||
import android.support.v4.os.EnvironmentCompat;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper for accessing features in {@link android.content.Context}
|
|
||||||
* introduced after API level 4 in a backwards compatible fashion.
|
|
||||||
*/
|
|
||||||
public class ContextCompat {
|
|
||||||
/**
|
|
||||||
* Start a set of activities as a synthesized task stack, if able.
|
|
||||||
*
|
|
||||||
* <p>In API level 11 (Android 3.0/Honeycomb) the recommended conventions for
|
|
||||||
* app navigation using the back key changed. The back key's behavior is local
|
|
||||||
* to the current task and does not capture navigation across different tasks.
|
|
||||||
* Navigating across tasks and easily reaching the previous task is accomplished
|
|
||||||
* through the "recents" UI, accessible through the software-provided Recents key
|
|
||||||
* on the navigation or system bar. On devices with the older hardware button configuration
|
|
||||||
* the recents UI can be accessed with a long press on the Home key.</p>
|
|
||||||
*
|
|
||||||
* <p>When crossing from one task stack to another post-Android 3.0,
|
|
||||||
* the application should synthesize a back stack/history for the new task so that
|
|
||||||
* the user may navigate out of the new task and back to the Launcher by repeated
|
|
||||||
* presses of the back key. Back key presses should not navigate across task stacks.</p>
|
|
||||||
*
|
|
||||||
* <p>startActivities provides a mechanism for constructing a synthetic task stack of
|
|
||||||
* multiple activities. If the underlying API is not available on the system this method
|
|
||||||
* will return false.</p>
|
|
||||||
*
|
|
||||||
* @param context Start activities using this activity as the starting context
|
|
||||||
* @param intents Array of intents defining the activities that will be started. The element
|
|
||||||
* length-1 will correspond to the top activity on the resulting task stack.
|
|
||||||
* @return true if the underlying API was available and the call was successful, false otherwise
|
|
||||||
*/
|
|
||||||
public static boolean startActivities(Context context, Intent[] intents) {
|
|
||||||
return startActivities(context, intents, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start a set of activities as a synthesized task stack, if able.
|
|
||||||
*
|
|
||||||
* <p>In API level 11 (Android 3.0/Honeycomb) the recommended conventions for
|
|
||||||
* app navigation using the back key changed. The back key's behavior is local
|
|
||||||
* to the current task and does not capture navigation across different tasks.
|
|
||||||
* Navigating across tasks and easily reaching the previous task is accomplished
|
|
||||||
* through the "recents" UI, accessible through the software-provided Recents key
|
|
||||||
* on the navigation or system bar. On devices with the older hardware button configuration
|
|
||||||
* the recents UI can be accessed with a long press on the Home key.</p>
|
|
||||||
*
|
|
||||||
* <p>When crossing from one task stack to another post-Android 3.0,
|
|
||||||
* the application should synthesize a back stack/history for the new task so that
|
|
||||||
* the user may navigate out of the new task and back to the Launcher by repeated
|
|
||||||
* presses of the back key. Back key presses should not navigate across task stacks.</p>
|
|
||||||
*
|
|
||||||
* <p>startActivities provides a mechanism for constructing a synthetic task stack of
|
|
||||||
* multiple activities. If the underlying API is not available on the system this method
|
|
||||||
* will return false.</p>
|
|
||||||
*
|
|
||||||
* @param context Start activities using this activity as the starting context
|
|
||||||
* @param intents Array of intents defining the activities that will be started. The element
|
|
||||||
* length-1 will correspond to the top activity on the resulting task stack.
|
|
||||||
* @param options Additional options for how the Activity should be started.
|
|
||||||
* See {@link android.content.Context#startActivity(Intent, Bundle)
|
|
||||||
* @return true if the underlying API was available and the call was successful, false otherwise
|
|
||||||
*/
|
|
||||||
public static boolean startActivities(Context context, Intent[] intents,
|
|
||||||
Bundle options) {
|
|
||||||
context.startActivities(intents, options);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns absolute paths to application-specific directories on all
|
|
||||||
* external storage devices where the application's OBB files (if there are
|
|
||||||
* any) can be found. Note if the application does not have any OBB files,
|
|
||||||
* these directories may not exist.
|
|
||||||
* <p>
|
|
||||||
* This is like {@link Context#getFilesDir()} in that these files will be
|
|
||||||
* deleted when the application is uninstalled, however there are some
|
|
||||||
* important differences:
|
|
||||||
* <ul>
|
|
||||||
* <li>External files are not always available: they will disappear if the
|
|
||||||
* user mounts the external storage on a computer or removes it.
|
|
||||||
* <li>There is no security enforced with these files.
|
|
||||||
* </ul>
|
|
||||||
* <p>
|
|
||||||
* External storage devices returned here are considered a permanent part of
|
|
||||||
* the device, including both emulated external storage and physical media
|
|
||||||
* slots, such as SD cards in a battery compartment. The returned paths do
|
|
||||||
* not include transient devices, such as USB flash drives.
|
|
||||||
* <p>
|
|
||||||
* An application may store data on any or all of the returned devices. For
|
|
||||||
* example, an app may choose to store large files on the device with the
|
|
||||||
* most available space, as measured by {@link StatFs}.
|
|
||||||
* <p>
|
|
||||||
* Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
|
|
||||||
* are required to write to the returned paths; they're always accessible to
|
|
||||||
* the calling app. Before then,
|
|
||||||
* {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} is required to
|
|
||||||
* write. Write access outside of these paths on secondary external storage
|
|
||||||
* devices is not available. To request external storage access in a
|
|
||||||
* backwards compatible way, consider using {@code android:maxSdkVersion}
|
|
||||||
* like this:
|
|
||||||
*
|
|
||||||
* <pre class="prettyprint"><uses-permission
|
|
||||||
* android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
|
||||||
* android:maxSdkVersion="18" /></pre>
|
|
||||||
* <p>
|
|
||||||
* The first path returned is the same as {@link Context#getObbDir()}.
|
|
||||||
* Returned paths may be {@code null} if a storage device is unavailable.
|
|
||||||
*
|
|
||||||
* @see Context#getObbDir()
|
|
||||||
* @see EnvironmentCompat#getStorageState(File)
|
|
||||||
*/
|
|
||||||
public static File[] getObbDirs(Context context) {
|
|
||||||
return context.getObbDirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns absolute paths to application-specific directories on all
|
|
||||||
* external storage devices where the application can place persistent files
|
|
||||||
* it owns. These files are internal to the application, and not typically
|
|
||||||
* visible to the user as media.
|
|
||||||
* <p>
|
|
||||||
* This is like {@link Context#getFilesDir()} in that these files will be
|
|
||||||
* deleted when the application is uninstalled, however there are some
|
|
||||||
* important differences:
|
|
||||||
* <ul>
|
|
||||||
* <li>External files are not always available: they will disappear if the
|
|
||||||
* user mounts the external storage on a computer or removes it.
|
|
||||||
* <li>There is no security enforced with these files.
|
|
||||||
* </ul>
|
|
||||||
* <p>
|
|
||||||
* External storage devices returned here are considered a permanent part of
|
|
||||||
* the device, including both emulated external storage and physical media
|
|
||||||
* slots, such as SD cards in a battery compartment. The returned paths do
|
|
||||||
* not include transient devices, such as USB flash drives.
|
|
||||||
* <p>
|
|
||||||
* An application may store data on any or all of the returned devices. For
|
|
||||||
* example, an app may choose to store large files on the device with the
|
|
||||||
* most available space, as measured by {@link StatFs}.
|
|
||||||
* <p>
|
|
||||||
* Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
|
|
||||||
* are required to write to the returned paths; they're always accessible to
|
|
||||||
* the calling app. Before then,
|
|
||||||
* {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} is required to
|
|
||||||
* write. Write access outside of these paths on secondary external storage
|
|
||||||
* devices is not available. To request external storage access in a
|
|
||||||
* backwards compatible way, consider using {@code android:maxSdkVersion}
|
|
||||||
* like this:
|
|
||||||
*
|
|
||||||
* <pre class="prettyprint"><uses-permission
|
|
||||||
* android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
|
||||||
* android:maxSdkVersion="18" /></pre>
|
|
||||||
* <p>
|
|
||||||
* The first path returned is the same as
|
|
||||||
* {@link Context#getExternalFilesDir(String)}. Returned paths may be
|
|
||||||
* {@code null} if a storage device is unavailable.
|
|
||||||
*
|
|
||||||
* @see Context#getExternalFilesDir(String)
|
|
||||||
* @see EnvironmentCompat#getStorageState(File)
|
|
||||||
*/
|
|
||||||
public static File[] getExternalFilesDirs(Context context, String type) {
|
|
||||||
return context.getExternalFilesDirs(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns absolute paths to application-specific directories on all
|
|
||||||
* external storage devices where the application can place cache files it
|
|
||||||
* owns. These files are internal to the application, and not typically
|
|
||||||
* visible to the user as media.
|
|
||||||
* <p>
|
|
||||||
* This is like {@link Context#getCacheDir()} in that these files will be
|
|
||||||
* deleted when the application is uninstalled, however there are some
|
|
||||||
* important differences:
|
|
||||||
* <ul>
|
|
||||||
* <li>External files are not always available: they will disappear if the
|
|
||||||
* user mounts the external storage on a computer or removes it.
|
|
||||||
* <li>There is no security enforced with these files.
|
|
||||||
* </ul>
|
|
||||||
* <p>
|
|
||||||
* External storage devices returned here are considered a permanent part of
|
|
||||||
* the device, including both emulated external storage and physical media
|
|
||||||
* slots, such as SD cards in a battery compartment. The returned paths do
|
|
||||||
* not include transient devices, such as USB flash drives.
|
|
||||||
* <p>
|
|
||||||
* An application may store data on any or all of the returned devices. For
|
|
||||||
* example, an app may choose to store large files on the device with the
|
|
||||||
* most available space, as measured by {@link StatFs}.
|
|
||||||
* <p>
|
|
||||||
* Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
|
|
||||||
* are required to write to the returned paths; they're always accessible to
|
|
||||||
* the calling app. Before then,
|
|
||||||
* {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} is required to
|
|
||||||
* write. Write access outside of these paths on secondary external storage
|
|
||||||
* devices is not available. To request external storage access in a
|
|
||||||
* backwards compatible way, consider using {@code android:maxSdkVersion}
|
|
||||||
* like this:
|
|
||||||
*
|
|
||||||
* <pre class="prettyprint"><uses-permission
|
|
||||||
* android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
|
||||||
* android:maxSdkVersion="18" /></pre>
|
|
||||||
* <p>
|
|
||||||
* The first path returned is the same as
|
|
||||||
* {@link Context#getExternalCacheDir()}. Returned paths may be {@code null}
|
|
||||||
* if a storage device is unavailable.
|
|
||||||
*
|
|
||||||
* @see Context#getExternalCacheDir()
|
|
||||||
* @see EnvironmentCompat#getStorageState(File)
|
|
||||||
*/
|
|
||||||
public static File[] getExternalCacheDirs(Context context) {
|
|
||||||
return context.getExternalCacheDirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a drawable object associated with a particular resource ID.
|
|
||||||
* <p>
|
|
||||||
* Starting in {@link android.os.Build.VERSION_CODES#LOLLIPOP}, the returned
|
|
||||||
* drawable will be styled for the specified Context's theme.
|
|
||||||
*
|
|
||||||
* @param id The desired resource identifier, as generated by the aapt tool.
|
|
||||||
* This integer encodes the package, type, and resource entry.
|
|
||||||
* The value 0 is an invalid identifier.
|
|
||||||
* @return Drawable An object that can be used to draw this resource.
|
|
||||||
*/
|
|
||||||
public static final Drawable getDrawable(Context context, int id) {
|
|
||||||
return context.getDrawable(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the absolute path to the directory on the filesystem similar to
|
|
||||||
* {@link Context#getFilesDir()}. The difference is that files placed under this
|
|
||||||
* directory will be excluded from automatic backup to remote storage on
|
|
||||||
* devices running {@link android.os.Build.VERSION_CODES#LOLLIPOP} or later. See
|
|
||||||
* {@link android.app.backup.BackupAgent BackupAgent} for a full discussion
|
|
||||||
* of the automatic backup mechanism in Android.
|
|
||||||
*
|
|
||||||
* <p>No permissions are required to read or write to the returned path, since this
|
|
||||||
* path is internal storage.
|
|
||||||
*
|
|
||||||
* @return The path of the directory holding application files that will not be
|
|
||||||
* automatically backed up to remote storage.
|
|
||||||
*
|
|
||||||
* @see android.content.Context.getFilesDir
|
|
||||||
*/
|
|
||||||
public final File getNoBackupFilesDir(Context context) {
|
|
||||||
return context.getNoBackupFilesDir();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the absolute path to the application specific cache directory on
|
|
||||||
* the filesystem designed for storing cached code. On devices running
|
|
||||||
* {@link android.os.Build.VERSION_CODES#LOLLIPOP} or later, the system will delete
|
|
||||||
* any files stored in this location both when your specific application is
|
|
||||||
* upgraded, and when the entire platform is upgraded.
|
|
||||||
* <p>
|
|
||||||
* This location is optimal for storing compiled or optimized code generated
|
|
||||||
* by your application at runtime.
|
|
||||||
* <p>
|
|
||||||
* Apps require no extra permissions to read or write to the returned path,
|
|
||||||
* since this path lives in their private storage.
|
|
||||||
*
|
|
||||||
* @return The path of the directory holding application code cache files.
|
|
||||||
*/
|
|
||||||
public final File getCodeCacheDir(Context context) {
|
|
||||||
return context.getCodeCacheDir();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2011 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package android.support.v4.os;
|
|
||||||
|
|
||||||
import android.os.Environment;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper for accessing features in {@link Environment} introduced after API
|
|
||||||
* level 4 in a backwards compatible fashion.
|
|
||||||
*/
|
|
||||||
public class EnvironmentCompat {
|
|
||||||
/**
|
|
||||||
* Unknown storage state, such as when a path isn't backed by known storage
|
|
||||||
* media.
|
|
||||||
*
|
|
||||||
* @see #getStorageState(File)
|
|
||||||
*/
|
|
||||||
public static final String MEDIA_UNKNOWN = "unknown";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the current state of the storage device that provides the given
|
|
||||||
* path.
|
|
||||||
*
|
|
||||||
* @return one of {@link #MEDIA_UNKNOWN}, {@link Environment#MEDIA_REMOVED},
|
|
||||||
* {@link Environment#MEDIA_UNMOUNTED},
|
|
||||||
* {@link Environment#MEDIA_CHECKING},
|
|
||||||
* {@link Environment#MEDIA_NOFS},
|
|
||||||
* {@link Environment#MEDIA_MOUNTED},
|
|
||||||
* {@link Environment#MEDIA_MOUNTED_READ_ONLY},
|
|
||||||
* {@link Environment#MEDIA_SHARED},
|
|
||||||
* {@link Environment#MEDIA_BAD_REMOVAL}, or
|
|
||||||
* {@link Environment#MEDIA_UNMOUNTABLE}.
|
|
||||||
*/
|
|
||||||
public static String getStorageState(File path) {
|
|
||||||
return Environment.getStorageState(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,193 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2017 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package android.support.v7.preference;
|
|
||||||
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A data store interface to be implemented and provided to the Preferences framework. This can be
|
|
||||||
* used to replace the default {@link android.content.SharedPreferences}, if needed.
|
|
||||||
*
|
|
||||||
* <p>In most cases you want to use {@link android.content.SharedPreferences} as it is automatically
|
|
||||||
* backed up and migrated to new devices. However, providing custom data store to preferences can be
|
|
||||||
* useful if your app stores its preferences in a local db, cloud or they are device specific like
|
|
||||||
* "Developer settings". It might be also useful when you want to use the preferences UI but
|
|
||||||
* the data are not supposed to be stored at all because they are valid per session only.
|
|
||||||
*
|
|
||||||
* <p>Once a put method is called it is full responsibility of the data store implementation to
|
|
||||||
* safely store the given values. Time expensive operations need to be done in the background to
|
|
||||||
* prevent from blocking the UI. You also need to have a plan on how to serialize the data in case
|
|
||||||
* the activity holding this object gets destroyed.
|
|
||||||
*
|
|
||||||
* <p>By default, all "put" methods throw {@link UnsupportedOperationException}.
|
|
||||||
*/
|
|
||||||
public abstract class PreferenceDataStore {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a {@link String} value to the data store.
|
|
||||||
*
|
|
||||||
* <p>Once the value is set the data store is responsible for holding it.
|
|
||||||
*
|
|
||||||
* @param key the name of the preference to modify
|
|
||||||
* @param value the new value for the preference
|
|
||||||
* @see #getString(String, String)
|
|
||||||
*/
|
|
||||||
public void putString(String key, @Nullable String value) {
|
|
||||||
throw new UnsupportedOperationException("Not implemented on this data store");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a set of Strings to the data store.
|
|
||||||
*
|
|
||||||
* <p>Once the value is set the data store is responsible for holding it.
|
|
||||||
*
|
|
||||||
* @param key the name of the preference to modify
|
|
||||||
* @param values the set of new values for the preference
|
|
||||||
* @see #getStringSet(String, Set<String>)
|
|
||||||
*/
|
|
||||||
public void putStringSet(String key, @Nullable Set<String> values) {
|
|
||||||
throw new UnsupportedOperationException("Not implemented on this data store");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets an {@link Integer} value to the data store.
|
|
||||||
*
|
|
||||||
* <p>Once the value is set the data store is responsible for holding it.
|
|
||||||
*
|
|
||||||
* @param key the name of the preference to modify
|
|
||||||
* @param value the new value for the preference
|
|
||||||
* @see #getInt(String, int)
|
|
||||||
*/
|
|
||||||
public void putInt(String key, int value) {
|
|
||||||
throw new UnsupportedOperationException("Not implemented on this data store");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a {@link Long} value to the data store.
|
|
||||||
*
|
|
||||||
* <p>Once the value is set the data store is responsible for holding it.
|
|
||||||
*
|
|
||||||
* @param key the name of the preference to modify
|
|
||||||
* @param value the new value for the preference
|
|
||||||
* @see #getLong(String, long)
|
|
||||||
*/
|
|
||||||
public void putLong(String key, long value) {
|
|
||||||
throw new UnsupportedOperationException("Not implemented on this data store");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a {@link Float} value to the data store.
|
|
||||||
*
|
|
||||||
* <p>Once the value is set the data store is responsible for holding it.
|
|
||||||
*
|
|
||||||
* @param key the name of the preference to modify
|
|
||||||
* @param value the new value for the preference
|
|
||||||
* @see #getFloat(String, float)
|
|
||||||
*/
|
|
||||||
public void putFloat(String key, float value) {
|
|
||||||
throw new UnsupportedOperationException("Not implemented on this data store");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a {@link Boolean} value to the data store.
|
|
||||||
*
|
|
||||||
* <p>Once the value is set the data store is responsible for holding it.
|
|
||||||
*
|
|
||||||
* @param key the name of the preference to modify
|
|
||||||
* @param value the new value for the preference
|
|
||||||
* @see #getBoolean(String, boolean)
|
|
||||||
*/
|
|
||||||
public void putBoolean(String key, boolean value) {
|
|
||||||
throw new UnsupportedOperationException("Not implemented on this data store");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves a {@link String} value from the data store.
|
|
||||||
*
|
|
||||||
* @param key the name of the preference to retrieve
|
|
||||||
* @param defValue value to return if this preference does not exist in the storage
|
|
||||||
* @return the value from the data store or the default return value
|
|
||||||
* @see #putString(String, String)
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
public String getString(String key, @Nullable String defValue) {
|
|
||||||
return defValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves a set of Strings from the data store.
|
|
||||||
*
|
|
||||||
* @param key the name of the preference to retrieve
|
|
||||||
* @param defValues values to return if this preference does not exist in the storage
|
|
||||||
* @return the values from the data store or the default return values
|
|
||||||
* @see #putStringSet(String, Set<String>)
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
public Set<String> getStringSet(String key, @Nullable Set<String> defValues) {
|
|
||||||
return defValues;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves an {@link Integer} value from the data store.
|
|
||||||
*
|
|
||||||
* @param key the name of the preference to retrieve
|
|
||||||
* @param defValue value to return if this preference does not exist in the storage
|
|
||||||
* @return the value from the data store or the default return value
|
|
||||||
* @see #putInt(String, int)
|
|
||||||
*/
|
|
||||||
public int getInt(String key, int defValue) {
|
|
||||||
return defValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves a {@link Long} value from the data store.
|
|
||||||
*
|
|
||||||
* @param key the name of the preference to retrieve
|
|
||||||
* @param defValue value to return if this preference does not exist in the storage
|
|
||||||
* @return the value from the data store or the default return value
|
|
||||||
* @see #putLong(String, long)
|
|
||||||
*/
|
|
||||||
public long getLong(String key, long defValue) {
|
|
||||||
return defValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves a {@link Float} value from the data store.
|
|
||||||
*
|
|
||||||
* @param key the name of the preference to retrieve
|
|
||||||
* @param defValue value to return if this preference does not exist in the storage
|
|
||||||
* @return the value from the data store or the default return value
|
|
||||||
* @see #putFloat(String, float)
|
|
||||||
*/
|
|
||||||
public float getFloat(String key, float defValue) {
|
|
||||||
return defValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves a {@link Boolean} value from the data store.
|
|
||||||
*
|
|
||||||
* @param key the name of the preference to retrieve
|
|
||||||
* @param defValue value to return if this preference does not exist in the storage
|
|
||||||
* @return the value from the data store or the default return value
|
|
||||||
* @see #getBoolean(String, boolean)
|
|
||||||
*/
|
|
||||||
public boolean getBoolean(String key, boolean defValue) {
|
|
||||||
return defValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
package android.support.v7.preference;
|
|
||||||
|
|
||||||
public class PreferenceScreen {
|
|
||||||
}
|
|
||||||
@@ -4,7 +4,7 @@ package android.text;
|
|||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jsoup.Jsoup;
|
import org.jsoup.Jsoup;
|
||||||
import org.jsoup.safety.Whitelist;
|
import org.jsoup.safety.Safelist;
|
||||||
import org.xml.sax.XMLReader;
|
import org.xml.sax.XMLReader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -18,7 +18,7 @@ import org.xml.sax.XMLReader;
|
|||||||
public class Html {
|
public class Html {
|
||||||
|
|
||||||
public static Spanned fromHtml(String source) {
|
public static Spanned fromHtml(String source) {
|
||||||
return new FakeSpanned(Jsoup.clean(source, Whitelist.none()));
|
return new FakeSpanned(Jsoup.clean(source, Safelist.none()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Spanned fromHtml(String source, Html.ImageGetter imageGetter, Html.TagHandler tagHandler) {
|
public static Spanned fromHtml(String source, Html.ImageGetter imageGetter, Html.TagHandler tagHandler) {
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package android.widget;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
public class EditText {
|
||||||
|
public EditText(android.content.Context context) { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
public EditText(android.content.Context context, android.util.AttributeSet attrs) { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
public EditText(android.content.Context context, android.util.AttributeSet attrs, int defStyleAttr) { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
public EditText(android.content.Context context, android.util.AttributeSet attrs, int defStyleAttr, int defStyleRes) { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
public boolean getFreezesText() { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
protected boolean getDefaultEditable() { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
protected android.text.method.MovementMethod getDefaultMovementMethod() { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
public android.text.Editable getText() { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
public void setText(java.lang.CharSequence text, android.widget.TextView.BufferType type) { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
public void setSelection(int start, int stop) { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
public void setSelection(int index) { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
public void selectAll() { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
public void extendSelection(int index) { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
public void setEllipsize(android.text.TextUtils.TruncateAt ellipsis) { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
public java.lang.CharSequence getAccessibilityClassName() { throw new RuntimeException("Stub!"); }
|
||||||
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package android.widget;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
public class Toast {
|
||||||
|
public static final int LENGTH_LONG = 1;
|
||||||
|
public static final int LENGTH_SHORT = 0;
|
||||||
|
|
||||||
|
private CharSequence text;
|
||||||
|
|
||||||
|
private Toast(CharSequence text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Toast(android.content.Context context) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show() {
|
||||||
|
System.out.printf("made a Toast: \"%s\"\n", text.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancel() {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setView(android.view.View view) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public android.view.View getView() {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDuration(int duration) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDuration() {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMargin(float horizontalMargin, float verticalMargin) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getHorizontalMargin() {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getVerticalMargin() {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGravity(int gravity, int xOffset, int yOffset) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getGravity() {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getXOffset() {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getYOffset() {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Toast makeText(android.content.Context context, java.lang.CharSequence text, int duration) {
|
||||||
|
return new Toast(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static android.widget.Toast makeText(android.content.Context context, int resId, int duration) throws android.content.res.Resources.NotFoundException {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(int resId) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(java.lang.CharSequence s) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package androidx.preference;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
public class CheckBoxPreference extends TwoStatePreference {
|
||||||
|
// reference: https://android.googlesource.com/platform/frameworks/support/+/996971f962fcd554339a7cb2859cef9ca89dbcb7/preference/preference/src/main/java/androidx/preference/CheckBoxPreference.java
|
||||||
|
|
||||||
|
public CheckBoxPreference(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package androidx.preference;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
public abstract class DialogPreference extends Preference {
|
||||||
|
private CharSequence dialogTitle;
|
||||||
|
private CharSequence dialogMessage;
|
||||||
|
|
||||||
|
public DialogPreference(Context context) { super(context); }
|
||||||
|
|
||||||
|
public CharSequence getDialogTitle() {
|
||||||
|
return dialogTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDialogTitle(CharSequence dialogTitle) {
|
||||||
|
this.dialogTitle = dialogTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharSequence getDialogMessage() {
|
||||||
|
return dialogMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDialogMessage(CharSequence dialogMessage) {
|
||||||
|
this.dialogMessage = dialogMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package androidx.preference;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
|
||||||
|
public class EditTextPreference extends DialogPreference {
|
||||||
|
// reference: https://android.googlesource.com/platform/frameworks/support/+/996971f962fcd554339a7cb2859cef9ca89dbcb7/preference/preference/src/main/java/androidx/preference/EditTextPreference.java
|
||||||
|
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
private OnBindEditTextListener onBindEditTextListener;
|
||||||
|
|
||||||
|
public EditTextPreference(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OnBindEditTextListener getOnBindEditTextListener() {
|
||||||
|
return onBindEditTextListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnBindEditTextListener(@Nullable OnBindEditTextListener onBindEditTextListener) {
|
||||||
|
this.onBindEditTextListener = onBindEditTextListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnBindEditTextListener {
|
||||||
|
void onBindEditText(@NonNull EditText editText);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Tachidesk specific API */
|
||||||
|
@Override
|
||||||
|
public String getDefaultValueType() {
|
||||||
|
return "String";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package androidx.preference;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
|
||||||
|
public class ListPreference extends Preference {
|
||||||
|
// reference: https://android.googlesource.com/platform/frameworks/support/+/996971f962fcd554339a7cb2859cef9ca89dbcb7/preference/preference/src/main/java/androidx/preference/ListPreference.java
|
||||||
|
// Note: remove @JsonIgnore and implement methods if any extension ever uses these methods or the variables behind them
|
||||||
|
|
||||||
|
private CharSequence[] entries;
|
||||||
|
private CharSequence[] entryValues;
|
||||||
|
|
||||||
|
public ListPreference(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharSequence[] getEntries() {
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEntries(CharSequence[] entries) {
|
||||||
|
this.entries = entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int findIndexOfValue(String value) {
|
||||||
|
if (value != null && entryValues != null) {
|
||||||
|
for (int i = entryValues.length - 1; i >= 0; i--) {
|
||||||
|
if (TextUtils.equals(entryValues[i].toString(), value)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharSequence[] getEntryValues() {
|
||||||
|
return entryValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEntryValues(CharSequence[] entryValues) {
|
||||||
|
this.entryValues = entryValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public void setValueIndex(int index) { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public String getValue() { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public void setValue(String value) { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
/** Tachidesk specific API */
|
||||||
|
@Override
|
||||||
|
public String getDefaultValueType() {
|
||||||
|
return "String";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package androidx.preference;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class MultiSelectListPreference extends DialogPreference {
|
||||||
|
// reference: https://android.googlesource.com/platform/frameworks/support/+/996971f962fcd554339a7cb2859cef9ca89dbcb7/preference/preference/src/main/java/androidx/preference/MultiSelectListPreference.java
|
||||||
|
// Note: remove @JsonIgnore and implement methods if any extension ever uses these methods or the variables behind them
|
||||||
|
|
||||||
|
private CharSequence[] entries;
|
||||||
|
private CharSequence[] entryValues;
|
||||||
|
|
||||||
|
public MultiSelectListPreference(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEntries(CharSequence[] entries) {
|
||||||
|
this.entries = entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharSequence[] getEntries() {
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEntryValues(CharSequence[] entryValues) {
|
||||||
|
this.entryValues = entryValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharSequence[] getEntryValues() {
|
||||||
|
return entryValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public void setValues(Set<String> values) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public Set<String> getValues() {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public int findIndexOfValue(String value) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Tachidesk specific API */
|
||||||
|
@Override
|
||||||
|
public String getDefaultValueType() {
|
||||||
|
return "Set<String>";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
package androidx.preference;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A minimal implementation of androidx.preference.Preference
|
||||||
|
*/
|
||||||
|
public class Preference {
|
||||||
|
// reference: https://android.googlesource.com/platform/frameworks/support/+/996971f962fcd554339a7cb2859cef9ca89dbcb7/preference/preference/src/main/java/androidx/preference/Preference.java
|
||||||
|
// Note: `Preference` doesn't actually hold or persist the value, `OnPreferenceChangeListener` is called and it's up to the extension to persist it.
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
protected Context context;
|
||||||
|
|
||||||
|
private String key;
|
||||||
|
private CharSequence title;
|
||||||
|
private CharSequence summary;
|
||||||
|
private Object defaultValue;
|
||||||
|
|
||||||
|
/** Tachidesk specific API */
|
||||||
|
@JsonIgnore
|
||||||
|
private SharedPreferences sharedPreferences;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public OnPreferenceChangeListener onChangeListener;
|
||||||
|
|
||||||
|
public Preference(Context context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Context getContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnPreferenceChangeListener(OnPreferenceChangeListener onPreferenceChangeListener) {
|
||||||
|
this.onChangeListener = onPreferenceChangeListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnPreferenceClickListener(OnPreferenceClickListener onPreferenceClickListener) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharSequence getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(CharSequence title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharSequence getSummary() {
|
||||||
|
return summary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSummary(CharSequence summary) {
|
||||||
|
this.summary = summary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultValue(Object defaultValue) {
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean callChangeListener(Object newValue) {
|
||||||
|
return onChangeListener == null || onChangeListener.onPreferenceChange(this, newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getDefaultValue() {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Tachidesk specific API */
|
||||||
|
public String getDefaultValueType() {
|
||||||
|
return defaultValue.getClass().getSimpleName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Tachidesk specific API */
|
||||||
|
public SharedPreferences getSharedPreferences() {
|
||||||
|
return sharedPreferences;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Tachidesk specific API */
|
||||||
|
public void setSharedPreferences(SharedPreferences sharedPreferences) {
|
||||||
|
this.sharedPreferences = sharedPreferences;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnPreferenceChangeListener {
|
||||||
|
boolean onPreferenceChange(Preference preference, Object newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnPreferenceClickListener {
|
||||||
|
boolean onPreferenceClick(Preference preference);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Tachidesk specific API */
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Object getCurrentValue() {
|
||||||
|
switch (getDefaultValueType()) {
|
||||||
|
case "String":
|
||||||
|
return sharedPreferences.getString(key, (String)defaultValue);
|
||||||
|
case "Boolean":
|
||||||
|
return sharedPreferences.getBoolean(key, (Boolean)defaultValue);
|
||||||
|
case "Set<String>":
|
||||||
|
return sharedPreferences.getStringSet(key, (Set<String>)defaultValue);
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("Unsupported type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Tachidesk specific API */
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void saveNewValue(Object value) {
|
||||||
|
switch (getDefaultValueType()) {
|
||||||
|
case "String":
|
||||||
|
sharedPreferences.edit().putString(key, (String)value).apply();
|
||||||
|
break;
|
||||||
|
case "Boolean":
|
||||||
|
sharedPreferences.edit().putBoolean(key, (Boolean)value).apply();
|
||||||
|
break;
|
||||||
|
case "Set<String>":
|
||||||
|
sharedPreferences.edit().putStringSet(key, (Set<String>)value).apply();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("Unsupported type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package androidx.preference;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PreferenceScreen extends Preference {
|
||||||
|
/** Tachidesk specific API */
|
||||||
|
private List<Preference> preferences = new LinkedList<>();
|
||||||
|
|
||||||
|
public PreferenceScreen(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addPreference(Preference preference) {
|
||||||
|
// propagate own shared preferences
|
||||||
|
preference.setSharedPreferences(getSharedPreferences());
|
||||||
|
|
||||||
|
preferences.add(preference);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Tachidesk specific API */
|
||||||
|
public List<Preference> getPreferences(){
|
||||||
|
return preferences;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package androidx.preference;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
public class SwitchPreferenceCompat extends TwoStatePreference {
|
||||||
|
// reference: https://android.googlesource.com/platform/frameworks/support/+/996971f962fcd554339a7cb2859cef9ca89dbcb7/preference/preference/src/main/java/androidx/preference/CheckBoxPreference.java
|
||||||
|
|
||||||
|
public SwitchPreferenceCompat(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package androidx.preference;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
|
||||||
|
public class TwoStatePreference extends Preference {
|
||||||
|
// Note: remove @JsonIgnore and implement methods if any extension ever uses these methods or the variables behind them
|
||||||
|
|
||||||
|
public TwoStatePreference(Context context) {
|
||||||
|
super(context);
|
||||||
|
setDefaultValue(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public boolean isChecked() { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public void setChecked(boolean checked) { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public CharSequence getSummaryOn() { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public void setSummaryOn(CharSequence summary) { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public CharSequence getSummaryOff() { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public void setSummaryOff(CharSequence summary) { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public boolean getDisableDependentsState() { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public void setDisableDependentsState(boolean disableDependentsState) { throw new RuntimeException("Stub!"); }
|
||||||
|
|
||||||
|
/** Tachidesk specific API */
|
||||||
|
@Override
|
||||||
|
public String getDefaultValueType() {
|
||||||
|
return "Boolean";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package app.cash.quickjs;
|
||||||
|
|
||||||
|
import org.mozilla.javascript.ConsString;
|
||||||
|
import org.mozilla.javascript.NativeArray;
|
||||||
|
|
||||||
|
import javax.script.ScriptEngine;
|
||||||
|
import javax.script.ScriptEngineManager;
|
||||||
|
import java.io.Closeable;
|
||||||
|
|
||||||
|
public final class QuickJs implements Closeable {
|
||||||
|
private ScriptEngine engine;
|
||||||
|
|
||||||
|
public static QuickJs create() {
|
||||||
|
return new QuickJs(new ScriptEngineManager());
|
||||||
|
}
|
||||||
|
|
||||||
|
public QuickJs(ScriptEngineManager manager) {
|
||||||
|
this.engine = manager.getEngineByName("rhino");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object evaluate(String script, String fileName) {
|
||||||
|
return this.evaluate(script);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object evaluate(String script) {
|
||||||
|
try {
|
||||||
|
Object value = engine.eval(script);
|
||||||
|
return translateType(value);
|
||||||
|
} catch (Exception exception) {
|
||||||
|
throw new QuickJsException(exception.getMessage(), exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object translateType(Object obj) {
|
||||||
|
if (obj instanceof NativeArray) {
|
||||||
|
NativeArray array = (NativeArray) obj;
|
||||||
|
long length = array.getLength();
|
||||||
|
Object[] objects = new Object[(int) length];
|
||||||
|
for (int i = 0; i < (int) length; i++) {
|
||||||
|
objects[i] = translateType(array.get(i));
|
||||||
|
}
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
if (obj instanceof ConsString) {
|
||||||
|
ConsString consString = (ConsString) obj;
|
||||||
|
return consString.toString();
|
||||||
|
}
|
||||||
|
if (obj instanceof Long) {
|
||||||
|
Long value = (Long) obj;
|
||||||
|
return value.intValue();
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] compile(String sourceCode, String fileName) {
|
||||||
|
return sourceCode.getBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Object execute(byte[] bytecode) {
|
||||||
|
return this.evaluate(new String(bytecode));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
this.engine = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package app.cash.quickjs;
|
||||||
|
|
||||||
|
public final class QuickJsException extends RuntimeException {
|
||||||
|
public QuickJsException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,9 +14,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.android.internal.util;
|
package com.android.internal.util;
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
|
||||||
import android.graphics.Bitmap.CompressFormat;
|
import android.graphics.Bitmap.CompressFormat;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
@@ -25,19 +26,14 @@ import android.util.Xml;
|
|||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
import org.xmlpull.v1.XmlSerializer;
|
import org.xmlpull.v1.XmlSerializer;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.ProtocolException;
|
import java.net.ProtocolException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
/** {@hide} */
|
/** {@hide} */
|
||||||
public class XmlUtils {
|
public class XmlUtils {
|
||||||
private static final String STRING_ARRAY_SEPARATOR = ":";
|
private static final String STRING_ARRAY_SEPARATOR = ":";
|
||||||
@@ -1396,9 +1392,9 @@ public class XmlUtils {
|
|||||||
} else if (tagName.equals("long")) {
|
} else if (tagName.equals("long")) {
|
||||||
return Long.valueOf(parser.getAttributeValue(null, "value"));
|
return Long.valueOf(parser.getAttributeValue(null, "value"));
|
||||||
} else if (tagName.equals("float")) {
|
} else if (tagName.equals("float")) {
|
||||||
return new Float(parser.getAttributeValue(null, "value"));
|
return Float.valueOf(parser.getAttributeValue(null, "value"));
|
||||||
} else if (tagName.equals("double")) {
|
} else if (tagName.equals("double")) {
|
||||||
return new Double(parser.getAttributeValue(null, "value"));
|
return Double.valueOf(parser.getAttributeValue(null, "value"));
|
||||||
} else if (tagName.equals("boolean")) {
|
} else if (tagName.equals("boolean")) {
|
||||||
return Boolean.valueOf(parser.getAttributeValue(null, "value"));
|
return Boolean.valueOf(parser.getAttributeValue(null, "value"));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
package com.f2prateek;
|
|
||||||
//TODO Consider if we can change this package into an Android dependency
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2014 Prateek Srivastava
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
This file may have been modified after being copied from it's original source.
|
|
||||||
*/
|
|
||||||
package com.f2prateek.rx.preferences;
|
|
||||||
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
|
|
||||||
final class BooleanAdapter implements Preference.Adapter<Boolean> {
|
|
||||||
static final BooleanAdapter INSTANCE = new BooleanAdapter();
|
|
||||||
|
|
||||||
@Override public Boolean get(@NonNull String key, @NonNull SharedPreferences preferences) {
|
|
||||||
return preferences.getBoolean(key, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void set(@NonNull String key, @NonNull Boolean value,
|
|
||||||
@NonNull SharedPreferences.Editor editor) {
|
|
||||||
editor.putBoolean(key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2014 Prateek Srivastava
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
This file may have been modified after being copied from it's original source.
|
|
||||||
*/
|
|
||||||
package com.f2prateek.rx.preferences;
|
|
||||||
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
|
|
||||||
final class EnumAdapter<T extends Enum<T>> implements Preference.Adapter<T> {
|
|
||||||
private final Class<T> enumClass;
|
|
||||||
|
|
||||||
EnumAdapter(Class<T> enumClass) {
|
|
||||||
this.enumClass = enumClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public T get(@NonNull String key, @NonNull SharedPreferences preferences) {
|
|
||||||
String value = preferences.getString(key, null);
|
|
||||||
assert value != null; // Not called unless key is present.
|
|
||||||
return Enum.valueOf(enumClass, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void set(@NonNull String key, @NonNull T value, @NonNull SharedPreferences.Editor editor) {
|
|
||||||
editor.putString(key, value.name());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2014 Prateek Srivastava
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
This file may have been modified after being copied from it's original source.
|
|
||||||
*/
|
|
||||||
package com.f2prateek.rx.preferences;
|
|
||||||
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
|
|
||||||
final class FloatAdapter implements Preference.Adapter<Float> {
|
|
||||||
static final FloatAdapter INSTANCE = new FloatAdapter();
|
|
||||||
|
|
||||||
@Override public Float get(@NonNull String key, @NonNull SharedPreferences preferences) {
|
|
||||||
return preferences.getFloat(key, 0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void set(@NonNull String key, @NonNull Float value,
|
|
||||||
@NonNull SharedPreferences.Editor editor) {
|
|
||||||
editor.putFloat(key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2014 Prateek Srivastava
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
This file may have been modified after being copied from it's original source.
|
|
||||||
*/
|
|
||||||
package com.f2prateek.rx.preferences;
|
|
||||||
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
|
|
||||||
final class IntegerAdapter implements Preference.Adapter<Integer> {
|
|
||||||
static final IntegerAdapter INSTANCE = new IntegerAdapter();
|
|
||||||
|
|
||||||
@Override public Integer get(@NonNull String key, @NonNull SharedPreferences preferences) {
|
|
||||||
return preferences.getInt(key, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void set(@NonNull String key, @NonNull Integer value,
|
|
||||||
@NonNull SharedPreferences.Editor editor) {
|
|
||||||
editor.putInt(key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2014 Prateek Srivastava
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
This file may have been modified after being copied from it's original source.
|
|
||||||
*/
|
|
||||||
package com.f2prateek.rx.preferences;
|
|
||||||
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
|
|
||||||
final class LongAdapter implements Preference.Adapter<Long> {
|
|
||||||
static final LongAdapter INSTANCE = new LongAdapter();
|
|
||||||
|
|
||||||
@Override public Long get(@NonNull String key, @NonNull SharedPreferences preferences) {
|
|
||||||
return preferences.getLong(key, 0L);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void set(@NonNull String key, @NonNull Long value,
|
|
||||||
@NonNull SharedPreferences.Editor editor) {
|
|
||||||
editor.putLong(key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2014 Prateek Srivastava
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
This file has been modified after being copied from it's original source.
|
|
||||||
*/
|
|
||||||
package com.f2prateek.rx.preferences;
|
|
||||||
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.support.annotation.CheckResult;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import rx.Observable;
|
|
||||||
import rx.functions.Action1;
|
|
||||||
|
|
||||||
/** A preference of type {@link T}. Instances can be created from {@link RxSharedPreferences}. */
|
|
||||||
public final class Preference<T> {
|
|
||||||
/** Stores and retrieves instances of {@code T} in {@link SharedPreferences}. */
|
|
||||||
public interface Adapter<T> {
|
|
||||||
/** Retrieve the value for {@code key} from {@code preferences}. */
|
|
||||||
T get(@NonNull String key, @NonNull SharedPreferences preferences);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store non-null {@code value} for {@code key} in {@code editor}.
|
|
||||||
* <p>
|
|
||||||
* Note: Implementations <b>must not</b> call {@code commit()} or {@code apply()} on
|
|
||||||
* {@code editor}.
|
|
||||||
*/
|
|
||||||
void set(@NonNull String key, @NonNull T value, @NonNull SharedPreferences.Editor editor);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final SharedPreferences preferences;
|
|
||||||
private final String key;
|
|
||||||
private final T defaultValue;
|
|
||||||
private final Adapter<T> adapter;
|
|
||||||
private final Observable<T> values;
|
|
||||||
|
|
||||||
Preference(SharedPreferences preferences, final String key, T defaultValue, Adapter<T> adapter,
|
|
||||||
Observable<String> keyChanges) {
|
|
||||||
this.preferences = preferences;
|
|
||||||
this.key = key;
|
|
||||||
this.defaultValue = defaultValue;
|
|
||||||
this.adapter = adapter;
|
|
||||||
this.values = keyChanges
|
|
||||||
.filter(key::equals)
|
|
||||||
.startWith("<init>") // Dummy value to trigger initial load.
|
|
||||||
.onBackpressureLatest()
|
|
||||||
.map(ignored -> get());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The key for which this preference will store and retrieve values. */
|
|
||||||
@NonNull
|
|
||||||
public String key() {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The value used if none is stored. May be {@code null}. */
|
|
||||||
@Nullable
|
|
||||||
public T defaultValue() {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the current value for this preference. Returns {@link #defaultValue()} if no value is
|
|
||||||
* set.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
public T get() {
|
|
||||||
if (!preferences.contains(key)) {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
return adapter.get(key, preferences);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Change this preference's stored value to {@code value}. A value of {@code null} will delete the
|
|
||||||
* preference.
|
|
||||||
*/
|
|
||||||
public void set(@Nullable T value) {
|
|
||||||
SharedPreferences.Editor editor = preferences.edit();
|
|
||||||
if (value == null) {
|
|
||||||
editor.remove(key);
|
|
||||||
} else {
|
|
||||||
adapter.set(key, value, editor);
|
|
||||||
}
|
|
||||||
editor.apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns true if this preference has a stored value. */
|
|
||||||
public boolean isSet() {
|
|
||||||
return preferences.contains(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Delete the stored value for this preference, if any. */
|
|
||||||
public void delete() {
|
|
||||||
set(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Observe changes to this preference. The current value or {@link #defaultValue()} will be
|
|
||||||
* emitted on first subscribe.
|
|
||||||
*/
|
|
||||||
@CheckResult @NonNull
|
|
||||||
public Observable<T> asObservable() {
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An action which stores a new value for this preference. Passing {@code null} will delete the
|
|
||||||
* preference.
|
|
||||||
*/
|
|
||||||
@CheckResult @NonNull
|
|
||||||
public Action1<? super T> asAction() {
|
|
||||||
return (Action1<T>) this::set;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,178 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2014 Prateek Srivastava
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
This file has been modified after being copied from it's original source.
|
|
||||||
*/
|
|
||||||
package com.f2prateek.rx.preferences;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
|
||||||
import android.support.annotation.CheckResult;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Set;
|
|
||||||
import rx.Observable;
|
|
||||||
import rx.subscriptions.Subscriptions;
|
|
||||||
|
|
||||||
import static android.os.Build.VERSION_CODES.HONEYCOMB;
|
|
||||||
import static com.f2prateek.rx.preferences.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
/** A factory for reactive {@link Preference} objects. */
|
|
||||||
public final class RxSharedPreferences {
|
|
||||||
private static final Float DEFAULT_FLOAT = 0f;
|
|
||||||
private static final Integer DEFAULT_INTEGER = 0;
|
|
||||||
private static final Boolean DEFAULT_BOOLEAN = Boolean.FALSE;
|
|
||||||
private static final Long DEFAULT_LONG = 0L;
|
|
||||||
|
|
||||||
/** Create an instance of {@link RxSharedPreferences} for {@code preferences}. */
|
|
||||||
@CheckResult @NonNull
|
|
||||||
public static RxSharedPreferences create(@NonNull SharedPreferences preferences) {
|
|
||||||
checkNotNull(preferences, "preferences == null");
|
|
||||||
return new RxSharedPreferences(preferences);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final SharedPreferences preferences;
|
|
||||||
private final Observable<String> keyChanges;
|
|
||||||
|
|
||||||
private RxSharedPreferences(final SharedPreferences preferences) {
|
|
||||||
this.preferences = preferences;
|
|
||||||
this.keyChanges = Observable.create((Observable.OnSubscribe<String>) subscriber -> {
|
|
||||||
final OnSharedPreferenceChangeListener listener = (preferences1, key) -> subscriber.onNext(key);
|
|
||||||
|
|
||||||
preferences.registerOnSharedPreferenceChangeListener(listener);
|
|
||||||
|
|
||||||
subscriber.add(Subscriptions.create(() -> preferences.unregisterOnSharedPreferenceChangeListener(listener)));
|
|
||||||
}).share();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a boolean preference for {@code key}. Default is {@code false}. */
|
|
||||||
@CheckResult @NonNull
|
|
||||||
public Preference<Boolean> getBoolean(@NonNull String key) {
|
|
||||||
return getBoolean(key, DEFAULT_BOOLEAN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a boolean preference for {@code key} with a default of {@code defaultValue}. */
|
|
||||||
@CheckResult @NonNull
|
|
||||||
public Preference<Boolean> getBoolean(@NonNull String key, @Nullable Boolean defaultValue) {
|
|
||||||
checkNotNull(key, "key == null");
|
|
||||||
return new Preference<>(preferences, key, defaultValue, BooleanAdapter.INSTANCE, keyChanges);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create an enum preference for {@code key}. Default is {@code null}. */
|
|
||||||
@CheckResult @NonNull
|
|
||||||
public <T extends Enum<T>> Preference<T> getEnum(@NonNull String key,
|
|
||||||
@NonNull Class<T> enumClass) {
|
|
||||||
return getEnum(key, null, enumClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create an enum preference for {@code key} with a default of {@code defaultValue}. */
|
|
||||||
@CheckResult @NonNull
|
|
||||||
public <T extends Enum<T>> Preference<T> getEnum(@NonNull String key, @Nullable T defaultValue,
|
|
||||||
@NonNull Class<T> enumClass) {
|
|
||||||
checkNotNull(key, "key == null");
|
|
||||||
checkNotNull(enumClass, "enumClass == null");
|
|
||||||
Preference.Adapter<T> adapter = new EnumAdapter<>(enumClass);
|
|
||||||
return new Preference<>(preferences, key, defaultValue, adapter, keyChanges);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a float preference for {@code key}. Default is {@code 0}. */
|
|
||||||
@CheckResult @NonNull
|
|
||||||
public Preference<Float> getFloat(@NonNull String key) {
|
|
||||||
return getFloat(key, DEFAULT_FLOAT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a float preference for {@code key} with a default of {@code defaultValue}. */
|
|
||||||
@CheckResult @NonNull
|
|
||||||
public Preference<Float> getFloat(@NonNull String key, @Nullable Float defaultValue) {
|
|
||||||
checkNotNull(key, "key == null");
|
|
||||||
return new Preference<>(preferences, key, defaultValue, FloatAdapter.INSTANCE, keyChanges);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create an integer preference for {@code key}. Default is {@code 0}. */
|
|
||||||
@CheckResult @NonNull
|
|
||||||
public Preference<Integer> getInteger(@NonNull String key) {
|
|
||||||
//noinspection UnnecessaryBoxing
|
|
||||||
return getInteger(key, DEFAULT_INTEGER);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create an integer preference for {@code key} with a default of {@code defaultValue}. */
|
|
||||||
@CheckResult @NonNull
|
|
||||||
public Preference<Integer> getInteger(@NonNull String key, @Nullable Integer defaultValue) {
|
|
||||||
checkNotNull(key, "key == null");
|
|
||||||
return new Preference<>(preferences, key, defaultValue, IntegerAdapter.INSTANCE, keyChanges);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a long preference for {@code key}. Default is {@code 0}. */
|
|
||||||
@CheckResult @NonNull
|
|
||||||
public Preference<Long> getLong(@NonNull String key) {
|
|
||||||
//noinspection UnnecessaryBoxing
|
|
||||||
return getLong(key, DEFAULT_LONG);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a long preference for {@code key} with a default of {@code defaultValue}. */
|
|
||||||
@CheckResult @NonNull
|
|
||||||
public Preference<Long> getLong(@NonNull String key, @Nullable Long defaultValue) {
|
|
||||||
checkNotNull(key, "key == null");
|
|
||||||
return new Preference<>(preferences, key, defaultValue, LongAdapter.INSTANCE, keyChanges);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a preference of type {@code T} for {@code key}. Default is {@code null}. */
|
|
||||||
@CheckResult @NonNull
|
|
||||||
public <T> Preference<T> getObject(@NonNull String key, @NonNull Preference.Adapter<T> adapter) {
|
|
||||||
return getObject(key, null, adapter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a preference for type {@code T} for {@code key} with a default of {@code defaultValue}.
|
|
||||||
*/
|
|
||||||
@CheckResult @NonNull
|
|
||||||
public <T> Preference<T> getObject(@NonNull String key, @Nullable T defaultValue,
|
|
||||||
@NonNull Preference.Adapter<T> adapter) {
|
|
||||||
checkNotNull(key, "key == null");
|
|
||||||
checkNotNull(adapter, "adapter == null");
|
|
||||||
return new Preference<>(preferences, key, defaultValue, adapter, keyChanges);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a string preference for {@code key}. Default is {@code null}. */
|
|
||||||
@CheckResult @NonNull
|
|
||||||
public Preference<String> getString(@NonNull String key) {
|
|
||||||
return getString(key, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a string preference for {@code key} with a default of {@code defaultValue}. */
|
|
||||||
@CheckResult @NonNull
|
|
||||||
public Preference<String> getString(@NonNull String key, @Nullable String defaultValue) {
|
|
||||||
checkNotNull(key, "key == null");
|
|
||||||
return new Preference<>(preferences, key, defaultValue, StringAdapter.INSTANCE, keyChanges);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a string set preference for {@code key}. Default is an empty set. */
|
|
||||||
@TargetApi(HONEYCOMB)
|
|
||||||
@CheckResult @NonNull
|
|
||||||
public Preference<Set<String>> getStringSet(@NonNull String key) {
|
|
||||||
return getStringSet(key, Collections.emptySet());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a string set preference for {@code key} with a default of {@code defaultValue}. */
|
|
||||||
@TargetApi(HONEYCOMB)
|
|
||||||
@CheckResult @NonNull
|
|
||||||
public Preference<Set<String>> getStringSet(@NonNull String key,
|
|
||||||
@NonNull Set<String> defaultValue) {
|
|
||||||
checkNotNull(key, "key == null");
|
|
||||||
return new Preference<>(preferences, key, defaultValue, StringSetAdapter.INSTANCE, keyChanges);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package com.f2prateek.rx.preferences;
|
|
||||||
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
|
|
||||||
final class StringAdapter implements Preference.Adapter<String> {
|
|
||||||
static final StringAdapter INSTANCE = new StringAdapter();
|
|
||||||
|
|
||||||
@Override public String get(@NonNull String key, @NonNull SharedPreferences preferences) {
|
|
||||||
return preferences.getString(key, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void set(@NonNull String key, @NonNull String value,
|
|
||||||
@NonNull SharedPreferences.Editor editor) {
|
|
||||||
editor.putString(key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
package com.f2prateek.rx.preferences;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static android.os.Build.VERSION_CODES.HONEYCOMB;
|
|
||||||
|
|
||||||
@TargetApi(HONEYCOMB)
|
|
||||||
final class StringSetAdapter implements Preference.Adapter<Set<String>> {
|
|
||||||
static final StringSetAdapter INSTANCE = new StringSetAdapter();
|
|
||||||
|
|
||||||
@Override public Set<String> get(@NonNull String key, @NonNull SharedPreferences preferences) {
|
|
||||||
return preferences.getStringSet(key, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void set(@NonNull String key, @NonNull Set<String> value,
|
|
||||||
@NonNull SharedPreferences.Editor editor) {
|
|
||||||
editor.putStringSet(key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-7
@@ -1,7 +0,0 @@
|
|||||||
package com.github.pwittchen.reactivenetwork.library
|
|
||||||
|
|
||||||
import android.net.NetworkInfo
|
|
||||||
|
|
||||||
class Connectivity {
|
|
||||||
val state = NetworkInfo.State.CONNECTED
|
|
||||||
}
|
|
||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
package com.github.pwittchen.reactivenetwork.library
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import rx.Observable
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by nulldev on 12/29/16.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class ReactiveNetwork {
|
|
||||||
companion object {
|
|
||||||
fun observeNetworkConnectivity(context: Context) = Observable.just(Connectivity())!!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
-1
@@ -5,4 +5,4 @@ import android.arch.persistence.db.framework.FrameworkSQLiteOpenHelperFactory
|
|||||||
|
|
||||||
class RequerySQLiteOpenHelperFactory {
|
class RequerySQLiteOpenHelperFactory {
|
||||||
fun create(configuration: SupportSQLiteOpenHelper.Configuration) = FrameworkSQLiteOpenHelperFactory().create(configuration)
|
fun create(configuration: SupportSQLiteOpenHelper.Configuration) = FrameworkSQLiteOpenHelperFactory().create(configuration)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
package kotlinx.coroutines.experimental.android
|
|
||||||
|
|
||||||
import kotlinx.coroutines.GlobalScope
|
|
||||||
|
|
||||||
val UI = GlobalScope.coroutineContext
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package rx.android.schedulers
|
package rx.android.schedulers
|
||||||
|
|
||||||
|
import rx.Scheduler
|
||||||
import rx.internal.schedulers.ImmediateScheduler
|
import rx.internal.schedulers.ImmediateScheduler
|
||||||
|
|
||||||
class AndroidSchedulers {
|
class AndroidSchedulers {
|
||||||
@@ -11,6 +12,7 @@ class AndroidSchedulers {
|
|||||||
/**
|
/**
|
||||||
* Simulated main thread scheduler
|
* Simulated main thread scheduler
|
||||||
*/
|
*/
|
||||||
fun mainThread() = mainThreadScheduler
|
@JvmStatic
|
||||||
|
fun mainThread(): Scheduler = mainThreadScheduler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,4 +14,4 @@ class AndroidCompat {
|
|||||||
application.attach(context)
|
application.attach(context)
|
||||||
application.onCreate()
|
application.onCreate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package xyz.nulldev.androidcompat
|
|||||||
|
|
||||||
import org.kodein.di.DI
|
import org.kodein.di.DI
|
||||||
import org.kodein.di.conf.global
|
import org.kodein.di.conf.global
|
||||||
import xyz.nulldev.androidcompat.bytecode.ModApplier
|
|
||||||
import xyz.nulldev.androidcompat.config.ApplicationInfoConfigModule
|
import xyz.nulldev.androidcompat.config.ApplicationInfoConfigModule
|
||||||
import xyz.nulldev.androidcompat.config.FilesConfigModule
|
import xyz.nulldev.androidcompat.config.FilesConfigModule
|
||||||
import xyz.nulldev.androidcompat.config.SystemConfigModule
|
import xyz.nulldev.androidcompat.config.SystemConfigModule
|
||||||
@@ -12,19 +11,17 @@ import xyz.nulldev.ts.config.GlobalConfigManager
|
|||||||
* Initializes the Android compatibility module
|
* Initializes the Android compatibility module
|
||||||
*/
|
*/
|
||||||
class AndroidCompatInitializer {
|
class AndroidCompatInitializer {
|
||||||
|
|
||||||
val modApplier by lazy { ModApplier() }
|
|
||||||
|
|
||||||
fun init() {
|
fun init() {
|
||||||
modApplier.apply()
|
|
||||||
|
|
||||||
DI.global.addImport(AndroidCompatModule().create())
|
DI.global.addImport(AndroidCompatModule().create())
|
||||||
|
|
||||||
//Register config modules
|
// Register config modules
|
||||||
GlobalConfigManager.registerModules(
|
GlobalConfigManager.registerModules(
|
||||||
FilesConfigModule.register(GlobalConfigManager.config),
|
FilesConfigModule.register(GlobalConfigManager.config),
|
||||||
ApplicationInfoConfigModule.register(GlobalConfigManager.config),
|
ApplicationInfoConfigModule.register(GlobalConfigManager.config),
|
||||||
SystemConfigModule.register(GlobalConfigManager.config)
|
SystemConfigModule.register(GlobalConfigManager.config)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Set some properties extensions use
|
||||||
|
System.setProperty("http.agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class AndroidCompatModule {
|
|||||||
|
|
||||||
bind<PackageController>() with singleton { PackageController() }
|
bind<PackageController>() with singleton { PackageController() }
|
||||||
|
|
||||||
//Context
|
// Context
|
||||||
bind<CustomContext>() with singleton { CustomContext() }
|
bind<CustomContext>() with singleton { CustomContext() }
|
||||||
bind<Context>() with singleton {
|
bind<Context>() with singleton {
|
||||||
val context: Context by DI.global.instance<CustomContext>()
|
val context: Context by DI.global.instance<CustomContext>()
|
||||||
|
|||||||
+10
-13
@@ -38,7 +38,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import xyz.nulldev.androidcompat.info.ApplicationInfoImpl;
|
import xyz.nulldev.androidcompat.info.ApplicationInfoImpl;
|
||||||
import xyz.nulldev.androidcompat.io.AndroidFiles;
|
import xyz.nulldev.androidcompat.io.AndroidFiles;
|
||||||
import xyz.nulldev.androidcompat.io.sharedprefs.JsonSharedPreferences;
|
import xyz.nulldev.androidcompat.io.sharedprefs.JavaSharedPreferences;
|
||||||
import xyz.nulldev.androidcompat.service.ServiceSupport;
|
import xyz.nulldev.androidcompat.service.ServiceSupport;
|
||||||
import xyz.nulldev.androidcompat.util.KodeinGlobalHelper;
|
import xyz.nulldev.androidcompat.util.KodeinGlobalHelper;
|
||||||
|
|
||||||
@@ -50,10 +50,9 @@ import java.util.Map;
|
|||||||
/**
|
/**
|
||||||
* Custom context implementation.
|
* Custom context implementation.
|
||||||
*
|
*
|
||||||
* TODO Deal with packagemanager for extension sources
|
|
||||||
*/
|
*/
|
||||||
public class CustomContext extends Context implements DIAware {
|
public class CustomContext extends Context implements DIAware {
|
||||||
private DI kodein;
|
private final DI kodein;
|
||||||
public CustomContext() {
|
public CustomContext() {
|
||||||
this(KodeinGlobalHelper.kodein());
|
this(KodeinGlobalHelper.kodein());
|
||||||
}
|
}
|
||||||
@@ -165,23 +164,22 @@ public class CustomContext extends Context implements DIAware {
|
|||||||
/** Fake shared prefs! **/
|
/** Fake shared prefs! **/
|
||||||
private Map<String, SharedPreferences> prefs = new HashMap<>(); //Cache
|
private Map<String, SharedPreferences> prefs = new HashMap<>(); //Cache
|
||||||
|
|
||||||
private File sharedPrefsFileFromString(String s) {
|
|
||||||
return new File(androidFiles.getPrefsDir(), s + ".json");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized SharedPreferences getSharedPreferences(String s, int i) {
|
public synchronized SharedPreferences getSharedPreferences(String s, int i) {
|
||||||
SharedPreferences preferences = prefs.get(s);
|
SharedPreferences preferences = prefs.get(s);
|
||||||
//Create new shared preferences if one does not exist
|
//Create new shared preferences if one does not exist
|
||||||
if(preferences == null) {
|
if(preferences == null) {
|
||||||
preferences = getSharedPreferences(sharedPrefsFileFromString(s), i);
|
preferences = new JavaSharedPreferences(s);
|
||||||
prefs.put(s, preferences);
|
prefs.put(s, preferences);
|
||||||
}
|
}
|
||||||
return preferences;
|
return preferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SharedPreferences getSharedPreferences(File file, int mode) {
|
@Override
|
||||||
return new JsonSharedPreferences(file);
|
public SharedPreferences getSharedPreferences(@NotNull File file, int mode) {
|
||||||
|
String path = file.getAbsolutePath().replace('\\', '/');
|
||||||
|
int firstSlash = path.indexOf("/");
|
||||||
|
return new JavaSharedPreferences(path.substring(firstSlash));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -191,8 +189,8 @@ public class CustomContext extends Context implements DIAware {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean deleteSharedPreferences(String name) {
|
public boolean deleteSharedPreferences(String name) {
|
||||||
prefs.remove(name);
|
JavaSharedPreferences item = (JavaSharedPreferences) prefs.remove(name);
|
||||||
return sharedPrefsFileFromString(name).delete();
|
return item.deleteAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -735,4 +733,3 @@ public class CustomContext extends Context implements DIAware {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
package xyz.nulldev.androidcompat.bytecode
|
|
||||||
|
|
||||||
import javassist.CtClass
|
|
||||||
import mu.KotlinLogging
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Applies Javassist modifications
|
|
||||||
*/
|
|
||||||
|
|
||||||
class ModApplier {
|
|
||||||
|
|
||||||
val logger = KotlinLogging.logger {}
|
|
||||||
|
|
||||||
fun apply() {
|
|
||||||
logger.info { "Applying Javassist mods..." }
|
|
||||||
val modifiedClasses = mutableListOf<CtClass>()
|
|
||||||
|
|
||||||
modifiedClasses.forEach {
|
|
||||||
it.toClass()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+5
-4
@@ -1,6 +1,7 @@
|
|||||||
package xyz.nulldev.androidcompat.config
|
package xyz.nulldev.androidcompat.config
|
||||||
|
|
||||||
import com.typesafe.config.Config
|
import com.typesafe.config.Config
|
||||||
|
import io.github.config4k.getValue
|
||||||
import xyz.nulldev.ts.config.ConfigModule
|
import xyz.nulldev.ts.config.ConfigModule
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -8,11 +9,11 @@ import xyz.nulldev.ts.config.ConfigModule
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
class ApplicationInfoConfigModule(config: Config) : ConfigModule(config) {
|
class ApplicationInfoConfigModule(config: Config) : ConfigModule(config) {
|
||||||
val packageName = config.getString("packageName")!!
|
val packageName: String by config
|
||||||
val debug = config.getBoolean("debug")
|
val debug: Boolean by config
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun register(config: Config)
|
fun register(config: Config) =
|
||||||
= ApplicationInfoConfigModule(config.getConfig("android.app"))
|
ApplicationInfoConfigModule(config.getConfig("android.app"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package xyz.nulldev.androidcompat.config
|
package xyz.nulldev.androidcompat.config
|
||||||
|
|
||||||
import com.typesafe.config.Config
|
import com.typesafe.config.Config
|
||||||
|
import io.github.config4k.getValue
|
||||||
import xyz.nulldev.ts.config.ConfigModule
|
import xyz.nulldev.ts.config.ConfigModule
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -8,26 +9,26 @@ import xyz.nulldev.ts.config.ConfigModule
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
class FilesConfigModule(config: Config) : ConfigModule(config) {
|
class FilesConfigModule(config: Config) : ConfigModule(config) {
|
||||||
val dataDir = config.getString("dataDir")!!
|
val dataDir: String by config
|
||||||
val filesDir = config.getString("filesDir")!!
|
val filesDir: String by config
|
||||||
val noBackupFilesDir = config.getString("noBackupFilesDir")!!
|
val noBackupFilesDir: String by config
|
||||||
val externalFilesDirs: MutableList<String> = config.getStringList("externalFilesDirs")!!
|
val externalFilesDirs: MutableList<String> by config
|
||||||
val obbDirs: MutableList<String> = config.getStringList("obbDirs")!!
|
val obbDirs: MutableList<String> by config
|
||||||
val cacheDir = config.getString("cacheDir")!!
|
val cacheDir: String by config
|
||||||
val codeCacheDir = config.getString("codeCacheDir")!!
|
val codeCacheDir: String by config
|
||||||
val externalCacheDirs: MutableList<String> = config.getStringList("externalCacheDirs")!!
|
val externalCacheDirs: MutableList<String> by config
|
||||||
val externalMediaDirs: MutableList<String> = config.getStringList("externalMediaDirs")!!
|
val externalMediaDirs: MutableList<String> by config
|
||||||
val rootDir = config.getString("rootDir")!!
|
val rootDir: String by config
|
||||||
val externalStorageDir = config.getString("externalStorageDir")!!
|
val externalStorageDir: String by config
|
||||||
val downloadCacheDir = config.getString("downloadCacheDir")!!
|
val downloadCacheDir: String by config
|
||||||
val databasesDir = config.getString("databasesDir")!!
|
val databasesDir: String by config
|
||||||
|
|
||||||
val prefsDir = config.getString("prefsDir")!!
|
val prefsDir: String by config
|
||||||
|
|
||||||
val packageDir = config.getString("packageDir")!!
|
val packageDir: String by config
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun register(config: Config)
|
fun register(config: Config) =
|
||||||
= FilesConfigModule(config.getConfig("android.files"))
|
FilesConfigModule(config.getConfig("android.files"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
package xyz.nulldev.androidcompat.config
|
package xyz.nulldev.androidcompat.config
|
||||||
|
|
||||||
import com.typesafe.config.Config
|
import com.typesafe.config.Config
|
||||||
|
import io.github.config4k.getValue
|
||||||
import xyz.nulldev.ts.config.ConfigModule
|
import xyz.nulldev.ts.config.ConfigModule
|
||||||
|
|
||||||
class SystemConfigModule(val config: Config) : ConfigModule(config) {
|
class SystemConfigModule(val config: Config) : ConfigModule(config) {
|
||||||
val isDebuggable = config.getBoolean("isDebuggable")
|
val isDebuggable: Boolean by config
|
||||||
|
|
||||||
val propertyPrefix = "properties."
|
val propertyPrefix = "properties."
|
||||||
|
|
||||||
@@ -15,7 +16,7 @@ class SystemConfigModule(val config: Config) : ConfigModule(config) {
|
|||||||
fun hasProperty(property: String) = config.hasPath("$propertyPrefix$property")
|
fun hasProperty(property: String) = config.hasPath("$propertyPrefix$property")
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun register(config: Config)
|
fun register(config: Config) =
|
||||||
= SystemConfigModule(config.getConfig("android.system"))
|
SystemConfigModule(config.getConfig("android.system"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,21 @@ import java.io.InputStream
|
|||||||
import java.io.Reader
|
import java.io.Reader
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.sql.*
|
|
||||||
import java.sql.Array
|
import java.sql.Array
|
||||||
|
import java.sql.Blob
|
||||||
|
import java.sql.Clob
|
||||||
import java.sql.Date
|
import java.sql.Date
|
||||||
import java.util.*
|
import java.sql.NClob
|
||||||
|
import java.sql.Ref
|
||||||
|
import java.sql.ResultSet
|
||||||
|
import java.sql.ResultSetMetaData
|
||||||
|
import java.sql.RowId
|
||||||
|
import java.sql.SQLXML
|
||||||
|
import java.sql.Time
|
||||||
|
import java.sql.Timestamp
|
||||||
|
import java.util.Calendar
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
class ScrollableResultSet(val parent: ResultSet) : ResultSet by parent {
|
class ScrollableResultSet(val parent: ResultSet) : ResultSet by parent {
|
||||||
|
|
||||||
private val cachedContent = mutableListOf<ResultSetEntry>()
|
private val cachedContent = mutableListOf<ResultSetEntry>()
|
||||||
@@ -19,7 +29,7 @@ class ScrollableResultSet(val parent: ResultSet) : ResultSet by parent {
|
|||||||
|
|
||||||
val parentMetadata = parent.metaData
|
val parentMetadata = parent.metaData
|
||||||
val columnCount = parentMetadata.columnCount
|
val columnCount = parentMetadata.columnCount
|
||||||
val columnLabels = (1 .. columnCount).map {
|
val columnLabels = (1..columnCount).map {
|
||||||
parentMetadata.getColumnLabel(it)
|
parentMetadata.getColumnLabel(it)
|
||||||
}.toTypedArray()
|
}.toTypedArray()
|
||||||
|
|
||||||
@@ -31,10 +41,10 @@ class ScrollableResultSet(val parent: ResultSet) : ResultSet by parent {
|
|||||||
// How can we optimize this?
|
// How can we optimize this?
|
||||||
// We need to fill the cache as the set is loaded
|
// We need to fill the cache as the set is loaded
|
||||||
|
|
||||||
//Fill cache
|
// Fill cache
|
||||||
while(parent.next()) {
|
while (parent.next()) {
|
||||||
cachedContent += ResultSetEntry().apply {
|
cachedContent += ResultSetEntry().apply {
|
||||||
for(i in 1 .. columnCount)
|
for (i in 1..columnCount)
|
||||||
data += parent.getObject(i)
|
data += parent.getObject(i)
|
||||||
}
|
}
|
||||||
resultSetLength++
|
resultSetLength++
|
||||||
@@ -50,9 +60,13 @@ class ScrollableResultSet(val parent: ResultSet) : ResultSet by parent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun internalMove(row: Int) {
|
private fun internalMove(row: Int) {
|
||||||
if(cursor < 0) cursor = 0
|
if (cursor < 0) {
|
||||||
else if(cursor > resultSetLength + 1) cursor = resultSetLength + 1
|
cursor = 0
|
||||||
else cursor = row
|
} else if (cursor > resultSetLength + 1) {
|
||||||
|
cursor = resultSetLength + 1
|
||||||
|
} else {
|
||||||
|
cursor = row
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun obj(column: Int): Any? {
|
private fun obj(column: Int): Any? {
|
||||||
@@ -65,10 +79,10 @@ class ScrollableResultSet(val parent: ResultSet) : ResultSet by parent {
|
|||||||
return obj(cachedFindColumn(column))
|
return obj(cachedFindColumn(column))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun cachedFindColumn(column: String?)
|
private fun cachedFindColumn(column: String?) =
|
||||||
= columnCache.getOrPut(column!!, {
|
columnCache.getOrPut(column!!, {
|
||||||
findColumn(column)
|
findColumn(column)
|
||||||
})
|
})
|
||||||
|
|
||||||
override fun getNClob(columnIndex: Int): NClob {
|
override fun getNClob(columnIndex: Int): NClob {
|
||||||
return obj(columnIndex) as NClob
|
return obj(columnIndex) as NClob
|
||||||
@@ -147,27 +161,27 @@ class ScrollableResultSet(val parent: ResultSet) : ResultSet by parent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getDate(columnIndex: Int): Date {
|
override fun getDate(columnIndex: Int): Date {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDate(columnLabel: String?): Date {
|
override fun getDate(columnLabel: String?): Date {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDate(columnIndex: Int, cal: Calendar?): Date {
|
override fun getDate(columnIndex: Int, cal: Calendar?): Date {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDate(columnLabel: String?, cal: Calendar?): Date {
|
override fun getDate(columnLabel: String?, cal: Calendar?): Date {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun beforeFirst() {
|
override fun beforeFirst() {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,12 +206,12 @@ class ScrollableResultSet(val parent: ResultSet) : ResultSet by parent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getBigDecimal(columnIndex: Int, scale: Int): BigDecimal {
|
override fun getBigDecimal(columnIndex: Int, scale: Int): BigDecimal {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getBigDecimal(columnLabel: String?, scale: Int): BigDecimal {
|
override fun getBigDecimal(columnLabel: String?, scale: Int): BigDecimal {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,22 +240,22 @@ class ScrollableResultSet(val parent: ResultSet) : ResultSet by parent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getTime(columnIndex: Int): Time {
|
override fun getTime(columnIndex: Int): Time {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTime(columnLabel: String?): Time {
|
override fun getTime(columnLabel: String?): Time {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTime(columnIndex: Int, cal: Calendar?): Time {
|
override fun getTime(columnIndex: Int, cal: Calendar?): Time {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTime(columnLabel: String?, cal: Calendar?): Time {
|
override fun getTime(columnLabel: String?, cal: Calendar?): Time {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,31 +276,32 @@ class ScrollableResultSet(val parent: ResultSet) : ResultSet by parent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun absolute(row: Int): Boolean {
|
override fun absolute(row: Int): Boolean {
|
||||||
if(row > 0) {
|
if (row > 0) {
|
||||||
internalMove(row)
|
internalMove(row)
|
||||||
} else {
|
} else {
|
||||||
last()
|
last()
|
||||||
for(i in 1 .. row)
|
for (i in 1..row)
|
||||||
previous()
|
previous()
|
||||||
}
|
}
|
||||||
return cursorValid()
|
return cursorValid()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSQLXML(columnIndex: Int): SQLXML? {
|
override fun getSQLXML(columnIndex: Int): SQLXML? {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSQLXML(columnLabel: String?): SQLXML? {
|
override fun getSQLXML(columnLabel: String?): SQLXML? {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <T : Any?> unwrap(iface: Class<T>?): T {
|
override fun <T : Any?> unwrap(iface: Class<T>?): T {
|
||||||
if(thisIsWrapperFor(iface))
|
if (thisIsWrapperFor(iface)) {
|
||||||
return this as T
|
return this as T
|
||||||
else
|
} else {
|
||||||
return parent.unwrap(iface)
|
return parent.unwrap(iface)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun next(): Boolean {
|
override fun next(): Boolean {
|
||||||
@@ -416,12 +431,12 @@ class ScrollableResultSet(val parent: ResultSet) : ResultSet by parent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getBlob(columnIndex: Int): Blob {
|
override fun getBlob(columnIndex: Int): Blob {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getBlob(columnLabel: String?): Blob {
|
override fun getBlob(columnLabel: String?): Blob {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -490,12 +505,12 @@ class ScrollableResultSet(val parent: ResultSet) : ResultSet by parent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getObject(columnIndex: Int, map: MutableMap<String, Class<*>>?): Any {
|
override fun getObject(columnIndex: Int, map: MutableMap<String, Class<*>>?): Any {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getObject(columnLabel: String?, map: MutableMap<String, Class<*>>?): Any {
|
override fun getObject(columnLabel: String?, map: MutableMap<String, Class<*>>?): Any {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -521,10 +536,15 @@ class ScrollableResultSet(val parent: ResultSet) : ResultSet by parent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun castToLong(obj: Any?): Long {
|
private fun castToLong(obj: Any?): Long {
|
||||||
if(obj == null) return 0
|
if (obj == null) {
|
||||||
else if(obj is Long) return obj
|
return 0
|
||||||
else if(obj is Number) return obj.toLong()
|
} else if (obj is Long) {
|
||||||
else throw IllegalStateException("Object is not a long!")
|
return obj
|
||||||
|
} else if (obj is Number) {
|
||||||
|
return obj.toLong()
|
||||||
|
} else {
|
||||||
|
throw IllegalStateException("Object is not a long!")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getLong(columnIndex: Int): Long {
|
override fun getLong(columnIndex: Int): Long {
|
||||||
@@ -536,12 +556,12 @@ class ScrollableResultSet(val parent: ResultSet) : ResultSet by parent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getClob(columnIndex: Int): Clob {
|
override fun getClob(columnIndex: Int): Clob {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getClob(columnLabel: String?): Clob {
|
override fun getClob(columnLabel: String?): Clob {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -594,12 +614,12 @@ class ScrollableResultSet(val parent: ResultSet) : ResultSet by parent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getArray(columnIndex: Int): Array {
|
override fun getArray(columnIndex: Int): Array {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getArray(columnLabel: String?): Array {
|
override fun getArray(columnLabel: String?): Array {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -678,32 +698,32 @@ class ScrollableResultSet(val parent: ResultSet) : ResultSet by parent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getTimestamp(columnIndex: Int): Timestamp {
|
override fun getTimestamp(columnIndex: Int): Timestamp {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTimestamp(columnLabel: String?): Timestamp {
|
override fun getTimestamp(columnLabel: String?): Timestamp {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTimestamp(columnIndex: Int, cal: Calendar?): Timestamp {
|
override fun getTimestamp(columnIndex: Int, cal: Calendar?): Timestamp {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTimestamp(columnLabel: String?, cal: Calendar?): Timestamp {
|
override fun getTimestamp(columnLabel: String?, cal: Calendar?): Timestamp {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getRef(columnIndex: Int): Ref {
|
override fun getRef(columnIndex: Int): Ref {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getRef(columnLabel: String?): Ref {
|
override fun getRef(columnLabel: String?): Ref {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -782,12 +802,12 @@ class ScrollableResultSet(val parent: ResultSet) : ResultSet by parent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getRowId(columnIndex: Int): RowId {
|
override fun getRowId(columnIndex: Int): RowId {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getRowId(columnLabel: String?): RowId {
|
override fun getRowId(columnLabel: String?): RowId {
|
||||||
//TODO Maybe?
|
// TODO Maybe?
|
||||||
notImplemented()
|
notImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -838,4 +858,4 @@ class ScrollableResultSet(val parent: ResultSet) : ResultSet by parent {
|
|||||||
class ResultSetEntry {
|
class ResultSetEntry {
|
||||||
val data = mutableListOf<Any?>()
|
val data = mutableListOf<Any?>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+177
@@ -0,0 +1,177 @@
|
|||||||
|
package xyz.nulldev.androidcompat.io.sharedprefs
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import com.russhwolf.settings.ExperimentalSettingsApi
|
||||||
|
import com.russhwolf.settings.ExperimentalSettingsImplementation
|
||||||
|
import com.russhwolf.settings.PreferencesSettings
|
||||||
|
import com.russhwolf.settings.serialization.decodeValue
|
||||||
|
import com.russhwolf.settings.serialization.decodeValueOrNull
|
||||||
|
import com.russhwolf.settings.serialization.encodeValue
|
||||||
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
|
import kotlinx.serialization.SerializationException
|
||||||
|
import kotlinx.serialization.builtins.SetSerializer
|
||||||
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
import java.util.prefs.PreferenceChangeListener
|
||||||
|
import java.util.prefs.Preferences
|
||||||
|
|
||||||
|
@OptIn(ExperimentalSettingsImplementation::class, ExperimentalSerializationApi::class, ExperimentalSettingsApi::class)
|
||||||
|
class JavaSharedPreferences(key: String) : SharedPreferences {
|
||||||
|
private val javaPreferences = Preferences.userRoot().node("suwayomi/tachidesk/$key")
|
||||||
|
private val preferences = PreferencesSettings(javaPreferences)
|
||||||
|
private val listeners = mutableMapOf<SharedPreferences.OnSharedPreferenceChangeListener, PreferenceChangeListener>()
|
||||||
|
|
||||||
|
// TODO: 2021-05-29 Need to find a way to get this working with all pref types
|
||||||
|
override fun getAll(): MutableMap<String, *> {
|
||||||
|
return preferences.keys.associateWith { preferences.getStringOrNull(it) }.toMutableMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getString(key: String, defValue: String?): String? {
|
||||||
|
return if (defValue != null) {
|
||||||
|
preferences.getString(key, defValue)
|
||||||
|
} else {
|
||||||
|
preferences.getStringOrNull(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStringSet(key: String, defValues: Set<String>?): Set<String>? {
|
||||||
|
try {
|
||||||
|
return if (defValues != null) {
|
||||||
|
preferences.decodeValue(SetSerializer(String.serializer()), key, defValues)
|
||||||
|
} else {
|
||||||
|
preferences.decodeValueOrNull(SetSerializer(String.serializer()), key)
|
||||||
|
}
|
||||||
|
} catch (e: SerializationException) {
|
||||||
|
throw ClassCastException("$key was not a StringSet")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getInt(key: String, defValue: Int): Int {
|
||||||
|
return preferences.getInt(key, defValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLong(key: String, defValue: Long): Long {
|
||||||
|
return preferences.getLong(key, defValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFloat(key: String, defValue: Float): Float {
|
||||||
|
return preferences.getFloat(key, defValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getBoolean(key: String, defValue: Boolean): Boolean {
|
||||||
|
return preferences.getBoolean(key, defValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun contains(key: String): Boolean {
|
||||||
|
return key in preferences.keys
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun edit(): SharedPreferences.Editor {
|
||||||
|
return Editor(preferences)
|
||||||
|
}
|
||||||
|
|
||||||
|
class Editor(private val preferences: PreferencesSettings) : SharedPreferences.Editor {
|
||||||
|
val itemsToAdd = mutableMapOf<String, Any>()
|
||||||
|
|
||||||
|
override fun putString(key: String, value: String?): SharedPreferences.Editor {
|
||||||
|
if (value != null) {
|
||||||
|
itemsToAdd[key] = value
|
||||||
|
} else {
|
||||||
|
remove(key)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun putStringSet(
|
||||||
|
key: String,
|
||||||
|
values: MutableSet<String>?
|
||||||
|
): SharedPreferences.Editor {
|
||||||
|
if (values != null) {
|
||||||
|
itemsToAdd[key] = values
|
||||||
|
} else {
|
||||||
|
remove(key)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun putInt(key: String, value: Int): SharedPreferences.Editor {
|
||||||
|
itemsToAdd[key] = value
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun putLong(key: String, value: Long): SharedPreferences.Editor {
|
||||||
|
itemsToAdd[key] = value
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun putFloat(key: String, value: Float): SharedPreferences.Editor {
|
||||||
|
itemsToAdd[key] = value
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun putBoolean(key: String, value: Boolean): SharedPreferences.Editor {
|
||||||
|
itemsToAdd[key] = value
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove(key: String): SharedPreferences.Editor {
|
||||||
|
itemsToAdd.remove(key)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun clear(): SharedPreferences.Editor {
|
||||||
|
itemsToAdd.clear()
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun commit(): Boolean {
|
||||||
|
addToPreferences()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun apply() {
|
||||||
|
addToPreferences()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addToPreferences() {
|
||||||
|
itemsToAdd.forEach { (key, value) ->
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
when (value) {
|
||||||
|
is Set<*> -> preferences.encodeValue(SetSerializer(String.serializer()), key, value as Set<String>)
|
||||||
|
is String -> preferences.putString(key, value)
|
||||||
|
is Int -> preferences.putInt(key, value)
|
||||||
|
is Long -> preferences.putLong(key, value)
|
||||||
|
is Float -> preferences.putFloat(key, value)
|
||||||
|
is Double -> preferences.putDouble(key, value)
|
||||||
|
is Boolean -> preferences.putBoolean(key, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun registerOnSharedPreferenceChangeListener(listener: SharedPreferences.OnSharedPreferenceChangeListener) {
|
||||||
|
val javaListener = PreferenceChangeListener {
|
||||||
|
listener.onSharedPreferenceChanged(this, it.key)
|
||||||
|
}
|
||||||
|
listeners[listener] = javaListener
|
||||||
|
javaPreferences.addPreferenceChangeListener(javaListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unregisterOnSharedPreferenceChangeListener(listener: SharedPreferences.OnSharedPreferenceChangeListener) {
|
||||||
|
val registeredListener = listeners.remove(listener)
|
||||||
|
if (registeredListener != null) {
|
||||||
|
javaPreferences.removePreferenceChangeListener(registeredListener)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteAll(): Boolean {
|
||||||
|
javaPreferences.removeNode()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -233,7 +233,7 @@ public class JsonSharedPreferences implements SharedPreferences {
|
|||||||
private JsonSharedPreferencesEditor() {
|
private JsonSharedPreferencesEditor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recordChange(String key) {
|
private void recordChange(String key) {
|
||||||
if (!affectedKeys.contains(key)) {
|
if (!affectedKeys.contains(key)) {
|
||||||
affectedKeys.add(key);
|
affectedKeys.add(key);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ import java.io.File
|
|||||||
import javax.imageio.ImageIO
|
import javax.imageio.ImageIO
|
||||||
import javax.xml.parsers.DocumentBuilderFactory
|
import javax.xml.parsers.DocumentBuilderFactory
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
data class InstalledPackage(val root: File) {
|
data class InstalledPackage(val root: File) {
|
||||||
val apk = File(root, "package.apk")
|
val apk = File(root, "package.apk")
|
||||||
val jar = File(root, "translated.jar")
|
val jar = File(root, "translated.jar")
|
||||||
@@ -40,20 +38,24 @@ data class InstalledPackage(val root: File) {
|
|||||||
}?.filter {
|
}?.filter {
|
||||||
it.tagName == "meta-data"
|
it.tagName == "meta-data"
|
||||||
}?.map {
|
}?.map {
|
||||||
putString(it.attributes.getNamedItem("android:name").nodeValue,
|
putString(
|
||||||
it.attributes.getNamedItem("android:value").nodeValue)
|
it.attributes.getNamedItem("android:name").nodeValue,
|
||||||
|
it.attributes.getNamedItem("android:value").nodeValue
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
it.signatures = (parsed.apkSingers.flatMap { it.certificateMetas }
|
it.signatures = (
|
||||||
/*+ parsed.apkV2Singers.flatMap { it.certificateMetas }*/) // Blocked by: https://github.com/hsiafan/apk-parser/issues/72
|
parsed.apkSingers.flatMap { it.certificateMetas }
|
||||||
.map { Signature(it.data) }.toTypedArray()
|
/*+ parsed.apkV2Singers.flatMap { it.certificateMetas }*/
|
||||||
|
) // Blocked by: https://github.com/hsiafan/apk-parser/issues/72
|
||||||
|
.map { Signature(it.data) }.toTypedArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun verify(): Boolean {
|
fun verify(): Boolean {
|
||||||
val res = ApkVerifier.Builder(apk)
|
val res = ApkVerifier.Builder(apk)
|
||||||
.build()
|
.build()
|
||||||
.verify()
|
.verify()
|
||||||
|
|
||||||
return res.isVerified
|
return res.isVerified
|
||||||
}
|
}
|
||||||
@@ -69,7 +71,7 @@ data class InstalledPackage(val root: File) {
|
|||||||
}.sortedByDescending { it.width * it.height }.firstOrNull() ?: return
|
}.sortedByDescending { it.width * it.height }.firstOrNull() ?: return
|
||||||
|
|
||||||
ImageIO.write(read, "png", icon)
|
ImageIO.write(read, "png", icon)
|
||||||
} catch(e: Exception) {
|
} catch (e: Exception) {
|
||||||
icon.delete()
|
icon.delete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,7 +79,7 @@ data class InstalledPackage(val root: File) {
|
|||||||
fun writeJar() {
|
fun writeJar() {
|
||||||
try {
|
try {
|
||||||
Dex2jar.from(apk).to(jar.toPath())
|
Dex2jar.from(apk).to(jar.toPath())
|
||||||
} catch(e: Exception) {
|
} catch (e: Exception) {
|
||||||
jar.delete()
|
jar.delete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,4 +94,4 @@ data class InstalledPackage(val root: File) {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class PackageController {
|
|||||||
if (!installed.jar.exists()) {
|
if (!installed.jar.exists()) {
|
||||||
throw IllegalStateException("Failed to translate APK dex!")
|
throw IllegalStateException("Failed to translate APK dex!")
|
||||||
}
|
}
|
||||||
} catch(t: Throwable) {
|
} catch (t: Throwable) {
|
||||||
root.deleteRecursively()
|
root.deleteRecursively()
|
||||||
throw t
|
throw t
|
||||||
}
|
}
|
||||||
@@ -63,7 +63,7 @@ class PackageController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun deletePackage(pack: InstalledPackage) {
|
fun deletePackage(pack: InstalledPackage) {
|
||||||
if(!pack.root.exists()) error("Package was never installed!")
|
if (!pack.root.exists()) error("Package was never installed!")
|
||||||
|
|
||||||
val packageName = pack.info.packageName
|
val packageName = pack.info.packageName
|
||||||
pack.root.deleteRecursively()
|
pack.root.deleteRecursively()
|
||||||
@@ -74,14 +74,15 @@ class PackageController {
|
|||||||
|
|
||||||
fun findPackage(packageName: String): InstalledPackage? {
|
fun findPackage(packageName: String): InstalledPackage? {
|
||||||
val file = File(androidFiles.packagesDir, packageName)
|
val file = File(androidFiles.packagesDir, packageName)
|
||||||
return if(file.exists())
|
return if (file.exists()) {
|
||||||
InstalledPackage(file)
|
InstalledPackage(file)
|
||||||
else
|
} else {
|
||||||
null
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findJarFromApk(apkFile: File): File? {
|
fun findJarFromApk(apkFile: File): File? {
|
||||||
val pkgName = ApkParsers.getMetaInfo(apkFile).packageName
|
val pkgName = ApkParsers.getMetaInfo(apkFile).packageName
|
||||||
return findPackage(pkgName)?.jar
|
return findPackage(pkgName)?.jar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,4 +24,4 @@ fun ApkMeta.toPackageInfo(apk: File): PackageInfo {
|
|||||||
sourceDir = apk.absolutePath
|
sourceDir = apk.absolutePath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+249
@@ -0,0 +1,249 @@
|
|||||||
|
package xyz.nulldev.androidcompat.replace.java.text;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import com.ibm.icu.text.DisplayContext;
|
||||||
|
import com.ibm.icu.util.Currency;
|
||||||
|
import com.ibm.icu.util.CurrencyAmount;
|
||||||
|
import com.ibm.icu.util.ULocale;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.text.AttributedCharacterIterator;
|
||||||
|
import java.text.FieldPosition;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.ParsePosition;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class NumberFormat extends java.text.NumberFormat {
|
||||||
|
private com.ibm.icu.text.NumberFormat delegate;
|
||||||
|
|
||||||
|
public NumberFormat(com.ibm.icu.text.NumberFormat delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuffer format(Object number, StringBuffer toAppendTo, FieldPosition pos) {
|
||||||
|
return delegate.format(number, toAppendTo, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String format(BigInteger number) {
|
||||||
|
return delegate.format(number);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String format(BigDecimal number) {
|
||||||
|
return delegate.format(number);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String format(com.ibm.icu.math.BigDecimal number) {
|
||||||
|
return delegate.format(number);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String format(CurrencyAmount currAmt) {
|
||||||
|
return delegate.format(currAmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) {
|
||||||
|
return delegate.format(number, toAppendTo, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) {
|
||||||
|
return delegate.format(number, toAppendTo, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuffer format(BigInteger number, StringBuffer toAppendTo, FieldPosition pos) {
|
||||||
|
return delegate.format(number, toAppendTo, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuffer format(BigDecimal number, StringBuffer toAppendTo, FieldPosition pos) {
|
||||||
|
return delegate.format(number, toAppendTo, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuffer format(com.ibm.icu.math.BigDecimal number, StringBuffer toAppendTo, FieldPosition pos) {
|
||||||
|
return delegate.format(number, toAppendTo, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuffer format(CurrencyAmount currAmt, StringBuffer toAppendTo, FieldPosition pos) {
|
||||||
|
return delegate.format(currAmt, toAppendTo, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Number parse(String text, ParsePosition parsePosition) {
|
||||||
|
return delegate.parse(text, parsePosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Number parse(String text) throws ParseException {
|
||||||
|
return delegate.parse(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CurrencyAmount parseCurrency(CharSequence text, ParsePosition pos) {
|
||||||
|
return delegate.parseCurrency(text, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isParseIntegerOnly() {
|
||||||
|
return delegate.isParseIntegerOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParseIntegerOnly(boolean value) {
|
||||||
|
delegate.setParseIntegerOnly(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParseStrict(boolean value) {
|
||||||
|
delegate.setParseStrict(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isParseStrict() {
|
||||||
|
return delegate.isParseStrict();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContext(DisplayContext context) {
|
||||||
|
delegate.setContext(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DisplayContext getContext(DisplayContext.Type type) {
|
||||||
|
return delegate.getContext(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static java.text.NumberFormat getInstance(Locale inLocale) {
|
||||||
|
return new NumberFormat(com.ibm.icu.text.NumberFormat.getInstance(inLocale));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.NumberFormat getInstance(ULocale inLocale) {
|
||||||
|
return com.ibm.icu.text.NumberFormat.getInstance(inLocale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.NumberFormat getInstance(int style) {
|
||||||
|
return com.ibm.icu.text.NumberFormat.getInstance(style);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.NumberFormat getInstance(Locale inLocale, int style) {
|
||||||
|
return com.ibm.icu.text.NumberFormat.getInstance(inLocale, style);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.NumberFormat getNumberInstance(ULocale inLocale) {
|
||||||
|
return com.ibm.icu.text.NumberFormat.getNumberInstance(inLocale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.NumberFormat getIntegerInstance(ULocale inLocale) {
|
||||||
|
return com.ibm.icu.text.NumberFormat.getIntegerInstance(inLocale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.NumberFormat getCurrencyInstance(ULocale inLocale) {
|
||||||
|
return com.ibm.icu.text.NumberFormat.getCurrencyInstance(inLocale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.NumberFormat getPercentInstance(ULocale inLocale) {
|
||||||
|
return com.ibm.icu.text.NumberFormat.getPercentInstance(inLocale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.NumberFormat getScientificInstance(ULocale inLocale) {
|
||||||
|
return com.ibm.icu.text.NumberFormat.getScientificInstance(inLocale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Locale[] getAvailableLocales() {
|
||||||
|
return com.ibm.icu.text.NumberFormat.getAvailableLocales();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ULocale[] getAvailableULocales() {
|
||||||
|
return com.ibm.icu.text.NumberFormat.getAvailableULocales();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object registerFactory(com.ibm.icu.text.NumberFormat.NumberFormatFactory factory) {
|
||||||
|
return com.ibm.icu.text.NumberFormat.registerFactory(factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean unregister(Object registryKey) {
|
||||||
|
return com.ibm.icu.text.NumberFormat.unregister(registryKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return delegate.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return delegate.equals(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object clone() {
|
||||||
|
return delegate.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGroupingUsed() {
|
||||||
|
return delegate.isGroupingUsed();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGroupingUsed(boolean newValue) {
|
||||||
|
delegate.setGroupingUsed(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaximumIntegerDigits() {
|
||||||
|
return delegate.getMaximumIntegerDigits();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaximumIntegerDigits(int newValue) {
|
||||||
|
delegate.setMaximumIntegerDigits(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinimumIntegerDigits() {
|
||||||
|
return delegate.getMinimumIntegerDigits();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMinimumIntegerDigits(int newValue) {
|
||||||
|
delegate.setMinimumIntegerDigits(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaximumFractionDigits() {
|
||||||
|
return delegate.getMaximumFractionDigits();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaximumFractionDigits(int newValue) {
|
||||||
|
delegate.setMaximumFractionDigits(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinimumFractionDigits() {
|
||||||
|
return delegate.getMinimumFractionDigits();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMinimumFractionDigits(int newValue) {
|
||||||
|
delegate.setMinimumFractionDigits(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrency(Currency theCurrency) {
|
||||||
|
delegate.setCurrency(theCurrency);
|
||||||
|
}
|
||||||
|
|
||||||
|
public java.util.Currency getCurrency() {
|
||||||
|
return java.util.Currency.getInstance(delegate.getCurrency().getCurrencyCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRoundingMode(int roundingMode) {
|
||||||
|
delegate.setRoundingMode(roundingMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.NumberFormat getInstance(ULocale desiredLocale, int choice) {
|
||||||
|
return com.ibm.icu.text.NumberFormat.getInstance(desiredLocale, choice);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public static String getPatternForStyle(ULocale forLocale, int choice) {
|
||||||
|
return com.ibm.icu.text.NumberFormat.getPatternForStyle(forLocale, choice);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ULocale getLocale(ULocale.Type type) {
|
||||||
|
return delegate.getLocale(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
|
||||||
|
return delegate.formatToCharacterIterator(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object parseObject(String source) throws ParseException {
|
||||||
|
return delegate.parseObject(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
+346
@@ -0,0 +1,346 @@
|
|||||||
|
package xyz.nulldev.androidcompat.replace.java.text;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import com.ibm.icu.text.DateFormatSymbols;
|
||||||
|
import com.ibm.icu.text.DisplayContext;
|
||||||
|
import com.ibm.icu.text.TimeZoneFormat;
|
||||||
|
import com.ibm.icu.util.ULocale;
|
||||||
|
import xyz.nulldev.androidcompat.replace.java.util.Calendar;
|
||||||
|
import xyz.nulldev.androidcompat.replace.java.util.TimeZone;
|
||||||
|
|
||||||
|
import java.text.*;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overridden to switch to Android implementation
|
||||||
|
*/
|
||||||
|
public class SimpleDateFormat extends java.text.DateFormat {
|
||||||
|
private com.ibm.icu.text.SimpleDateFormat delegate;
|
||||||
|
|
||||||
|
public SimpleDateFormat() {
|
||||||
|
delegate = new com.ibm.icu.text.SimpleDateFormat();
|
||||||
|
}
|
||||||
|
|
||||||
|
private SimpleDateFormat(com.ibm.icu.text.SimpleDateFormat delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleDateFormat(String pattern) {
|
||||||
|
delegate = new com.ibm.icu.text.SimpleDateFormat(pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleDateFormat(String pattern, Locale loc) {
|
||||||
|
delegate = new com.ibm.icu.text.SimpleDateFormat(pattern, loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleDateFormat(String pattern, ULocale loc) {
|
||||||
|
delegate = new com.ibm.icu.text.SimpleDateFormat(pattern, loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleDateFormat(String pattern, String override, ULocale loc) {
|
||||||
|
delegate = new com.ibm.icu.text.SimpleDateFormat(pattern, override, loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleDateFormat(String pattern, DateFormatSymbols formatData) {
|
||||||
|
delegate = new com.ibm.icu.text.SimpleDateFormat(pattern, formatData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleDateFormat(String pattern, DateFormatSymbols formatData, ULocale loc) {
|
||||||
|
delegate = new com.ibm.icu.text.SimpleDateFormat(pattern, formatData, loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public static SimpleDateFormat getInstance(com.ibm.icu.util.Calendar.FormatConfiguration formatConfig) {
|
||||||
|
return new SimpleDateFormat(com.ibm.icu.text.SimpleDateFormat.getInstance(formatConfig));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set2DigitYearStart(Date startDate) {
|
||||||
|
delegate.set2DigitYearStart(startDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date get2DigitYearStart() {
|
||||||
|
return delegate.get2DigitYearStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContext(DisplayContext context) {
|
||||||
|
delegate.setContext(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuffer format(com.ibm.icu.util.Calendar cal, StringBuffer toAppendTo, FieldPosition pos) {
|
||||||
|
return delegate.format(cal, toAppendTo, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNumberFormat(com.ibm.icu.text.NumberFormat newNumberFormat) {
|
||||||
|
delegate.setNumberFormat(newNumberFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void parse(String text, com.ibm.icu.util.Calendar cal, ParsePosition parsePos) {
|
||||||
|
delegate.parse(text, cal, parsePos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toPattern() {
|
||||||
|
return delegate.toPattern();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toLocalizedPattern() {
|
||||||
|
return delegate.toLocalizedPattern();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void applyPattern(String pat) {
|
||||||
|
delegate.applyPattern(pat);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void applyLocalizedPattern(String pat) {
|
||||||
|
delegate.applyLocalizedPattern(pat);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateFormatSymbols getDateFormatSymbols() {
|
||||||
|
return delegate.getDateFormatSymbols();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDateFormatSymbols(DateFormatSymbols newFormatSymbols) {
|
||||||
|
delegate.setDateFormatSymbols(newFormatSymbols);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeZoneFormat getTimeZoneFormat() {
|
||||||
|
return delegate.getTimeZoneFormat();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeZoneFormat(TimeZoneFormat tzfmt) {
|
||||||
|
delegate.setTimeZoneFormat(tzfmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object clone() {
|
||||||
|
return delegate.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return delegate.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return delegate.equals(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
|
||||||
|
return delegate.formatToCharacterIterator(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public StringBuffer intervalFormatByAlgorithm(com.ibm.icu.util.Calendar fromCalendar, com.ibm.icu.util.Calendar toCalendar, StringBuffer appendTo, FieldPosition pos) throws IllegalArgumentException {
|
||||||
|
return delegate.intervalFormatByAlgorithm(fromCalendar, toCalendar, appendTo, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNumberFormat(String fields, com.ibm.icu.text.NumberFormat overrideNF) {
|
||||||
|
delegate.setNumberFormat(fields, overrideNF);
|
||||||
|
}
|
||||||
|
|
||||||
|
public com.ibm.icu.text.NumberFormat getNumberFormat(char field) {
|
||||||
|
return delegate.getNumberFormat(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
|
||||||
|
return delegate.format(date, toAppendTo, fieldPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Date parse(String text) throws ParseException {
|
||||||
|
return delegate.parse(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Date parse(String text, ParsePosition pos) {
|
||||||
|
return delegate.parse(text, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object parseObject(String source, ParsePosition pos) {
|
||||||
|
return delegate.parseObject(source, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getTimeInstance(int style, ULocale locale) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getTimeInstance(style, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getDateInstance(int style, ULocale locale) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getDateInstance(style, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getDateTimeInstance(int dateStyle, int timeStyle, ULocale locale) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Locale[] getAvailableLocales() {
|
||||||
|
return com.ibm.icu.text.DateFormat.getAvailableLocales();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ULocale[] getAvailableULocales() {
|
||||||
|
return com.ibm.icu.text.DateFormat.getAvailableULocales();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCalendar(java.util.Calendar newCalendar) {
|
||||||
|
com.ibm.icu.util.Calendar cal = com.ibm.icu.util.Calendar.getInstance(com.ibm.icu.util.TimeZone.getTimeZone(newCalendar.getTimeZone().getID()));
|
||||||
|
cal.setTimeInMillis(newCalendar.getTimeInMillis());
|
||||||
|
delegate.setCalendar(cal);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.util.Calendar getCalendar() {
|
||||||
|
return new Calendar(delegate.getCalendar());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.text.NumberFormat getNumberFormat() {
|
||||||
|
return new NumberFormat(delegate.getNumberFormat());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTimeZone(java.util.TimeZone zone) {
|
||||||
|
delegate.setTimeZone(com.ibm.icu.util.TimeZone.getTimeZone(zone.getID()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.util.TimeZone getTimeZone() {
|
||||||
|
return new TimeZone(delegate.getTimeZone());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLenient(boolean lenient) {
|
||||||
|
delegate.setLenient(lenient);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLenient() {
|
||||||
|
return delegate.isLenient();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCalendarLenient(boolean lenient) {
|
||||||
|
delegate.setCalendarLenient(lenient);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCalendarLenient() {
|
||||||
|
return delegate.isCalendarLenient();
|
||||||
|
}
|
||||||
|
|
||||||
|
public com.ibm.icu.text.DateFormat setBooleanAttribute(com.ibm.icu.text.DateFormat.BooleanAttribute key, boolean value) {
|
||||||
|
return delegate.setBooleanAttribute(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getBooleanAttribute(com.ibm.icu.text.DateFormat.BooleanAttribute key) {
|
||||||
|
return delegate.getBooleanAttribute(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DisplayContext getContext(DisplayContext.Type type) {
|
||||||
|
return delegate.getContext(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getDateInstance(com.ibm.icu.util.Calendar cal, int dateStyle, Locale locale) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getDateInstance(cal, dateStyle, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getDateInstance(com.ibm.icu.util.Calendar cal, int dateStyle, ULocale locale) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getDateInstance(cal, dateStyle, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getTimeInstance(com.ibm.icu.util.Calendar cal, int timeStyle, Locale locale) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getTimeInstance(cal, timeStyle, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getTimeInstance(com.ibm.icu.util.Calendar cal, int timeStyle, ULocale locale) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getTimeInstance(cal, timeStyle, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getDateTimeInstance(com.ibm.icu.util.Calendar cal, int dateStyle, int timeStyle, Locale locale) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getDateTimeInstance(cal, dateStyle, timeStyle, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getDateTimeInstance(com.ibm.icu.util.Calendar cal, int dateStyle, int timeStyle, ULocale locale) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getDateTimeInstance(cal, dateStyle, timeStyle, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getInstance(com.ibm.icu.util.Calendar cal, Locale locale) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getInstance(cal, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getInstance(com.ibm.icu.util.Calendar cal, ULocale locale) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getInstance(cal, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getInstance(com.ibm.icu.util.Calendar cal) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getInstance(cal);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getDateInstance(com.ibm.icu.util.Calendar cal, int dateStyle) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getDateInstance(cal, dateStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getTimeInstance(com.ibm.icu.util.Calendar cal, int timeStyle) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getTimeInstance(cal, timeStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getDateTimeInstance(com.ibm.icu.util.Calendar cal, int dateStyle, int timeStyle) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getDateTimeInstance(cal, dateStyle, timeStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getInstanceForSkeleton(String skeleton) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getInstanceForSkeleton(skeleton);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getInstanceForSkeleton(String skeleton, Locale locale) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getInstanceForSkeleton(skeleton, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getInstanceForSkeleton(String skeleton, ULocale locale) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getInstanceForSkeleton(skeleton, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getInstanceForSkeleton(com.ibm.icu.util.Calendar cal, String skeleton, Locale locale) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getInstanceForSkeleton(cal, skeleton, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getInstanceForSkeleton(com.ibm.icu.util.Calendar cal, String skeleton, ULocale locale) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getInstanceForSkeleton(cal, skeleton, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getPatternInstance(String skeleton) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getPatternInstance(skeleton);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getPatternInstance(String skeleton, Locale locale) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getPatternInstance(skeleton, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getPatternInstance(String skeleton, ULocale locale) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getPatternInstance(skeleton, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getPatternInstance(com.ibm.icu.util.Calendar cal, String skeleton, Locale locale) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getPatternInstance(cal, skeleton, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.text.DateFormat getPatternInstance(com.ibm.icu.util.Calendar cal, String skeleton, ULocale locale) {
|
||||||
|
return com.ibm.icu.text.DateFormat.getPatternInstance(cal, skeleton, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ULocale getLocale(ULocale.Type type) {
|
||||||
|
return delegate.getLocale(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object parseObject(String source) throws ParseException {
|
||||||
|
return delegate.parseObject(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
+294
@@ -0,0 +1,294 @@
|
|||||||
|
package xyz.nulldev.androidcompat.replace.java.util;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import com.ibm.icu.text.DateFormat;
|
||||||
|
import com.ibm.icu.util.ULocale;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class Calendar extends java.util.Calendar {
|
||||||
|
private com.ibm.icu.util.Calendar delegate;
|
||||||
|
|
||||||
|
public Calendar(com.ibm.icu.util.Calendar delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static java.util.Calendar getInstance() {
|
||||||
|
return new Calendar(com.ibm.icu.util.Calendar.getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.util.Calendar getInstance(com.ibm.icu.util.TimeZone zone) {
|
||||||
|
return com.ibm.icu.util.Calendar.getInstance(zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static java.util.Calendar getInstance(Locale aLocale) {
|
||||||
|
return new Calendar(com.ibm.icu.util.Calendar.getInstance(aLocale));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.util.Calendar getInstance(ULocale locale) {
|
||||||
|
return com.ibm.icu.util.Calendar.getInstance(locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.util.Calendar getInstance(com.ibm.icu.util.TimeZone zone, Locale aLocale) {
|
||||||
|
return com.ibm.icu.util.Calendar.getInstance(zone, aLocale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.util.Calendar getInstance(com.ibm.icu.util.TimeZone zone, ULocale locale) {
|
||||||
|
return com.ibm.icu.util.Calendar.getInstance(zone, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Locale[] getAvailableLocales() {
|
||||||
|
return com.ibm.icu.util.Calendar.getAvailableLocales();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void computeTime() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void computeFields() {}
|
||||||
|
|
||||||
|
public static ULocale[] getAvailableULocales() {
|
||||||
|
return com.ibm.icu.util.Calendar.getAvailableULocales();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] getKeywordValuesForLocale(String key, ULocale locale, boolean commonlyUsed) {
|
||||||
|
return com.ibm.icu.util.Calendar.getKeywordValuesForLocale(key, locale, commonlyUsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getTimeInMillis() {
|
||||||
|
return delegate.getTimeInMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTimeInMillis(long millis) {
|
||||||
|
delegate.setTimeInMillis(millis);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public int getRelatedYear() {
|
||||||
|
return delegate.getRelatedYear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public void setRelatedYear(int year) {
|
||||||
|
delegate.setRelatedYear(year);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return delegate.equals(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEquivalentTo(com.ibm.icu.util.Calendar other) {
|
||||||
|
return delegate.isEquivalentTo(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return delegate.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean before(Object when) {
|
||||||
|
return delegate.before(when);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean after(Object when) {
|
||||||
|
return delegate.after(when);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getActualMaximum(int field) {
|
||||||
|
return delegate.getActualMaximum(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getActualMinimum(int field) {
|
||||||
|
return delegate.getActualMinimum(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void roll(int field, int amount) {
|
||||||
|
delegate.roll(field, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(int field, int amount) {
|
||||||
|
delegate.add(field, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void roll(int field, boolean up) {
|
||||||
|
roll(field, up ? 1 : -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisplayName(Locale loc) {
|
||||||
|
return delegate.getDisplayName(loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisplayName(ULocale loc) {
|
||||||
|
return delegate.getDisplayName(loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compareTo(com.ibm.icu.util.Calendar that) {
|
||||||
|
return delegate.compareTo(that);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateFormat getDateTimeFormat(int dateStyle, int timeStyle, Locale loc) {
|
||||||
|
return delegate.getDateTimeFormat(dateStyle, timeStyle, loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateFormat getDateTimeFormat(int dateStyle, int timeStyle, ULocale loc) {
|
||||||
|
return delegate.getDateTimeFormat(dateStyle, timeStyle, loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public static String getDateTimePattern(com.ibm.icu.util.Calendar cal, ULocale uLocale, int dateStyle) {
|
||||||
|
return com.ibm.icu.util.Calendar.getDateTimePattern(cal, uLocale, dateStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int fieldDifference(Date when, int field) {
|
||||||
|
return delegate.fieldDifference(when, field);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeZone(com.ibm.icu.util.TimeZone value) {
|
||||||
|
delegate.setTimeZone(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.util.TimeZone getTimeZone() {
|
||||||
|
return new TimeZone(delegate.getTimeZone());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLenient(boolean lenient) {
|
||||||
|
delegate.setLenient(lenient);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLenient() {
|
||||||
|
return delegate.isLenient();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRepeatedWallTimeOption(int option) {
|
||||||
|
delegate.setRepeatedWallTimeOption(option);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRepeatedWallTimeOption() {
|
||||||
|
return delegate.getRepeatedWallTimeOption();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSkippedWallTimeOption(int option) {
|
||||||
|
delegate.setSkippedWallTimeOption(option);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSkippedWallTimeOption() {
|
||||||
|
return delegate.getSkippedWallTimeOption();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFirstDayOfWeek(int value) {
|
||||||
|
delegate.setFirstDayOfWeek(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFirstDayOfWeek() {
|
||||||
|
return delegate.getFirstDayOfWeek();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMinimalDaysInFirstWeek(int value) {
|
||||||
|
delegate.setMinimalDaysInFirstWeek(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimalDaysInFirstWeek() {
|
||||||
|
return delegate.getMinimalDaysInFirstWeek();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimum(int field) {
|
||||||
|
return delegate.getMinimum(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaximum(int field) {
|
||||||
|
return delegate.getMaximum(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getGreatestMinimum(int field) {
|
||||||
|
return delegate.getGreatestMinimum(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLeastMaximum(int field) {
|
||||||
|
return delegate.getLeastMaximum(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public int getDayOfWeekType(int dayOfWeek) {
|
||||||
|
return delegate.getDayOfWeekType(dayOfWeek);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public int getWeekendTransition(int dayOfWeek) {
|
||||||
|
return delegate.getWeekendTransition(dayOfWeek);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isWeekend(Date date) {
|
||||||
|
return delegate.isWeekend(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isWeekend() {
|
||||||
|
return delegate.isWeekend();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object clone() {
|
||||||
|
return delegate.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return delegate.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.util.Calendar.WeekData getWeekDataForRegion(String region) {
|
||||||
|
return com.ibm.icu.util.Calendar.getWeekDataForRegion(region);
|
||||||
|
}
|
||||||
|
|
||||||
|
public com.ibm.icu.util.Calendar.WeekData getWeekData() {
|
||||||
|
return delegate.getWeekData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public com.ibm.icu.util.Calendar setWeekData(com.ibm.icu.util.Calendar.WeekData wdata) {
|
||||||
|
return delegate.setWeekData(wdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFieldCount() {
|
||||||
|
return delegate.getFieldCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return delegate.getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public boolean haveDefaultCentury() {
|
||||||
|
return delegate.haveDefaultCentury();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ULocale getLocale(ULocale.Type type) {
|
||||||
|
return delegate.getLocale(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
+196
@@ -0,0 +1,196 @@
|
|||||||
|
package xyz.nulldev.androidcompat.replace.java.util;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import com.ibm.icu.util.ULocale;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class TimeZone extends java.util.TimeZone {
|
||||||
|
private com.ibm.icu.util.TimeZone delegate;
|
||||||
|
|
||||||
|
public TimeZone(com.ibm.icu.util.TimeZone delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOffset(int era, int year, int month, int day, int dayOfWeek, int milliseconds) {
|
||||||
|
return delegate.getOffset(era, year, month, day, dayOfWeek, milliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOffset(long date) {
|
||||||
|
return delegate.getOffset(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getOffset(long date, boolean local, int[] offsets) {
|
||||||
|
delegate.getOffset(date, local, offsets);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRawOffset(int offsetMillis) {
|
||||||
|
delegate.setRawOffset(offsetMillis);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRawOffset() {
|
||||||
|
return delegate.getRawOffset();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getID() {
|
||||||
|
return delegate.getID();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setID(String ID) {
|
||||||
|
delegate.setID(ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisplayName(ULocale locale) {
|
||||||
|
return delegate.getDisplayName(locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDisplayName(boolean daylight, int style, Locale locale) {
|
||||||
|
return delegate.getDisplayName(daylight, style, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisplayName(boolean daylight, int style, ULocale locale) {
|
||||||
|
return delegate.getDisplayName(daylight, style, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDSTSavings() {
|
||||||
|
return delegate.getDSTSavings();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean useDaylightTime() {
|
||||||
|
return delegate.useDaylightTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean observesDaylightTime() {
|
||||||
|
return delegate.observesDaylightTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean inDaylightTime(Date date) {
|
||||||
|
return delegate.inDaylightTime(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static java.util.TimeZone getTimeZone(String ID) {
|
||||||
|
return new TimeZone(com.ibm.icu.util.TimeZone.getTimeZone(ID));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.util.TimeZone getFrozenTimeZone(String ID) {
|
||||||
|
return com.ibm.icu.util.TimeZone.getFrozenTimeZone(ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.ibm.icu.util.TimeZone getTimeZone(String ID, int type) {
|
||||||
|
return com.ibm.icu.util.TimeZone.getTimeZone(ID, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setDefaultTimeZoneType(int type) {
|
||||||
|
com.ibm.icu.util.TimeZone.setDefaultTimeZoneType(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getDefaultTimeZoneType() {
|
||||||
|
return com.ibm.icu.util.TimeZone.getDefaultTimeZoneType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Set<String> getAvailableIDs(com.ibm.icu.util.TimeZone.SystemTimeZoneType zoneType, String region, Integer rawOffset) {
|
||||||
|
return com.ibm.icu.util.TimeZone.getAvailableIDs(zoneType, region, rawOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] getAvailableIDs(int rawOffset) {
|
||||||
|
return com.ibm.icu.util.TimeZone.getAvailableIDs(rawOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] getAvailableIDs(String country) {
|
||||||
|
return com.ibm.icu.util.TimeZone.getAvailableIDs(country);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] getAvailableIDs() {
|
||||||
|
return com.ibm.icu.util.TimeZone.getAvailableIDs();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int countEquivalentIDs(String id) {
|
||||||
|
return com.ibm.icu.util.TimeZone.countEquivalentIDs(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getEquivalentID(String id, int index) {
|
||||||
|
return com.ibm.icu.util.TimeZone.getEquivalentID(id, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static java.util.TimeZone getDefault() {
|
||||||
|
return new TimeZone(com.ibm.icu.util.TimeZone.getDefault());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setDefault(com.ibm.icu.util.TimeZone tz) {
|
||||||
|
com.ibm.icu.util.TimeZone.setDefault(tz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasSameRules(com.ibm.icu.util.TimeZone other) {
|
||||||
|
return delegate.hasSameRules(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object clone() {
|
||||||
|
return delegate.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return delegate.equals(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return delegate.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getTZDataVersion() {
|
||||||
|
return com.ibm.icu.util.TimeZone.getTZDataVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getCanonicalID(String id) {
|
||||||
|
return com.ibm.icu.util.TimeZone.getCanonicalID(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getCanonicalID(String id, boolean[] isSystemID) {
|
||||||
|
return com.ibm.icu.util.TimeZone.getCanonicalID(id, isSystemID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getRegion(String id) {
|
||||||
|
return com.ibm.icu.util.TimeZone.getRegion(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getWindowsID(String id) {
|
||||||
|
return com.ibm.icu.util.TimeZone.getWindowsID(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getIDForWindowsID(String winid, String region) {
|
||||||
|
return com.ibm.icu.util.TimeZone.getIDForWindowsID(winid, region);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFrozen() {
|
||||||
|
return delegate.isFrozen();
|
||||||
|
}
|
||||||
|
|
||||||
|
public com.ibm.icu.util.TimeZone freeze() {
|
||||||
|
return delegate.freeze();
|
||||||
|
}
|
||||||
|
|
||||||
|
public com.ibm.icu.util.TimeZone cloneAsThawed() {
|
||||||
|
return delegate.cloneAsThawed();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,4 +24,4 @@ interface Resource {
|
|||||||
fun getType(): Class<out Resource>
|
fun getType(): Class<out Resource>
|
||||||
|
|
||||||
fun getValue(): Any?
|
fun getValue(): Any?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class ServiceSupport {
|
|||||||
|
|
||||||
private val logger = KotlinLogging.logger {}
|
private val logger = KotlinLogging.logger {}
|
||||||
|
|
||||||
fun startService(context: Context, intent: Intent) {
|
fun startService(@Suppress("UNUSED_PARAMETER") context: Context, intent: Intent) {
|
||||||
val name = intentToClassName(intent)
|
val name = intentToClassName(intent)
|
||||||
|
|
||||||
logger.debug { "Starting service: $name" }
|
logger.debug { "Starting service: $name" }
|
||||||
@@ -27,15 +27,15 @@ class ServiceSupport {
|
|||||||
|
|
||||||
runningServices[name] = service
|
runningServices[name] = service
|
||||||
|
|
||||||
//Setup service
|
// Setup service
|
||||||
thread {
|
thread {
|
||||||
callOnCreate(service)
|
callOnCreate(service)
|
||||||
//TODO Handle more complex cases
|
// TODO Handle more complex cases
|
||||||
service.onStartCommand(intent, 0, 0)
|
service.onStartCommand(intent, 0, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopService(context: Context, intent: Intent) {
|
fun stopService(@Suppress("UNUSED_PARAMETER") context: Context, intent: Intent) {
|
||||||
val name = intentToClassName(intent)
|
val name = intentToClassName(intent)
|
||||||
stopService(name)
|
stopService(name)
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ class ServiceSupport {
|
|||||||
fun stopService(name: String) {
|
fun stopService(name: String) {
|
||||||
logger.debug { "Stopping service: $name" }
|
logger.debug { "Stopping service: $name" }
|
||||||
val service = runningServices.remove(name)
|
val service = runningServices.remove(name)
|
||||||
if(service == null) {
|
if (service == null) {
|
||||||
logger.warn { "An attempt was made to stop a service that is not running: $name" }
|
logger.warn { "An attempt was made to stop a service that is not running: $name" }
|
||||||
} else {
|
} else {
|
||||||
thread {
|
thread {
|
||||||
@@ -63,6 +63,6 @@ class ServiceSupport {
|
|||||||
fun serviceInstanceFromClass(className: String): Service {
|
fun serviceInstanceFromClass(className: String): Service {
|
||||||
val clazzObj = Class.forName(className)
|
val clazzObj = Class.forName(className)
|
||||||
return clazzObj.getDeclaredConstructor().newInstance() as? Service
|
return clazzObj.getDeclaredConstructor().newInstance() as? Service
|
||||||
?: throw IllegalArgumentException("$className is not a Service!")
|
?: throw IllegalArgumentException("$className is not a Service!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,8 +25,9 @@ object KodeinGlobalHelper {
|
|||||||
* Get a dependency
|
* Get a dependency
|
||||||
*/
|
*/
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
fun <T : Any> instance(type: Class<T>, kodein: DI? = null): T {
|
fun <T : Any> instance(type: Class<T>, kodein: DI? = null): T {
|
||||||
return when(type) {
|
return when (type) {
|
||||||
AndroidFiles::class.java -> {
|
AndroidFiles::class.java -> {
|
||||||
val instance: AndroidFiles by (kodein ?: kodein()).instance()
|
val instance: AndroidFiles by (kodein ?: kodein()).instance()
|
||||||
instance as T
|
instance as T
|
||||||
@@ -63,5 +64,4 @@ object KodeinGlobalHelper {
|
|||||||
fun <T : Any> instance(type: Class<T>): T {
|
fun <T : Any> instance(type: Class<T>): T {
|
||||||
return instance(type, null)
|
return instance(type, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +1,12 @@
|
|||||||
|
# AndroidComapt Root dir
|
||||||
|
androidcompat.rootDir = androidcompat-root
|
||||||
|
|
||||||
# Allow/disallow preference changes (useful for demos)
|
####################### `android.files` (FilesConfigModule) #######################
|
||||||
ts.server.allowConfigChanges = true
|
|
||||||
|
|
||||||
# Enable the WebUI? Note: The API and multi-user sync server ui will remain available even if the WebUI is disabled
|
|
||||||
ts.server.enableWebUi = true
|
|
||||||
|
|
||||||
# 'true' to use the old, buggy/memory-leaking WebUI
|
|
||||||
ts.server.useOldWebUi = false
|
|
||||||
|
|
||||||
# 'true' to pretty print all JSON API responses
|
|
||||||
ts.server.prettyPrintApi = false
|
|
||||||
|
|
||||||
# List of blacklisted/whitelisted API endpoints/operation IDs
|
|
||||||
ts.server.disabledApiEndpoints = []
|
|
||||||
ts.server.enabledApiEndpoints = []
|
|
||||||
|
|
||||||
# Message to print in the console when the API has finished booting
|
|
||||||
ts.server.httpInitializedPrintMessage = ""
|
|
||||||
|
|
||||||
# Use external folder for static files
|
|
||||||
ts.server.useExternalStaticFiles = false
|
|
||||||
ts.server.externalStaticFilesFolder = ""
|
|
||||||
|
|
||||||
# Root storage dir
|
|
||||||
ts.server.rootDir = tachiserver-data
|
|
||||||
# Dir to store JVM patches
|
|
||||||
ts.server.patchesDir = ${ts.server.rootDir}/patches
|
|
||||||
|
|
||||||
# Storage dir for the emulated Android app
|
# Storage dir for the emulated Android app
|
||||||
android.files.rootDir = ${ts.server.rootDir}/android-compat/appdata
|
android.files.rootDir = ${androidcompat.rootDir}/appdata
|
||||||
# External storage dir for the emulated Android app's
|
# External storage dir for the emulated Android app's
|
||||||
android.files.externalStorageDir = ${ts.server.rootDir}/android-compat/extappdata
|
android.files.externalStorageDir = ${androidcompat.rootDir}/extappdata
|
||||||
|
|
||||||
# Internal Android directories
|
# Internal Android directories
|
||||||
android.files.dataDir = ${android.files.rootDir}/data
|
android.files.dataDir = ${android.files.rootDir}/data
|
||||||
@@ -48,37 +24,16 @@ android.files.externalCacheDirs = [${android.files.externalStorageDir}/cache]
|
|||||||
android.files.externalMediaDirs = [${android.files.externalStorageDir}/media]
|
android.files.externalMediaDirs = [${android.files.externalStorageDir}/media]
|
||||||
android.files.downloadCacheDir = ${android.files.externalStorageDir}/downloadCache
|
android.files.downloadCacheDir = ${android.files.externalStorageDir}/downloadCache
|
||||||
|
|
||||||
android.files.packageDir = ${ts.server.rootDir}/android-compat/packages
|
android.files.packageDir = ${androidcompat.rootDir}/android-compat/packages
|
||||||
|
|
||||||
|
####################### `android.app` (ApplicationInfoConfigModule) #######################
|
||||||
|
|
||||||
# Emulated Android app package name
|
# Emulated Android app package name
|
||||||
android.app.packageName = eu.kanade.tachiyomi
|
android.app.packageName = eu.kanade.tachiyomi
|
||||||
# Debug mode for the emulated Android app
|
# Debug mode for the emulated Android app
|
||||||
android.app.debug = true
|
android.app.debug = true
|
||||||
|
|
||||||
|
####################### `android.system` (SystemConfigModule) #######################
|
||||||
|
|
||||||
# Whether or not the emulated Android system is debuggable
|
# Whether or not the emulated Android system is debuggable
|
||||||
android.system.isDebuggable = true
|
android.system.isDebuggable = true
|
||||||
|
|
||||||
# Is the multi-user sync server enabled? Does not affect the single-user sync server included in the API.
|
|
||||||
ts.syncd.enable = false
|
|
||||||
|
|
||||||
# The URL of this server (displayed in the sync server web ui)
|
|
||||||
ts.syncd.baseUrl = "http://example.com"
|
|
||||||
|
|
||||||
# 'true' to disable the API and only enable the multi-user sync server
|
|
||||||
ts.syncd.syncOnlyMode = false
|
|
||||||
|
|
||||||
# The root directory to store synchronized data
|
|
||||||
ts.syncd.rootDir = ${ts.server.rootDir}/sync/accounts
|
|
||||||
|
|
||||||
# Location to store config files for the sandbox
|
|
||||||
ts.syncd.sandboxedConfig = ${ts.server.rootDir}/sync/sandboxed_config.config
|
|
||||||
|
|
||||||
# Recaptcha stuff for signup/login
|
|
||||||
ts.syncd.recaptcha.siteKey = ""
|
|
||||||
ts.syncd.recaptcha.secret = ""
|
|
||||||
|
|
||||||
# Sync server display name
|
|
||||||
ts.syncd.name = "Tachiyomi sync server"
|
|
||||||
|
|
||||||
# Header used to forward the IP to the multi-user sync server if the server is behind a reverse proxy
|
|
||||||
ts.syncd.ipHeader = ""
|
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# Server: v0.X.Y-next + WebUI: rXXX
|
||||||
|
## TL;DR
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
## Tachidesk-Server Changelog
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
## Tachidesk-WebUI Changelog
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
|
||||||
+654
@@ -0,0 +1,654 @@
|
|||||||
|
# Server: v0.6.6 + WebUI: r963
|
||||||
|
## TL;DR
|
||||||
|
- Batch actions for chapters
|
||||||
|
- Improved the downloader
|
||||||
|
- WebUI changes:
|
||||||
|
- Support for chapter actions
|
||||||
|
- a lot of code cleanup
|
||||||
|
- some bugfixes
|
||||||
|
|
||||||
|
## Tachidesk-Server Changelog
|
||||||
|
- (r1114) fix broken links (by @AriaMoradi)
|
||||||
|
- (r1115) fix more broken stuff (by @AriaMoradi)
|
||||||
|
- (r1116) fix more broken stuff (by @AriaMoradi)
|
||||||
|
- (r1117) fix more broken stuff (by @AriaMoradi)
|
||||||
|
- (r1118) Update winget.yml ([#393](https://github.com/Suwayomi/Tachidesk-Server/pull/393) by @vedantmgoyal2009)
|
||||||
|
- (r1119) fix jre path([#396](https://github.com/Suwayomi/Tachidesk-Server/pull/396) by @vedantmgoyal2009)
|
||||||
|
- (r1120) Fix deb package ([#397](https://github.com/Suwayomi/Tachidesk-Server/pull/397) by @mahor1221)
|
||||||
|
- (r1121) bump version (by @AriaMoradi)
|
||||||
|
- (r1122) Update Changelog (by @AriaMoradi)
|
||||||
|
- (r1123) Add libc++-dev ([#405](https://github.com/Suwayomi/Tachidesk-Server/pull/405) by @mahor1221)
|
||||||
|
- (r1124) Revert back to correct way of handling jre_dir ([#408](https://github.com/Suwayomi/Tachidesk-Server/pull/408) by @mahor1221)
|
||||||
|
- (r1125) Update winget.yml ([#410](https://github.com/Suwayomi/Tachidesk-Server/pull/410) by @vedantmgoyal2009)
|
||||||
|
- (r1126) Remove support for Sorayomi web interface ([#414](https://github.com/Suwayomi/Tachidesk-Server/pull/414) by @marcoebbinghaus)
|
||||||
|
- (r1127) Fix downloader memory leak ([#418](https://github.com/Suwayomi/Tachidesk-Server/pull/418) by @Syer10)
|
||||||
|
- (r1128) Documentation cleanup ([#417](https://github.com/Suwayomi/Tachidesk-Server/pull/417) by @Syer10)
|
||||||
|
- (r1129) Updater cleanup and improvements ([#416](https://github.com/Suwayomi/Tachidesk-Server/pull/416) by @Syer10)
|
||||||
|
- (r1130) replace quickjs with Mozilla Rhino ([#415](https://github.com/Suwayomi/Tachidesk-Server/pull/415) by @xhzhe)
|
||||||
|
- (r1131) ktlint (by @AriaMoradi)
|
||||||
|
- (r1132) move Tachiyomi's BuildConfig to kotlin dir (by @AriaMoradi)
|
||||||
|
- (r1133) remove BuildConfig as extensions now use AppInfo (by @AriaMoradi)
|
||||||
|
- (r1134) include list of mangas missing source in restore report ([#421](https://github.com/Suwayomi/Tachidesk-Server/pull/421) by @AriaMoradi)
|
||||||
|
- (r1135) Update dependencies ([#422](https://github.com/Suwayomi/Tachidesk-Server/pull/422) by @Syer10)
|
||||||
|
- (r1136) Lint ([#423](https://github.com/Suwayomi/Tachidesk-Server/pull/423) by @Syer10)
|
||||||
|
- (r1137) Fix: Error handling for popular/latest api if pageNum was supplied as zero ([#424](https://github.com/Suwayomi/Tachidesk-Server/pull/424) by @meta-boy)
|
||||||
|
- (r1138) Add cache control header to manga page response ([#430](https://github.com/Suwayomi/Tachidesk-Server/pull/430) by @martinek)
|
||||||
|
- (r1139) add MangaTable.lastFetchedAt and ChapterTable.chaptersLastFetchedAt ([#431](https://github.com/Suwayomi/Tachidesk-Server/pull/431) by @martinek)
|
||||||
|
- (r1140) Pre-load meta entries for all chapters for optimization ([#432](https://github.com/Suwayomi/Tachidesk-Server/pull/432) by @martinek)
|
||||||
|
- (r1141) POST variant for `/{sourceId}/search` endpoint ([#434](https://github.com/Suwayomi/Tachidesk-Server/pull/434) by @martinek)
|
||||||
|
- (r1142) Add request body to documentation ([#435](https://github.com/Suwayomi/Tachidesk-Server/pull/435) by @Syer10)
|
||||||
|
- (r1143) add batch download api ([#436](https://github.com/Suwayomi/Tachidesk-Server/pull/436) by @martinek)
|
||||||
|
- (r1144) Migrate to H2 v2 (by @AriaMoradi)
|
||||||
|
- (r1145) add category and global meta ([#438](https://github.com/Suwayomi/Tachidesk-Server/pull/438) by @AriaMoradi)
|
||||||
|
- (r1146) Revert H2 database to v1 (by @AriaMoradi)
|
||||||
|
- (r1147) refactor deprecated api (by @AriaMoradi)
|
||||||
|
- (r1148) Downloader Rewrite ([#437](https://github.com/Suwayomi/Tachidesk-Server/pull/437) by @Syer10)
|
||||||
|
- (r1149) Set source preference doc fix ([#441](https://github.com/Suwayomi/Tachidesk-Server/pull/441) by @Syer10)
|
||||||
|
- (r1150) Add batch chapter update endpoint ([#442](https://github.com/Suwayomi/Tachidesk-Server/pull/442) by @martinek)
|
||||||
|
- (r1151) changes needed for tachiyomi tracker (by @AriaMoradi)
|
||||||
|
- (r1152) Future proofing (by @AriaMoradi)
|
||||||
|
- (r1153) Fix settings/check-update endpoint ([#445](https://github.com/Suwayomi/Tachidesk-Server/pull/445) by @martinek)
|
||||||
|
- (r1154) Fix docs for /server/check-updates ([#447](https://github.com/Suwayomi/Tachidesk-Server/pull/447) by @martinek)
|
||||||
|
- (r1155) Batch editing and deleting any chapter ([#449](https://github.com/Suwayomi/Tachidesk-Server/pull/449) by @martinek)
|
||||||
|
- (r1156) make chapters endpoint more unifrom (by @AriaMoradi)
|
||||||
|
- (r1157) Add batch endpoint for removing downloads from download queue ([#452](https://github.com/Suwayomi/Tachidesk-Server/pull/452) by @martinek)
|
||||||
|
- (r1158) Download queue missing update fix ([#450](https://github.com/Suwayomi/Tachidesk-Server/pull/450) by @martinek)
|
||||||
|
|
||||||
|
## Tachidesk-WebUI Changelog
|
||||||
|
- (r947) Feature/swr for library screens ([#186](https://github.com/Suwayomi/Tachidesk-WebUI/pull/186) by @martinek)
|
||||||
|
- (r948) Feature/swr for simple queries ([#187](https://github.com/Suwayomi/Tachidesk-WebUI/pull/187) by @martinek)
|
||||||
|
- (r949) Check download queue for changes and reload chapters if any chapter download changes state. ([#189](https://github.com/Suwayomi/Tachidesk-WebUI/pull/189) by @martinek)
|
||||||
|
- (r950) Update typescript dependency ([#190](https://github.com/Suwayomi/Tachidesk-WebUI/pull/190) by @martinek)
|
||||||
|
- (r951) update browserlist (by @AriaMoradi)
|
||||||
|
- (r952) Feature/batch chapter download ([#191](https://github.com/Suwayomi/Tachidesk-WebUI/pull/191) by @martinek)
|
||||||
|
- (r953) Memoize empty view face so it does not change on rerender ([#193](https://github.com/Suwayomi/Tachidesk-WebUI/pull/193) by @martinek)
|
||||||
|
- (r954) Feature/batch chapter actions ([#194](https://github.com/Suwayomi/Tachidesk-WebUI/pull/194) by @martinek)
|
||||||
|
- (r955) Fix navbar back button behavior ([#195](https://github.com/Suwayomi/Tachidesk-WebUI/pull/195) by @martinek)
|
||||||
|
- (r956) Options panels refactoring ([#196](https://github.com/Suwayomi/Tachidesk-WebUI/pull/196) by @martinek)
|
||||||
|
- (r957) Refactor and fix sorting in library ([#197](https://github.com/Suwayomi/Tachidesk-WebUI/pull/197) by @martinek)
|
||||||
|
- (r958) Scroll window to top when PagedPager changes page ([#198](https://github.com/Suwayomi/Tachidesk-WebUI/pull/198) by @martinek)
|
||||||
|
- (r959) Verticall scroll navigation and fix ([#200](https://github.com/Suwayomi/Tachidesk-WebUI/pull/200) by @martinek)
|
||||||
|
- (r960) Hide overflowing text in reader title if text can't be wrapped ([#199](https://github.com/Suwayomi/Tachidesk-WebUI/pull/199) by @martinek)
|
||||||
|
- (r961) Add safezone to scroll end detection to prevent edge cases when scrolling to the end would not detect end ([#201](https://github.com/Suwayomi/Tachidesk-WebUI/pull/201) by @martinek)
|
||||||
|
- (r962) Refactor/download queue and cleanup visuals overall ([#202](https://github.com/Suwayomi/Tachidesk-WebUI/pull/202) by @martinek)
|
||||||
|
- (r963) Fix "back" pagination on double page layout in reader for spread pages ([#203](https://github.com/Suwayomi/Tachidesk-WebUI/pull/203) by @martinek)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Server: v0.6.5 + WebUI: r946
|
||||||
|
## TL;DR
|
||||||
|
- Fixed Windows bundler
|
||||||
|
|
||||||
|
## Tachidesk-Server Changelog
|
||||||
|
- (r1113) v0.6.4 (by @AriaMoradi)
|
||||||
|
- (r1114) fix broken links (by @AriaMoradi)
|
||||||
|
- (r1115) fix more broken stuff (by @AriaMoradi)
|
||||||
|
- (r1116) fix more broken stuff (by @AriaMoradi)
|
||||||
|
- (r1117) fix more broken stuff (by @AriaMoradi)
|
||||||
|
- (r1118) Update winget.yml ([#393](https://github.com/Suwayomi/Tachidesk-Server/pull/393) by @vedantmgoyal2009)
|
||||||
|
- (r1119) fix jre path([#396](https://github.com/Suwayomi/Tachidesk-Server/pull/396) by @voltrare)
|
||||||
|
- (r1120) Fix deb package ([#397](https://github.com/Suwayomi/Tachidesk-Server/pull/397) by @mahor1221)
|
||||||
|
- (r1121) bump version (by @AriaMoradi)
|
||||||
|
|
||||||
|
## Tachidesk-WebUI Changelog
|
||||||
|
- None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Server: v0.6.4 + WebUI: r946
|
||||||
|
## TL;DR
|
||||||
|
- No new major features
|
||||||
|
- Bug fixes and changes for packaging
|
||||||
|
- Documentation changes
|
||||||
|
|
||||||
|
## Tachidesk-Server Changelog
|
||||||
|
- (r1087) v0.6.3 (by @AriaMoradi)
|
||||||
|
- (r1088) Save categories when manga is unfavorited ([#335](https://github.com/Suwayomi/Tachidesk-Server/pull/335) by @Syer10)
|
||||||
|
- (r1089) handle solid RAR archives ([#339](https://github.com/Suwayomi/Tachidesk-Server/pull/339)) cfso100@gmail.com
|
||||||
|
- (r1090) add support for changing downloads dir ([#343](https://github.com/Suwayomi/Tachidesk-Server/pull/343) by @AriaMoradi)
|
||||||
|
- (r1091) fix Applications dir dependency ([#344](https://github.com/Suwayomi/Tachidesk-Server/pull/344) by @AriaMoradi)
|
||||||
|
- (r1092) add support for alternative web interfaces ([#342](https://github.com/Suwayomi/Tachidesk-Server/pull/342) by @AriaMoradi)
|
||||||
|
- (r1093) Add displayValues json field for select filter ([#347](https://github.com/Suwayomi/Tachidesk-Server/pull/347) by @Syer10)
|
||||||
|
- (r1094) document manga endpoints ([#348](https://github.com/Suwayomi/Tachidesk-Server/pull/348) by @Syer10)
|
||||||
|
- (r1095) add ChapterCount to manga object in categoryMangas endpoint ([#349](https://github.com/Suwayomi/Tachidesk-Server/pull/349) by @abhijeetChawla)
|
||||||
|
- (r1096) document all endpoints ([#350](https://github.com/Suwayomi/Tachidesk-Server/pull/350) by @Syer10)
|
||||||
|
- (r1097) fix copymanga ([#354](https://github.com/Suwayomi/Tachidesk-Server/pull/354) by @AriaMoradi)
|
||||||
|
- (r1098) fix formatting by kotlinter (by @AriaMoradi)
|
||||||
|
- (r1099) bump WebUI (by @AriaMoradi)
|
||||||
|
- (r1100) fix WebUI release name (by @AriaMoradi)
|
||||||
|
- (r1101) Fix documentation errors ([#358](https://github.com/Suwayomi/Tachidesk-Server/pull/358) by @Syer10)
|
||||||
|
- (r1102) Docs improvements ([#359](https://github.com/Suwayomi/Tachidesk-Server/pull/359) by @Syer10)
|
||||||
|
- (r1103) Add linux-all.tar.gz & systemd service ([#366](https://github.com/Suwayomi/Tachidesk-Server/pull/366) by @mahor1221)
|
||||||
|
- (r1104) Publish to Windows Package Managar (WinGet) ([#369](https://github.com/Suwayomi/Tachidesk-Server/pull/369) by @vedantmgoyal2009)
|
||||||
|
- (r1105) Refactor scripts ([#370](https://github.com/Suwayomi/Tachidesk-Server/pull/370) by @mahor1221)
|
||||||
|
- (r1106) Run workflow jobs toghether ([#371](https://github.com/Suwayomi/Tachidesk-Server/pull/371) by @mahor1221)
|
||||||
|
- (r1107) Update gradle action ([#372](https://github.com/Suwayomi/Tachidesk-Server/pull/372) by @mahor1221)
|
||||||
|
- (r1108) Improve DocumentationDsl, bugfix default values and add queryParams ([#378](https://github.com/Suwayomi/Tachidesk-Server/pull/378) by @Syer10)
|
||||||
|
- (r1109) Tidy up bundler script ([#380](https://github.com/Suwayomi/Tachidesk-Server/pull/380) by @mahor1221)
|
||||||
|
- (r1110) Replace linux-all with linux-assets ([#381](https://github.com/Suwayomi/Tachidesk-Server/pull/381) by @mahor1221)
|
||||||
|
- (r1111) Rename every instance of Tachidesk jar to Tachdidesk-Server.jar ([#384](https://github.com/Suwayomi/Tachidesk-Server/pull/384) by @AriaMoradi)
|
||||||
|
- (r1112) Fix mistakes from #384 ([#385](https://github.com/Suwayomi/Tachidesk-Server/pull/385) by @AriaMoradi)
|
||||||
|
|
||||||
|
## Tachidesk-WebUI Changelog
|
||||||
|
- (r943) fix default width ([#171](https://github.com/Suwayomi/Tachidesk-WebUI/pull/171) by @Robonau)
|
||||||
|
- (r944) added an update checker button for library ([#172](https://github.com/Suwayomi/Tachidesk-WebUI/pull/172) by @infix)
|
||||||
|
- (r945) fix download queue delete button ([#176](https://github.com/Suwayomi/Tachidesk-WebUI/pull/176) by @Kreach37)
|
||||||
|
- (r946) fix mangadex filters ([#177](https://github.com/Suwayomi/Tachidesk-WebUI/pull/177) by @Robonau)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Server: v0.6.3 + WebUI: r942
|
||||||
|
## TL;DR
|
||||||
|
- Changes in Server
|
||||||
|
- Support for array search filter changes list
|
||||||
|
- Support for Tachiyomi extensions lib 1.3
|
||||||
|
- Changes in WebUI
|
||||||
|
- Better search filter support
|
||||||
|
- Fluid manga grid
|
||||||
|
- Library comfortable grid
|
||||||
|
- Sources view layouts
|
||||||
|
- Various other changes...
|
||||||
|
|
||||||
|
## Tachidesk-Server Changelog
|
||||||
|
- (r1074) v0.6.2 (by @AriaMoradi)
|
||||||
|
- (r1075) support array filter changes ([#304](https://github.com/Suwayomi/Tachidesk-Server/pull/304) by @AriaMoradi)
|
||||||
|
- (r1076) fix filterlist bugs ([#306](https://github.com/Suwayomi/Tachidesk-Server/pull/306) by @AriaMoradi)
|
||||||
|
- (r1077) Update README.md ([#305](https://github.com/Suwayomi/Tachidesk-Server/pull/305) by @mahor1221)
|
||||||
|
- (r1078) fix meta update changing all keys ([#314](https://github.com/Suwayomi/Tachidesk-Server/pull/314) by @AriaMoradi)
|
||||||
|
- (r1079) add support for tachiyomi extensions Lib 1.3 ([#316](https://github.com/Suwayomi/Tachidesk-Server/pull/316) by @AriaMoradi)
|
||||||
|
- (r1080) Fix sources list of one source throws an exception ([#308](https://github.com/Suwayomi/Tachidesk-Server/pull/308) by @Syer10)
|
||||||
|
- (r1081) Improve source handling, fix errors with uninitialized mangas in broken sources ([#319](https://github.com/Suwayomi/Tachidesk-Server/pull/319) by @Syer10)
|
||||||
|
- (r1082) Add thumbnail support for stub sources ([#320](https://github.com/Suwayomi/Tachidesk-Server/pull/320) by @Syer10)
|
||||||
|
- (r1083) update description for Tachidesk-Sorayomi ([#326](https://github.com/Suwayomi/Tachidesk-Server/pull/326) by @DattatreyaReddy)
|
||||||
|
- (r1084) Add last bit of code needed for Extensions Lib 1.3 ([#330](https://github.com/Suwayomi/Tachidesk-Server/pull/330) by @Syer10)
|
||||||
|
- (r1085) Add QuickJS, replaces Duktape for Extensions Lib 1.3 ([#331](https://github.com/Suwayomi/Tachidesk-Server/pull/331) by @Syer10)
|
||||||
|
- (r1086) fix auth not actually blocking requests ([#333](https://github.com/Suwayomi/Tachidesk-Server/pull/333) by @AriaMoradi)
|
||||||
|
|
||||||
|
## Tachidesk-WebUI Changelog
|
||||||
|
- (r930) Source filter scroll fix (array of filters on submit [#149](https://github.com/Suwayomi/Tachidesk-WebUI/pull/149) by @Robonau)
|
||||||
|
- (r931) fix manga badges setting menu that turns the update/download badges on and off ([#150](https://github.com/Suwayomi/Tachidesk-WebUI/pull/150) by @Robonau)
|
||||||
|
- (r932) move sorts to copy tachiyomi ([#151](https://github.com/Suwayomi/Tachidesk-WebUI/pull/151) by @Robonau)
|
||||||
|
- (r933) add comfortable grid option ([#152](https://github.com/Suwayomi/Tachidesk-WebUI/pull/152) by @Robonau)
|
||||||
|
- (r934) source layouts ([#153](https://github.com/Suwayomi/Tachidesk-WebUI/pull/153) by @Robonau)
|
||||||
|
- (r935) List layout ([#154](https://github.com/Suwayomi/Tachidesk-WebUI/pull/154) by @Robonau)
|
||||||
|
- (r936) in library badge to manga in sources ([#156](https://github.com/Suwayomi/Tachidesk-WebUI/pull/156) by @Robonau)
|
||||||
|
- (r937) mass search ([#157](https://github.com/Suwayomi/Tachidesk-WebUI/pull/157) by @Robonau)
|
||||||
|
- (r938) 18+ tag on source/extension cards ([#160](https://github.com/Suwayomi/Tachidesk-WebUI/pull/160) by @Robonau)
|
||||||
|
- (r939) fix search source click ([#164](https://github.com/Suwayomi/Tachidesk-WebUI/pull/164) by @Robonau)
|
||||||
|
- (r940) items per row setting ([#165](https://github.com/Suwayomi/Tachidesk-WebUI/pull/165) by @Robonau)
|
||||||
|
- (r941) fix the grid width thing ([#169](https://github.com/Suwayomi/Tachidesk-WebUI/pull/169) by @Robonau)
|
||||||
|
- (r942) unified library options ([#168](https://github.com/Suwayomi/Tachidesk-WebUI/pull/168) by @infix)
|
||||||
|
|
||||||
|
# Server: v0.6.2 + WebUI: r929
|
||||||
|
## TL;DR
|
||||||
|
- Changes in WebUI
|
||||||
|
- Moved search to Browse
|
||||||
|
- Support for Source Filters
|
||||||
|
- Better visuals for Download Queue
|
||||||
|
- A live version of WebUI is now available [at this link](https://tachidesk-webui-preview.github.io/).
|
||||||
|
|
||||||
|
## Tachidesk-Server Changelog
|
||||||
|
- (r1073) Refactor debian-packager.sh, rename launcher scripts ([#303](https://github.com/Suwayomi/Tachidesk-Server/pull/303) by @mahor1221)
|
||||||
|
|
||||||
|
## Tachidesk-WebUI Changelog
|
||||||
|
- (r912) show locale date, less confusing ([#131](https://github.com/Suwayomi/Tachidesk-WebUI/pull/131) by @AriaMoradi)
|
||||||
|
- (r913) fix links to work on a bare host ([#132](https://github.com/Suwayomi/Tachidesk-WebUI/pull/132) by @AriaMoradi)
|
||||||
|
- (r914) fix direct links ([#133](https://github.com/Suwayomi/Tachidesk-WebUI/pull/133) by @AriaMoradi)
|
||||||
|
- (r915) deploy to github pages (by @AriaMoradi)
|
||||||
|
- (r916) fix typo (by @AriaMoradi)
|
||||||
|
- (r917) better naming (by @AriaMoradi)
|
||||||
|
- (r918) update notice about github pages (by @AriaMoradi)
|
||||||
|
- (r919) move text (by @AriaMoradi)
|
||||||
|
- (r920) make all links work by catching 404 (by @AriaMoradi)
|
||||||
|
- (r921) fix scrolling 8px ([#135](https://github.com/Suwayomi/Tachidesk-WebUI/pull/135) by @Robonau)
|
||||||
|
- (r922) sorting ([#136](https://github.com/Suwayomi/Tachidesk-WebUI/pull/136) by @Robonau)
|
||||||
|
- (r923) Close button fix ([#141](https://github.com/Suwayomi/Tachidesk-WebUI/pull/141)) z14942744@gmail.com
|
||||||
|
- (r924) add NavBarContextProvider ([#128](https://github.com/Suwayomi/Tachidesk-WebUI/pull/128) by @abhijeetChawla)
|
||||||
|
- (r925) Resolved Merged Conflicts ([#127](https://github.com/Suwayomi/Tachidesk-WebUI/pull/127) by @abhijeetChawla)
|
||||||
|
- (r926) more Download Queue info ([#138](https://github.com/Suwayomi/Tachidesk-WebUI/pull/138) by @Robonau)
|
||||||
|
- (r927) Source filters, move search to SourceMangas ([#142](https://github.com/Suwayomi/Tachidesk-WebUI/pull/142) by @Robonau)
|
||||||
|
- (r928) Source genre sorts design ([#147](https://github.com/Suwayomi/Tachidesk-WebUI/pull/147) by @Robonau)
|
||||||
|
- (r929) Update LibraryOptions.tsx ([#146](https://github.com/Suwayomi/Tachidesk-WebUI/pull/146) by @Robonau)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Server: v0.6.1 + WebUI: r911
|
||||||
|
## TL;DR
|
||||||
|
- msi and deb packages thanks to @mahor1221
|
||||||
|
- [Tachidesk-Flutter](https://github.com/Suwayomi/Tachidesk-Flutter) exists now!
|
||||||
|
|
||||||
|
## Tachidesk-Server Changelog
|
||||||
|
- (r1047) update (by @AriaMoradi)
|
||||||
|
- (r1048) bump version (by @AriaMoradi)
|
||||||
|
- (r1049) Update README.md (by @AriaMoradi)
|
||||||
|
- (r1050) Update README.md (by @AriaMoradi)
|
||||||
|
- (r1051) refactor getChapter ([#268](https://github.com/Suwayomi/Tachidesk-Server/pull/268) by @AriaMoradi)
|
||||||
|
- (r1052) Improve documentation with Http codes ([#261](https://github.com/Suwayomi/Tachidesk-Server/pull/261) by @Syer10)
|
||||||
|
- (r1053) Add Route to stop and reset the updater ([#260](https://github.com/Suwayomi/Tachidesk-Server/pull/260) by @ntbm)
|
||||||
|
- (r1054) ignore non image files ([#269](https://github.com/Suwayomi/Tachidesk-Server/pull/269) by @AriaMoradi)
|
||||||
|
- (r1055) fix compile erorr (by @AriaMoradi)
|
||||||
|
- (r1056) update dex2jar (by @AriaMoradi)
|
||||||
|
- (r1057) Update Gradle and Dependencies ([#281](https://github.com/Suwayomi/Tachidesk-Server/pull/281) by @Syer10)
|
||||||
|
- (r1058) Handlers must return a result ([#282](https://github.com/Suwayomi/Tachidesk-Server/pull/282) by @Syer10)
|
||||||
|
- (r1059) Allow app compilation on Java 18+ ([#286](https://github.com/Suwayomi/Tachidesk-Server/pull/286) by @Syer10)
|
||||||
|
- (r1060) Automated MSI package building ([#277](https://github.com/Suwayomi/Tachidesk-Server/pull/277) by @mahor1221)
|
||||||
|
- (r1061) Automated debian package building ([#287](https://github.com/Suwayomi/Tachidesk-Server/pull/287) by @mahor1221)
|
||||||
|
- (r1062) fix Debian package errors ([#288](https://github.com/Suwayomi/Tachidesk-Server/pull/288) by @mahor1221)
|
||||||
|
- (r1063) Fix build_push.yml Hopefully ([#289](https://github.com/Suwayomi/Tachidesk-Server/pull/289) by @mahor1221)
|
||||||
|
- (r1064) Improve windows-bundler.sh ([#290](https://github.com/Suwayomi/Tachidesk-Server/pull/290) by @mahor1221)
|
||||||
|
- (r1065) add Tachidesk-Flutter to readme ([#292](https://github.com/Suwayomi/Tachidesk-Server/pull/292)) @DattatreyaReddy)
|
||||||
|
- (r1066) no online fetch on backup ([#293](https://github.com/Suwayomi/Tachidesk-Server/pull/293) by @AriaMoradi)
|
||||||
|
- (r1067) auto-remove duplicate chapters ([#294](https://github.com/Suwayomi/Tachidesk-Server/pull/294) by @AriaMoradi)
|
||||||
|
- (r1068) remove gson ([#295](https://github.com/Suwayomi/Tachidesk-Server/pull/295) by @AriaMoradi)
|
||||||
|
|
||||||
|
## Tachidesk-WebUI Changelog
|
||||||
|
- (r894) migrate ReaderNavbar to Mui 5 ([#84](https://github.com/Suwayomi/Tachidesk-WebUI/pull/84) by @AriaMoradi)
|
||||||
|
- (r895) migrate SpinnerImage to Mui 5 ([#97](https://github.com/Suwayomi/Tachidesk-WebUI/pull/97) by @AriaMoradi)
|
||||||
|
- (r896) migrate VerticalPager to Mui 5 ([#94](https://github.com/Suwayomi/Tachidesk-WebUI/pull/94) by @AriaMoradi)
|
||||||
|
- (r897) migrate PagedPager to Mui 5 ([#93](https://github.com/Suwayomi/Tachidesk-WebUI/pull/93) by @AriaMoradi)
|
||||||
|
- (r898) MangaCard imges don't stretch now ([#110](https://github.com/Suwayomi/Tachidesk-WebUI/pull/110) by @abhijeetChawla)
|
||||||
|
- (r899) show correct title ([#111](https://github.com/Suwayomi/Tachidesk-WebUI/pull/111) by @AriaMoradi)
|
||||||
|
- (r900) migrate DoublePage to Mui 5 ([#88](https://github.com/Suwayomi/Tachidesk-WebUI/pull/88) by @AriaMoradi)
|
||||||
|
- (r901) migrate DoublePagedPager to Mui 5 ([#91](https://github.com/Suwayomi/Tachidesk-WebUI/pull/91) by @AriaMoradi)
|
||||||
|
- (r902) migrate Reader to Mui 5 ([#100](https://github.com/Suwayomi/Tachidesk-WebUI/pull/100) by @AriaMoradi)
|
||||||
|
- (r903) migrate HorizantalPager to Mui 5 ([#92](https://github.com/Suwayomi/Tachidesk-WebUI/pull/92) by @AriaMoradi)
|
||||||
|
- (r904) migrate PageNumber to Mui 5 ([#90](https://github.com/Suwayomi/Tachidesk-WebUI/pull/90) by @AriaMoradi)
|
||||||
|
- (r905) Chapter filter is woking ([#114](https://github.com/Suwayomi/Tachidesk-WebUI/pull/114) by @abhijeetChawla)
|
||||||
|
- (r906) added extension search ([#115](https://github.com/Suwayomi/Tachidesk-WebUI/pull/115) by @abhijeetChawla)
|
||||||
|
- (r907) cleanup ([#117](https://github.com/Suwayomi/Tachidesk-WebUI/pull/117) by @AriaMoradi)
|
||||||
|
- (r908) handle search shortcuts ([#116](https://github.com/Suwayomi/Tachidesk-WebUI/pull/116) by @AriaMoradi)
|
||||||
|
- (r909) Refactor for Removing unnecesary UseEffect ([#118](https://github.com/Suwayomi/Tachidesk-WebUI/pull/118) by @abhijeetChawla)
|
||||||
|
- (r910) refactor ChapterList ([#125](https://github.com/Suwayomi/Tachidesk-WebUI/pull/125) by @abhijeetChawla)
|
||||||
|
- (r911) refactor ChapterOptions ([#126](https://github.com/Suwayomi/Tachidesk-WebUI/pull/126) by @abhijeetChawla)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Server: v0.6.0 + WebUI: r893
|
||||||
|
## TL;DR
|
||||||
|
- WebUI design went through a whole lot of changes, including
|
||||||
|
- Got rid of hamburger menu, now we have a custom mobile navbar
|
||||||
|
- Unread and Download count badges
|
||||||
|
- Back button so better electron experience
|
||||||
|
- There's a whole lot more that I'm too lazy to explore.
|
||||||
|
- Completely removed anime support
|
||||||
|
- Fixed category reordering
|
||||||
|
- Added support for search filters(Server side only)
|
||||||
|
- Added support for updating library(Server side only)
|
||||||
|
- A bunch of API breaking changes(hence why bumping to v0.6.0)!
|
||||||
|
|
||||||
|
## Tachidesk-Server Changelog
|
||||||
|
- (r996) cleanup (by @AriaMoradi)
|
||||||
|
- (r999) better cleaning algorithm (by @AriaMoradi)
|
||||||
|
- (r1007) remove anime support (by @AriaMoradi)
|
||||||
|
- (r1009) Fix tests ([#226](https://github.com/Suwayomi/Tachidesk-Server/pull/226) by @ntbm)
|
||||||
|
- (r1010) Expose unread and download count of Manga in category api ([#227](https://github.com/Suwayomi/Tachidesk-Server/pull/227) by @ntbm)
|
||||||
|
- (r1011) add Cache Header to Thumbnail Response for improved library performance ([#228](https://github.com/Suwayomi/Tachidesk-Server/pull/228) by @ntbm)
|
||||||
|
- (r1013) Fix unread and download counts casing ([#230](https://github.com/Suwayomi/Tachidesk-Server/pull/230) by @Syer10)
|
||||||
|
- (r1014) Fix broken test ([#231](https://github.com/Suwayomi/Tachidesk-Server/pull/231) by @ntbm)
|
||||||
|
- (r1016) Fix category reorder Endpoint. Added Test for Category Reorder ([#232](https://github.com/Suwayomi/Tachidesk-Server/pull/232) by @ntbm)
|
||||||
|
- (r1017) change windows bundle names (by @AriaMoradi)
|
||||||
|
- (r1018) improve tests (by @AriaMoradi)
|
||||||
|
- (r1019) allow injecting Sources (by @AriaMoradi)
|
||||||
|
- (r1020) update (by @AriaMoradi)
|
||||||
|
- (r1021) fix credit (by @AriaMoradi)
|
||||||
|
- (r1022) cleanup (by @AriaMoradi)
|
||||||
|
- (r1023) refactor (by @AriaMoradi)
|
||||||
|
- (r1024) refactor (by @AriaMoradi)
|
||||||
|
- (r1025) implement Source Filters (by @AriaMoradi)
|
||||||
|
- (r1026) ignore build artifacts generated by teting (by @AriaMoradi)
|
||||||
|
- (r1027) convert request type (by @AriaMoradi)
|
||||||
|
- (r1028) Update CONTRIBUTING.md (by @AriaMoradi)
|
||||||
|
- (r1029) stop supporting zero based image storage ([#242](https://github.com/Suwayomi/src/pull/242) by @AriaMoradi)
|
||||||
|
- (r1030) add manga data to download queue object ([#244](https://github.com/Suwayomi/src/pull/244) by @AriaMoradi)
|
||||||
|
- (r1031) Fix Manga Meta, add Manga Meta test ([#245](https://github.com/Suwayomi/src/pull/245) by @Syer10)
|
||||||
|
- (r1032) add pagination to recentChapters ([#246](https://github.com/Suwayomi/src/pull/246) by @AriaMoradi)
|
||||||
|
- (r1033) update (by @AriaMoradi)
|
||||||
|
- (r1034) Implement Update of Library/Category ([#235](https://github.com/Suwayomi/src/pull/235) by @ntbm)
|
||||||
|
- (r1035) update (by @AriaMoradi)
|
||||||
|
- (r1036) Mention the existence of Mahor's Tachidesk-GTK (by @AriaMoradi)
|
||||||
|
- (r1037) Add a Kotlin DSL for endpoint documentation ([#249](https://github.com/Suwayomi/Tachidesk-Server/pull/249) by @Syer10)
|
||||||
|
- (r1038) update (by @AriaMoradi)
|
||||||
|
- (r1039) update (by @AriaMoradi)
|
||||||
|
- (r1040) cleanup directory names ([#251](https://github.com/Suwayomi/Tachidesk-Server/pull/251) by @AriaMoradi)
|
||||||
|
- (r1041) Fix first page not being detected correctly ([#253](https://github.com/Suwayomi/Tachidesk-Server/pull/253) by @AriaMoradi)
|
||||||
|
- (r1042) Update README.md (by @AriaMoradi)
|
||||||
|
- (r1043) Update README.md (by @AriaMoradi)
|
||||||
|
- (r1044) migrate application directories ([#255](https://github.com/Suwayomi/Tachidesk-Server/pull/255) by @AriaMoradi)
|
||||||
|
- (r1045) add support for MultiSelectListPreference ([#258](https://github.com/Suwayomi/Tachidesk-Server/pull/258) by @AriaMoradi)
|
||||||
|
- (r1046) empty searchTerm support ([#259](https://github.com/Suwayomi/Tachidesk-Server/pull/259) by @AriaMoradi)
|
||||||
|
|
||||||
|
|
||||||
|
## Tachidesk-WebUI
|
||||||
|
- (r821) add Permanent sidebar for desktop widths([#46](https://github.com/Suwayomi/Tachidesk-WebUI/pull/46) by @abhijeetChawla)
|
||||||
|
- (r822) Fix Local Source being missing (by @AriaMoradi)
|
||||||
|
- (r823) fix the ugliness of bare messages (by @AriaMoradi)
|
||||||
|
- (r824) add pull request template (by @AriaMoradi)
|
||||||
|
- (r825) add Unread badges ([#48](https://github.com/Suwayomi/Tachidesk-WebUI/pull/48) by @ntbm)
|
||||||
|
- (r826) Back button implementation ([#47](https://github.com/Suwayomi/Tachidesk-WebUI/pull/47) by @abhijeetChawla)
|
||||||
|
- (r827) remove redundant '/manga' prefix from paths (by @AriaMoradi)
|
||||||
|
- (r828) refactor (by @AriaMoradi)
|
||||||
|
- (r829) put Sources and Extensions in the same screen (by @AriaMoradi)
|
||||||
|
- (r830) Set Fallback Image for broken Thumbnails ([#50](https://github.com/Suwayomi/Tachidesk-WebUI/pull/50) by @ntbm)
|
||||||
|
- (r833) Apply Api changes for unread badges ([#52](https://github.com/Suwayomi/Tachidesk-WebUI/pull/52) by @ntbm)
|
||||||
|
- (r834) add EmptyView to DownloadQueue, refactro strings ([#53](https://github.com/Suwayomi/Tachidesk-WebUI/pull/53) by @abhijeetChawla)
|
||||||
|
- (r835) Bottom navbar for mobile ([#51](https://github.com/Suwayomi/Tachidesk-WebUI/pull/51) by @abhijeetChawla)
|
||||||
|
- (r836) Implement Unread Filter for Library ([#54](https://github.com/Suwayomi/Tachidesk-WebUI/pull/54) by @ntbm)
|
||||||
|
- (r837) fix navbar broken logic (by @AriaMoradi)
|
||||||
|
- (r838) fix navbar (by @AriaMoradi)
|
||||||
|
- (r839) refactor (by @AriaMoradi)
|
||||||
|
- (r840) refactor (by @AriaMoradi)
|
||||||
|
- (r841) refactor (by @AriaMoradi)
|
||||||
|
- (r842) show different NavbarItems depending on device width (by @AriaMoradi)
|
||||||
|
- (r843) remove text decoration (by @AriaMoradi)
|
||||||
|
- (r844) fancy icon based on if path selected (by @AriaMoradi)
|
||||||
|
- (r845) custom Extension icon, google's version is shit (by @AriaMoradi)
|
||||||
|
- (r846) refactor (by @AriaMoradi)
|
||||||
|
- (r848) move info (by @AriaMoradi)
|
||||||
|
- (r849) add Search to Library ([#55](https://github.com/Suwayomi/Tachidesk-WebUI/pull/55) by @ntbm)
|
||||||
|
- (r850) add aspect ratio to the manga card. ([#56](https://github.com/Suwayomi/Tachidesk-WebUI/pull/56) by @abhijeetChawla)
|
||||||
|
- (r851) better wording (by @AriaMoradi)
|
||||||
|
- (r852) reorder nav buttons (by @AriaMoradi)
|
||||||
|
- (r853) nicer gradient (by @AriaMoradi)
|
||||||
|
- (r854) refactor MangaCard (by @AriaMoradi)
|
||||||
|
- (r855) closes #58 (by @AriaMoradi
|
||||||
|
- (r856) Add Resume Reading FAB Manga screen ([#59](https://github.com/Suwayomi/Tachidesk-WebUI/pull/59) by @abhijeetChawla)
|
||||||
|
- (r857) add filter and badge for `downloadCount` ([#62](https://github.com/Suwayomi/Tachidesk-WebUI/pull/62) by @abhijeetChawla)
|
||||||
|
- (r858) add issue template (by @AriaMoradi)
|
||||||
|
- (r859) Change color of navbar in light mode ([#65](https://github.com/Suwayomi/Tachidesk-WebUI/pull/65) by @abhijeetChawla)
|
||||||
|
- (r860) fix manga FAB margins ([#66](https://github.com/Suwayomi/Tachidesk-WebUI/pull/66) by @AriaMoradi)
|
||||||
|
- (r861) remove extra scrollbar on mobile ([#67](https://github.com/Suwayomi/Tachidesk-WebUI/pull/67) by @AriaMoradi)
|
||||||
|
- (r862) Fix Bad messages in Library Appbar search ([#70](https://github.com/Suwayomi/Tachidesk-WebUI/pull/70) by @ntbm)
|
||||||
|
- (r863) ban the style prop (by @AriaMoradi)
|
||||||
|
- (r864) Updates pagination update ([#68](https://github.com/Suwayomi/Tachidesk-WebUI/pull/68) by @AriaMoradi)
|
||||||
|
- (r865) make the whole chapter card into a button ([#73](https://github.com/Suwayomi/Tachidesk-WebUI/pull/73) by @AriaMoradi)
|
||||||
|
- (r866) fix chapter actions not working if manga is not fetched online ([#74](https://github.com/Suwayomi/Tachidesk-WebUI/pull/74) by @AriaMoradi)
|
||||||
|
- (r867) migrate some components to Mui5 new styling system ([#72](https://github.com/Suwayomi/Tachidesk-WebUI/pull/72) by @abhijeetChawla)
|
||||||
|
- (r868) load first page on read manga ([#76](https://github.com/Suwayomi/Tachidesk-WebUI/pull/76) by @AriaMoradi)
|
||||||
|
- (r869) Revert "migrate some components to Mui5 new styling system ([#72](https://github.com/Suwayomi/Tachidesk-WebUI/pull/72))" (by @AriaMoradi)
|
||||||
|
- (r870) migrate Backup to Mui 5 ([#106](https://github.com/Suwayomi/Tachidesk-WebUI/pull/106) by @AriaMoradi)
|
||||||
|
- (r871) migrate EmptyView to Mui 5 ([#95](https://github.com/Suwayomi/Tachidesk-WebUI/pull/95) by @AriaMoradi)
|
||||||
|
- (r872) migrate CategorySelect to Mui 5 ([#85](https://github.com/Suwayomi/Tachidesk-WebUI/pull/85) by @AriaMoradi)
|
||||||
|
- (r873) migrate LibraryOptions to Mui 5 ([#83](https://github.com/Suwayomi/Tachidesk-WebUI/pull/83) by @AriaMoradi)
|
||||||
|
- (r874) migrate ChapterCard.tsx to Mui 5 ([#80](https://github.com/Suwayomi/Tachidesk-WebUI/pull/80) by @AriaMoradi)
|
||||||
|
- (r875) migrate App.tsx to Mui 5 ([#79](https://github.com/Suwayomi/Tachidesk-WebUI/pull/79) by @AriaMoradi)
|
||||||
|
- (r876) migrate SourceConfigure to Mui 5 ([#103](https://github.com/Suwayomi/Tachidesk-WebUI/pull/103) by @AriaMoradi)
|
||||||
|
- (r877) migrate Settings to Mui 5 ([#102](https://github.com/Suwayomi/Tachidesk-WebUI/pull/102) by @AriaMoradi)
|
||||||
|
- (r878) migrate Updates to Mui 5 ([#104](https://github.com/Suwayomi/Tachidesk-WebUI/pull/104) by @AriaMoradi)
|
||||||
|
- (r879) Save tabs number in Url to persist tab when go to other paths ([#78](https://github.com/Suwayomi/Tachidesk-WebUI/pull/78) by @abhijeetChawla)
|
||||||
|
- (r880) migrate LangSelect to Mui 5 ([#86](https://github.com/Suwayomi/Tachidesk-WebUI/pull/86) by @AriaMoradi)
|
||||||
|
- (r881) migrate ExtensionCard.tsx to Mui 5 ([#81](https://github.com/Suwayomi/Tachidesk-WebUI/pull/81) by @AriaMoradi)
|
||||||
|
- (r882) migrate SingleSearch to Mui 5 ([#101](https://github.com/Suwayomi/Tachidesk-WebUI/pull/101) by @AriaMoradi)
|
||||||
|
- (r883) migrate LoadingPlaceholder to Mui 5 ([#96](https://github.com/Suwayomi/Tachidesk-WebUI/pull/96) by @AriaMoradi)
|
||||||
|
- (r884) migrate About to Mui 5 ([#105](https://github.com/Suwayomi/Tachidesk-WebUI/pull/105) by @AriaMoradi)
|
||||||
|
- (r885) migrate SourceCard to Mui 5 ([#82](https://github.com/Suwayomi/Tachidesk-WebUI/pull/82) by @AriaMoradi)
|
||||||
|
- (r886) migrate Manga to Mui 5 ([#99](https://github.com/Suwayomi/Tachidesk-WebUI/pull/99) by @AriaMoradi)
|
||||||
|
- (r887) migrate Browse to Mui 5 ([#98](https://github.com/Suwayomi/Tachidesk-WebUI/pull/98) by @AriaMoradi)
|
||||||
|
- (r888) migrate DesktopSideBar to Mui 5 ([#87](https://github.com/Suwayomi/Tachidesk-WebUI/pull/87) by @AriaMoradi)
|
||||||
|
- (r889) cleanup library ([#107](https://github.com/Suwayomi/Tachidesk-WebUI/pull/107) by @AriaMoradi)
|
||||||
|
- (r890) support for new searchTerm (by @AriaMoradi)
|
||||||
|
- (r891) Revert "support for new searchTerm" (by @AriaMoradi)
|
||||||
|
- (r892) add support for emptySearch ([#109](https://github.com/Suwayomi/Tachidesk-WebUI/pull/109) by @AriaMoradi)
|
||||||
|
- (r893) add support for MultiSelectListPreference ([#108](https://github.com/Suwayomi/Tachidesk-WebUI/pull/108) by @AriaMoradi)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Server: v0.5.4 + WebUI: r820
|
||||||
|
## TL;DR
|
||||||
|
- Fixed ReadComicOnline, Toonily and possibly other sources not working
|
||||||
|
- Backup and Restore now includes Updates tab data
|
||||||
|
- Removed Anime support from WebUI, Anime support will also be removed from Tachidesk-Server in a future update
|
||||||
|
|
||||||
|
## Tachidesk-Server Changelog
|
||||||
|
- (r973) convert android.jar lib to a maven repo
|
||||||
|
- (r978) mimic Tachiyomi's behaviour more closely, fixes ReadComicOnline (EN)
|
||||||
|
- (r980) fix export chapter ordering, include new props in backup
|
||||||
|
- (r982) remove isNsfw annotation detection
|
||||||
|
- (r984) use correct time conversion units when doing backups
|
||||||
|
- (r989) Support using a CatalogueSource instead of only HttpSources ([#219](https://github.com/Suwayomi/Tachidesk-Server/pull/219) by @Syer10)
|
||||||
|
- (r991) Use a custom task to run electron ([#220](https://github.com/Suwayomi/Tachidesk-Server/pull/220) by @Syer10)
|
||||||
|
|
||||||
|
## Tachidesk-WebUI Changelog
|
||||||
|
- (r810) fix wrong strings in set Server Address dialog, fixes [#39](https://github.com/Suwayomi/Tachidesk-WebUI/issues/39)
|
||||||
|
- (r811) fix chapterFetch loop
|
||||||
|
- (r812) fix overlapping requests
|
||||||
|
- (r813) fix typo
|
||||||
|
- (r814) Better portrait support ([#41](https://github.com/Suwayomi/Tachidesk-WebUI/issues/41) by @minhe7735)
|
||||||
|
- (r815) fixes Reader navbar colors when in light mode ([#43](https://github.com/Suwayomi/Tachidesk-WebUI/issues/43) by @abhijeetChawla)
|
||||||
|
- (r816) default languages cleanup, force Local source enabled
|
||||||
|
- (r817) force Local source at LangSelect
|
||||||
|
- (r818) rename ExtensionLangSelect: generic name for generic use
|
||||||
|
- (r819) don't show anime anymore
|
||||||
|
- (r820) Remove Anime support
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Server: v0.5.3 + WebUI: r809
|
||||||
|
## TL;DR
|
||||||
|
- added support for a equivalent page to Tachiyomi's Updates tab
|
||||||
|
- fix launchers not working on macOS M1/arm64
|
||||||
|
|
||||||
|
## Tachidesk-Server Changelog
|
||||||
|
- (r956) fix macOS-arm64 bundle launchers not working
|
||||||
|
- (r957) Workaround StdLib issue and add KtLint to all modules ([#206](https://github.com/Suwayomi/Tachidesk-Server/pull/206) by @Syer10)
|
||||||
|
- (r960-r963) Add recently updated chapters(Updates) endpoint
|
||||||
|
|
||||||
|
|
||||||
|
## Tachidesk-WebUI Changelog
|
||||||
|
- (r808) fix chapter list not calling onlineFetch=true
|
||||||
|
- (r809) add support for Updates
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Server: v0.5.2 + WebUI: r807
|
||||||
|
## TL;DR
|
||||||
|
- Fixed Local source not working on Windows
|
||||||
|
- Fixed Chapter numbers being shown incorrectly
|
||||||
|
|
||||||
|
## Tachidesk-Server
|
||||||
|
### Public API
|
||||||
|
#### Non-breaking changes
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
#### Breaking changes
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
#### Bug fixes
|
||||||
|
- (r948) Fix ManaToki (KO) and NewToki (KO) (issue [#202](https://github.com/Suwayomi/Tachidesk-Server/issue/202))
|
||||||
|
- (r949) Local source: fix windows paths
|
||||||
|
|
||||||
|
### Private API
|
||||||
|
- (r941) Update BytecodeEditor to use Java NIO Paths ([#200](https://github.com/Suwayomi/Tachidesk-Server/pull/200) by @Syer10)
|
||||||
|
- (r942) Gradle Updates ([#199](https://github.com/Suwayomi/Tachidesk-Server/pull/199) by @Syer10)
|
||||||
|
|
||||||
|
|
||||||
|
## Tachidesk-WebUI
|
||||||
|
#### Visible changes
|
||||||
|
- (r804) update text positioning on Reader and Player ([#35](https://github.com/Suwayomi/Tachidesk-WebUI/pull/35) by @voltrare)
|
||||||
|
- (r806) Source card for Local source is different
|
||||||
|
- (r807) add Local source guide
|
||||||
|
|
||||||
|
#### Bug fixes
|
||||||
|
- (r805) fix chapter name
|
||||||
|
|
||||||
|
#### Internal changes
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Server: v0.5.1 + WebUI: r803
|
||||||
|
## TL;DR
|
||||||
|
- Loading sources' manga list is at least twice as fast
|
||||||
|
- Added support for Tachiyomi's Local source
|
||||||
|
- Added BasicAuth support, now you can protect your Tachidesk instance if you are running it on a public server
|
||||||
|
- Added ability to turn off cache for image requests
|
||||||
|
|
||||||
|
## Tachidesk-Server
|
||||||
|
### Public API
|
||||||
|
#### Non-breaking changes
|
||||||
|
- (r915) add BasicAuth support
|
||||||
|
- (r918) add ability to delete downloaded chapters
|
||||||
|
- (r923-r930) add Local Source
|
||||||
|
- (r938) add ability to turn off cache for image requests
|
||||||
|
|
||||||
|
#### Breaking changes
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
#### Bug fixes
|
||||||
|
- (r917) detect if a downloaded chapter is missing
|
||||||
|
|
||||||
|
### Private API
|
||||||
|
- (r913) remove expand char limit on MangaTable columns
|
||||||
|
- (r914) migrate to Javalin 4
|
||||||
|
- (r921) depricate zero based chapters
|
||||||
|
- (r937) add ChapterRecognition from tachiyomi, closes #10
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Tachidesk-WebUI
|
||||||
|
#### Visible changes
|
||||||
|
- (r790) nice looking progress percentage
|
||||||
|
- (r791) show a Delete button for downloaded chapters
|
||||||
|
- (r792) Update hover effect using more of Material-UI color pallete ([#29](https://github.com/Suwayomi/Tachidesk-WebUI/pull/29) by @voltrare)
|
||||||
|
- (r793) Optimize images ([#32](https://github.com/Suwayomi/Tachidesk-WebUI/pull/32) by @phanirithvij)
|
||||||
|
- (r794) try fix #30 ([#31](https://github.com/Suwayomi/Tachidesk-WebUI/pull/31) by @phanirithvij)
|
||||||
|
- (r795) fix viewing page number when the string is long
|
||||||
|
- (r796) show proper display name for source
|
||||||
|
- (r797) fail gracefully when a thumbnail has errors
|
||||||
|
- (r798) fix when a source fails to load mangas
|
||||||
|
- (r800) add Local source ([#31](https://github.com/Suwayomi/Tachidesk-WebUI/pull/31))
|
||||||
|
- (r803) add support for useCache
|
||||||
|
|
||||||
|
#### Bug fixes
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
#### Internal changes
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Server: v0.5.0 + WebUI: r789
|
||||||
|
## TL;DR
|
||||||
|
- You can now install APK extensions from the extensions page
|
||||||
|
- WebUI now comes with an updated Material Design looks and is faster a little bit.
|
||||||
|
- WebUI now shows Nsfw content by default, disable it in settings if you prefer to not see Nsfw stuff
|
||||||
|
- Added support for configuration of sources, this enables MangaDex, Komga, Cubari and many other sources
|
||||||
|
- Chapters in the Manga page and Sources in the source page now look nicer and will glow with mouse hover
|
||||||
|
|
||||||
|
## Tachidesk-Server
|
||||||
|
### Public API
|
||||||
|
#### Non-breaking changes
|
||||||
|
- (r888) add installing APK from external sources endpoint
|
||||||
|
|
||||||
|
#### Breaking changes
|
||||||
|
- (r877 [#188](https://github.com/Suwayomi/Tachidesk-Server/pull/188) by @Syer10) `MangaDataClass.genre` changed type to `List<String>`
|
||||||
|
|
||||||
|
#### Bug fixes
|
||||||
|
- (r899-r901) fix when an external apk is installed and it doesn't have the default tachiyomi-extensions name
|
||||||
|
- (r905) fix a bug where if two sources return the same URL, a false duplicate might be detected
|
||||||
|
|
||||||
|
### Private API
|
||||||
|
- (r887) the `run` task won't call `downloadWebUI` now
|
||||||
|
- (r902) cleanup print/ln instances
|
||||||
|
- (r906) better handling of uninstalling Extensions
|
||||||
|
|
||||||
|
## Tachidesk-WebUI
|
||||||
|
#### Visible changes
|
||||||
|
- (r770) add support for the new genre type
|
||||||
|
- (r771) set the default value of `showNsfw` to `true` so we won't have visual artifacts with a clean install
|
||||||
|
- (r774 [#21](https://github.com/Suwayomi/Tachidesk-WebUI/pull/21) by @voltrare) `ReaderNavbar.jsx`: Swap close and retract Navbar buttons
|
||||||
|
- (r775 [#23](https://github.com/Suwayomi/Tachidesk-WebUI/pull/23) by @voltrare) `yarn.lock`: Fixes version inconsistency after commit 9b866811b
|
||||||
|
- (r776 [#23](https://github.com/Suwayomi/Tachidesk-WebUI/pull/23) by @voltrare) add margin between Source and Extension cards, make the Search button look nicer
|
||||||
|
- (r777) add support for installing external APK files
|
||||||
|
- (r778) fix the makeToaster?
|
||||||
|
- (r779) Action button for installing external extension
|
||||||
|
- (r780 Suwayomi/Tachidesk-WebUI#25) add on hover, active effect to Chapter/Episode card
|
||||||
|
- (r782-r785) updating material-ui to v5 changed the theme
|
||||||
|
- (r785-r788) better `SourceCard` looks on mobile, move `SourceDataClass.isConfigurable` gear button to `SourceMangas`
|
||||||
|
- (r789) implement source configuration
|
||||||
|
|
||||||
|
#### Bug fixes
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
#### Internal changes
|
||||||
|
- (r782-r785) update dependencies, migrate material-ui from v4 to v5
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Server: v0.4.9 + WebUI: r769
|
||||||
|
## Tachidesk-Server
|
||||||
|
### Public API
|
||||||
|
#### Non-breaking changes
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
#### Breaking changes
|
||||||
|
- (r857) renamed: `SourceDataClass.isNSFW` -> `SourceDataClass.isNsfw`
|
||||||
|
|
||||||
|
#### Bug fixes
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
### Private API
|
||||||
|
- (r850) Bump WebUI version to r767
|
||||||
|
- (r861) Bump WebUI version to r769
|
||||||
|
|
||||||
|
#### Non-code changes
|
||||||
|
- (r851) Add this changelog file and `CHANGELOG-TEMPLATE.md`
|
||||||
|
- (r852-r853) `CONTRIBUTING.md`: Add a note about this maintaining this file changelog
|
||||||
|
- (r855) `CONTRIBUTING.md`: text cleanup
|
||||||
|
- (r859) `CONTRIBUTING.md`: remove dumb rule
|
||||||
|
- (r862) `windows-bundler.sh`: update jre
|
||||||
|
- (r864) add linux and macOS bundler script and launcher scripts
|
||||||
|
- (r865) fix macOS bundler script and launcher scripts
|
||||||
|
- (r866) bump electron version to v14.0.0
|
||||||
|
- (r868) add linux and macOS bundlers to the publish workflow
|
||||||
|
- (r871) `publish.yml`: remove node module cache, won't need it anymore
|
||||||
|
- (r873) `publish.yml` and `build_push.yml`: fix oopsies
|
||||||
|
|
||||||
|
|
||||||
|
## Tachidesk-WebUI
|
||||||
|
#### Visible changes
|
||||||
|
- (r767-r769) Support for hiding NSFW content in settings screen, extensions screen, sources screen
|
||||||
|
|
||||||
|
#### Bug fixes
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
#### Internal changes
|
||||||
|
- (r767) Remove some duplicate dependency declaration from `package.json`
|
||||||
|
|
||||||
|
#### Non-code changes
|
||||||
|
- (r42-r45) Change `README.md`: some links and stuff
|
||||||
|
- (r45-r765) Add all of the commit history from when WebUI was separated from Server, jumping from r45 to r765 (r45 is exactly the same as r765)
|
||||||
|
- (r766) Steal `.gitattributes` from Tachidesk-Server
|
||||||
|
- (r767) Dependency cleanup in `package.json`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Server: v0.4.8 + WebUI: r41
|
||||||
|
## Tachidesk-Server
|
||||||
|
### Public API
|
||||||
|
#### Non-breaking changes
|
||||||
|
- Added support for serializing Search Filters
|
||||||
|
- `SourceDataClass` now has a `isNsfw` key
|
||||||
|
|
||||||
|
#### Breaking changes
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
#### Bug fixes
|
||||||
|
- Fixed a bug where backup restore reversed chapter order
|
||||||
|
- Open Site feature now works properly (https://github.com/Suwayomi/Tachidesk-WebUI/issues/19)
|
||||||
|
|
||||||
|
### Private API
|
||||||
|
- Added `CloudflareInterceptor` from TachiWeb-Server
|
||||||
|
- Restoring backup for mangas in library(merging manga data) is now supported
|
||||||
|
|
||||||
|
## Tachidesk-WebUI
|
||||||
|
#### Visible changes
|
||||||
|
- Better looking manga card titles
|
||||||
|
- Better reader title, next, prev buttons
|
||||||
|
|
||||||
|
#### Bug fixes
|
||||||
|
- Open Site feature now works properly (https://github.com/Suwayomi/Tachidesk-WebUI/issues/19)
|
||||||
|
- Re-ordering categories now works
|
||||||
|
|
||||||
|
#### Internal changes
|
||||||
|
- N/A
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Code Of Conduct
|
||||||
|
- Don't be a dick.
|
||||||
|
|
||||||
|
# expanding the code of conduct!
|
||||||
|
The contents of this document is up for debate and improvement! Discussions on discord.
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
# Contributing
|
||||||
|
## Where should I start?
|
||||||
|
Checkout [This Kanban Board](https://github.com/Suwayomi/Tachidesk/projects/1) to see the rough development roadmap.
|
||||||
|
|
||||||
|
**Note 1:** Notify the developers on [Suwayomi discord](https://discord.gg/DDZdqZWaHA) (#tachidesk-server and #tachidesk-webui channels) or open a WIP pull request before starting if you decide to take on working on anything from/not from the roadmap in order to avoid parallel efforts on the same issue/feature.
|
||||||
|
|
||||||
|
**Note 2:** Your pull request will be squashed into a single commit.
|
||||||
|
|
||||||
|
### Project goals and vision
|
||||||
|
- Porting Tachiyomi and covering it's features
|
||||||
|
- Syncing with Tachiyomi, [main issue](https://github.com/Suwayomi/Tachidesk-Server/issues/159)
|
||||||
|
- Generally rejecting features that Tachiyomi(main app) doesn't have,
|
||||||
|
- Unless it's something that makes sense for desktop sizes or desktop form factor (keyboard + mouse)
|
||||||
|
- Additional/crazy features can go in forks and alternative clients
|
||||||
|
- [Tachidesk-WebUI](https://github.com/Suwayomi/Tachidesk-WebUI) should
|
||||||
|
- be responsive
|
||||||
|
- support both desktop and mobile form factors well
|
||||||
|
|
||||||
|
## How does Tachidesk-Server work?
|
||||||
|
This project has two components:
|
||||||
|
1. **Server:** contains the implementation of [tachiyomi's extensions library](https://github.com/tachiyomiorg/extensions-lib) and uses an Android compatibility library to run jar libraries converted from apk extensions. All this concludes to serving a REST API.
|
||||||
|
2. **WebUI:** A React SPA(`create-react-app`) project that works with the server to do the presentation located at https://github.com/Suwayomi/Tachidesk-WebUI
|
||||||
|
|
||||||
|
## Why a web app?
|
||||||
|
This structure is chosen to
|
||||||
|
- Achieve the maximum multi-platform-ness
|
||||||
|
- Gives the ability to access Tachidesk-Server from a remote client e.g., your phone, tablet or smart TV
|
||||||
|
- Ease development of user interfaces for Tachidesk
|
||||||
|
|
||||||
|
## Building from source
|
||||||
|
### Prerequisites
|
||||||
|
You need these software packages installed in order to build the project
|
||||||
|
|
||||||
|
- Java Development Kit and Java Runtime Environment version 8 or newer(both Oracle JDK and OpenJDK works)
|
||||||
|
|
||||||
|
### building the full-blown jar (Tachidesk-Server + Tachidesk-WebUI bundle)
|
||||||
|
Run `./gradlew server:downloadWebUI server:shadowJar`, the resulting built jar file will be `server/build/Tachidesk-Server-vX.Y.Z-rxxx.jar`.
|
||||||
|
|
||||||
|
### building without `webUI` bundled (server only)
|
||||||
|
Delete `server/src/main/resources/WebUI.zip` if exists from previous runs, then run `./gradlew server:shadowJar`, the resulting built jar file will be `server/build/Tachidesk-Server-vX.Y.Z-rxxx.jar`.
|
||||||
|
|
||||||
|
### building the Windows package
|
||||||
|
First Build the jar, then cd into the `scripts` directory and run `./windows-bundler.sh win32` or `./windows-bundler.sh win64` depending on the target architecture, the resulting built zip package file will be `server/build/Tachidesk-Server-vX.Y.Z-rxxx-winXX.zip`.
|
||||||
|
|
||||||
|
## Running in development mode
|
||||||
|
run `./gradlew :server:run --stacktrace` to run the server
|
||||||
|
|
||||||
|
## Running tests
|
||||||
|
run `./gradlew :server:test` to execute all tests
|
||||||
|
to test a specific class run `./gradlew :server:test --tests <package.with.classname>`
|
||||||
|
|
||||||
|
## Building the android-jar maven repository
|
||||||
|
Run `AndroidCompat/getAndroid.sh`(macOS/Linux) or `AndroidCompat/getAndroid.ps1`(Windows)
|
||||||
|
from project's root directory to download and rebuild the jar file from Google's repository,
|
||||||
|
then use `AndroidCompat/lib/android.jar` to manually create a maven repository inside the `android-jar` git branch.
|
||||||
|
Update the dependency declaration afterwards.
|
||||||
@@ -1,108 +1,170 @@
|
|||||||
|
|
||||||
| Build | Stable | Preview | Support Server |
|
| Build | Stable | Preview | Support Server |
|
||||||
|-------|----------|---------|---------|
|
|-------|----------|---------|---------|
|
||||||
|  | [](https://github.com/Suwayomi/Tachidesk/releases) | [](https://github.com/Suwayomi/Tachidesk/tree/preview/latest_pointer) | [](https://discord.gg/DDZdqZWaHA) |
|
|  | [](https://github.com/Suwayomi/Tachidesk/releases) | [](https://github.com/Suwayomi/Tachidesk-preview/releases/latest) | [](https://discord.gg/DDZdqZWaHA) |
|
||||||
|
|
||||||
# Tachidesk
|
## Table of Content
|
||||||
|
- [What is Tachidesk?](#what-is-tachidesk)
|
||||||
|
- [Tachidesk client projects](#tachidesk-client-projects)
|
||||||
|
* [Is this application usable? Should I test it?](#is-this-application-usable-should-i-test-it)
|
||||||
|
- [Downloading and Running the app](#downloading-and-running-the-app)
|
||||||
|
* [Using Operating System Specific Bundles](#using-operating-system-specific-bundles)
|
||||||
|
- [Launcher Scripts](#launcher-scripts)
|
||||||
|
+ [Windows](#windows)
|
||||||
|
+ [macOS](#macos)
|
||||||
|
+ [GNU/Linux](#gnulinux)
|
||||||
|
* [Other methods of getting Tachidesk](#other-methods-of-getting-tachidesk)
|
||||||
|
+ [Arch Linux](#arch-linux)
|
||||||
|
+ [Ubuntu-based distributions](#ubuntu-based-distributions)
|
||||||
|
+ [Docker](#docker)
|
||||||
|
* [Advanced Methods](#advanced-methods)
|
||||||
|
+ [Running the jar release directly](#running-the-jar-release-directly)
|
||||||
|
+ [Using Tachidesk Remotely](#using-tachidesk-remotely)
|
||||||
|
- [Syncing With Tachiyomi](#syncing-with-tachiyomi)
|
||||||
|
- [Troubleshooting and Support](#troubleshooting-and-support)
|
||||||
|
- [Contributing and Technical info](#contributing-and-technical-info)
|
||||||
|
- [Credit](#credit)
|
||||||
|
- [License](#license)
|
||||||
|
<!-- Generated with https://ecotrust-canada.github.io/markdown-toc/ -->
|
||||||
|
|
||||||
|
# What is Tachidesk?
|
||||||
<img src="https://github.com/Suwayomi/Tachidesk/raw/master/server/src/main/resources/icon/faviconlogo.png" alt="drawing" width="200"/>
|
<img src="https://github.com/Suwayomi/Tachidesk/raw/master/server/src/main/resources/icon/faviconlogo.png" alt="drawing" width="200"/>
|
||||||
|
|
||||||
A free and open source manga reader that runs extensions built for [Tachiyomi](https://tachiyomi.org/).
|
A free and open source manga reader server that runs extensions built for [Tachiyomi](https://tachiyomi.org/).
|
||||||
|
|
||||||
Tachidesk is an independent Tachiyomi compatible software made by [@AriaMoradi AKA ArMor](https://github.com/AriaMoradi) and contributors and is **not a Fork of** Tachiyomi.
|
Tachidesk is an independent Tachiyomi compatible software and is **not a Fork of** Tachiyomi.
|
||||||
|
|
||||||
Tachidesk is as multi-platform as you can get. Any platform that runs java and/or has a modern browser can run it.
|
Tachidesk-Server is as multi-platform as you can get. Any platform that runs java and/or has a modern browser can run it. This includes Windows, Linux, macOS, chrome OS, etc. Follow [Downloading and Running the app](#downloading-and-running-the-app) for installation instructions.
|
||||||
|
|
||||||
Ability to read and write Tachiyomi compatible backups and syncing is a planned feature.
|
Ability to sync with Tachiyomi is a planned feature, for more info look [here](#syncing-with-tachiyomi).
|
||||||
|
|
||||||
|
# Tachidesk client projects
|
||||||
|
**You need a client/user interface app as a front-end for Tachidesk-Server, if you [Directly Download Tachidesk-Server](https://github.com/Suwayomi/Tachidesk-Server/releases/latest) you'll get a bundled version of [Tachidesk-WebUI](https://github.com/Suwayomi/Tachidesk-WebUI) with it.**
|
||||||
|
|
||||||
|
Here's a list of known clients/user interfaces for Tachidesk-Server:
|
||||||
|
##### Actively Developed Cients
|
||||||
|
- [Tachidesk-WebUI](https://github.com/Suwayomi/Tachidesk-WebUI): The web/ElectronJS front-end that Tachidesk-Server ships with by default.
|
||||||
|
- [Tachidesk-JUI](https://github.com/Suwayomi/Tachidesk-JUI): The native desktop front-end for Tachidesk-Server. Currently the most advanced.
|
||||||
|
- [Tachidesk-qtui](https://github.com/Suwayomi/Tachidesk-qtui): A C++/Qt front-end for mobile devices(Android/linux), feature support is basic.
|
||||||
|
- [Tachidesk-Sorayomi](https://github.com/Suwayomi/Tachidesk-Sorayomi): A Flutter front-end for Desktop(Linux, windows, etc.), Web and Android with a User Inerface inspired by Tachiyomi.
|
||||||
|
##### Inctive/Abandoned Cients
|
||||||
|
- [Equinox](https://github.com/Suwayomi/Equinox): A web user interface made with Vue.js.
|
||||||
|
- [Tachidesk-GTK](https://github.com/mahor1221/Tachidesk-GTK): A native Rust/GTK desktop client.
|
||||||
|
|
||||||
## Is this application usable? Should I test it?
|
## Is this application usable? Should I test it?
|
||||||
Here is a list of current features:
|
Here is a list of current features:
|
||||||
|
|
||||||
- Installing and executing Tachiyomi's Extensions, So you'll get the same sources.
|
- Installing and executing Tachiyomi's Extensions, So you'll get the same sources
|
||||||
- A library to save your mangas and categories to put them into.
|
- A library to save your mangas and categories to put them into
|
||||||
- Searching and browsing installed sources.
|
- Searching and browsing installed sources
|
||||||
- A decent chapter reader.
|
- Ability to download Manga for offline read
|
||||||
- Ability to download Mangas for offline read(This partially works)
|
- Backup and restore support powered by Tachiyomi-compatible Backups
|
||||||
- Backup and restore support powered by Tachiyomi Legacy Backups
|
- Viewing latest updated chapters.
|
||||||
|
|
||||||
**Note:** Keep in mind that Tachidesk is alpha software and can break rarely and/or with each update, so you may have to delete your data to fix it. See [General troubleshooting](#general-troubleshooting) and [Support and help](#support-and-help) if it happens.
|
**Note:** These are capabilities of Tachidesk-Server, the actual working support is provided by each front-end app, checkout their respective readme for more info.
|
||||||
|
|
||||||
Anyways, for more info checkout [finished milestone #1](https://github.com/Suwayomi/Tachidesk/issues/2) and [milestone #2](https://github.com/Suwayomi/Tachidesk/projects/1) to see what's implemented in more detail.
|
# Downloading and Running the app
|
||||||
|
## Using Operating System Specific Bundles
|
||||||
|
To facilitate the use of Tachidesk we provide bundle releases that include The Java Runtime Environment, ElectronJS and 3 Tachidesk Launcher Scripts.
|
||||||
|
|
||||||
## Downloading and Running the app
|
If a bundle for your operating system or cpu architecture is not provided then refer to [Advanced Methods](#advanced-methods)
|
||||||
### All Operating Systems
|
|
||||||
You should have The Java Runtime Environment(JRE) 8 or newer and a modern browser installed. Also an internet connection is required as almost everything this app does is downloading stuff.
|
|
||||||
|
|
||||||
Download the latest "Stable" jar release from [the releases section](https://github.com/Suwayomi/Tachidesk/releases) or a preview jar build from [the preview branch](https://github.com/Suwayomi/Tachidesk/tree/preview).
|
#### Launcher Scripts
|
||||||
|
- `Tachidesk Electron Launcher`: Launches Tachidesk inside Electron as a desktop applicaton
|
||||||
|
- `Tachidesk Browser Launcher`: Launches Tachidesk in a browser window
|
||||||
|
- `Tachidesk Debug Launcher`: Launches Tachidesk with debug logs attached. If Tachidesk doesn't work for you, running this can give you insight into why.
|
||||||
|
|
||||||
Double click on the jar file or run `java -jar Tachidesk-vX.Y.Z-rxxx.jar` (or `java -jar Tachidesk-latest.jar` if you have the latest preview) from a Terminal/Command Prompt window to run the app which will open a new browser window automatically. Also the System Tray Icon is your friend if you need to open the browser window again or close Tachidesk.
|
**Node:** Linux launcher scripts are named a bit differently but work the same.
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
Download the latest win32 release from [the releases section](https://github.com/Suwayomi/Tachidesk/releases).
|
Download the latest `win32`(Windows 32-bit) or `win64`(Windows 64-bit) release from [the releases section](https://github.com/Suwayomi/Tachidesk-Server/releases) or a preview one from [the preview repository](https://github.com/Suwayomi/Tachidesk-Server-preview/releases).
|
||||||
|
|
||||||
The Windows specific build has java bundled inside, so you don't have to install java to use it. Unzip `Tachidesk-vX.Y.Z-rxxx-win32.zip` and run `server.exe`. The rest works like the previous section.
|
Unzip the downloaded file and double click on one of the launcher scripts.
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
Download the latest `macOS-x64`(older macOS systems) or `macOS-arm64`(Apple M1 and newer) release from [the releases section](https://github.com/Suwayomi/Tachidesk-Server/releases) or a preview one from [the preview repository](https://github.com/Suwayomi/Tachidesk-Server-preview/releases).
|
||||||
|
|
||||||
|
Unzip the downloaded file and double click on one of the launcher scripts.
|
||||||
|
|
||||||
|
### GNU/Linux
|
||||||
|
Download the latest `linux-x64`(x86_64) release from [the releases section](https://github.com/Suwayomi/Tachidesk-Server/releases) or a preview one from [the preview repository](https://github.com/Suwayomi/Tachidesk-Server-preview/releases).
|
||||||
|
|
||||||
|
`tar xvf` the downloaded file and double click on one of the launcher scripts or run them using the terminal.
|
||||||
|
|
||||||
|
## Other methods of getting Tachidesk
|
||||||
### Arch Linux
|
### Arch Linux
|
||||||
You can install Tachidesk from the AUR
|
You can install Tachidesk from the AUR:
|
||||||
```
|
```
|
||||||
yay -S tachidesk
|
yay -S tachidesk
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Debian/Ubuntu
|
||||||
|
Download the latest deb package from the release section or Install from the MPR
|
||||||
|
```
|
||||||
|
git clone https://mpr.makedeb.org/tachidesk-server.git
|
||||||
|
cd tachidesk-server
|
||||||
|
makedeb -si
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ubuntu
|
||||||
|
```
|
||||||
|
sudo add-apt-repository ppa:suwayomi/tachidesk-server
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install tachidesk-server
|
||||||
|
```
|
||||||
|
|
||||||
### Docker
|
### Docker
|
||||||
Check [arbuilder's repo](https://github.com/arbuilder/Tachidesk-docker) out for more details and the dockerfile.
|
Check our Official Docker release [Tachidesk Container](https://github.com/orgs/Suwayomi/packages/container/package/tachidesk) for running Tachidesk Server in a docker container. Source code for our container is available at [docker-tachidesk](https://github.com/Suwayomi/docker-tachidesk). By default the server will be running on http://localhost:4567 open this url in your browser.
|
||||||
|
|
||||||
## General troubleshooting
|
Install from the command line:
|
||||||
If the app breaks, make sure that it's not running(right click on tray icon and quit or kill it through the way your Operating System provides), delete the directory below and re-run the app (**This procedure will delete all your data!**) and if the problem persists open an issue or ask for help on discord.
|
```
|
||||||
|
$ docker pull ghcr.io/suwayomi/tachidesk
|
||||||
|
```
|
||||||
|
Run Container from the command line:
|
||||||
|
```
|
||||||
|
$ docker run -p 4567:4567 ghcr.io/suwayomi/tachidesk
|
||||||
|
```
|
||||||
|
|
||||||
On Mac OS X : `/Users/<Account>/Library/Application Support/Tachidesk`
|
## Advanced Methods
|
||||||
|
### Running the jar release directly
|
||||||
|
In order to run the app you need the following:
|
||||||
|
- The jar release of Tachidesk-Server
|
||||||
|
- The Java Runtime Environment(JRE) 8 or newer
|
||||||
|
- A Browser like Google Chrome, Firefox, Edge, etc.
|
||||||
|
- ElectronJS (optional)
|
||||||
|
|
||||||
On Windows XP : `C:\Documents and Settings\<Account>\Application Data\Local Settings\Tachidesk`
|
Download the latest `.jar` release from [the releases section](https://github.com/Suwayomi/Tachidesk-Server/releases) or a preview jar build from [the preview repository](https://github.com/Suwayomi/Tachidesk-preview/releases).
|
||||||
|
|
||||||
On Windows 7 and later : `C:\Users\<Account>\AppData\Local\Tachidesk`
|
Make sure you have The Java Runtime Environment installed on your system, Double click on the jar file or run `java -jar Tachidesk-vX.Y.Z-rxxxx.jar` from a Terminal/Command Prompt window to run the app which will open a new browser window automatically.
|
||||||
|
|
||||||
On Unix/Linux : `/home/<account>/.local/share/Tachidesk`
|
### Using Tachidesk Remotely
|
||||||
|
You can run Tachidesk on your computer or a server and connect to it remotely through one of our clients or the bundled web interface with a web browser. This method of using Tachidesk is requires a bit of networking/firewall/port forwarding/server configuration/etc. knowledge on your side, if you can run a Minecraft server and configure it, then you are good to go.
|
||||||
|
|
||||||
## Support and help
|
Check out [this wiki page](https://github.com/Suwayomi/Tachidesk-Server/wiki/Configuring-Tachidesk-Server) for a guide on configuring Tachidesk-Server.
|
||||||
Join Tachidesk's [discord server](https://discord.gg/DDZdqZWaHA) to hang out with the community and to receive support and help.
|
|
||||||
|
|
||||||
## How does it work?
|
If you face issues with your setup then we are happy to provide help, just join our discord server(a discord badge is on the top of the page, you are just a click clack away!).
|
||||||
This project has two components:
|
|
||||||
1. **server:** contains the implementation of [tachiyomi's extensions library](https://github.com/tachiyomiorg/extensions-lib) and uses an Android compatibility library to run apk extensions. All this concludes to serving a REST API to `webUI`.
|
|
||||||
2. **webUI:** A react SPA project that works with the server to do the presentation.
|
|
||||||
|
|
||||||
## Building from source
|
## Syncing With Tachiyomi
|
||||||
### Prerequisite: Get Android stubs jar
|
### The Tachidesk extension
|
||||||
#### Manual download
|
- You can install the `Tachidesk` extension inside tachiyomi.
|
||||||
Download [android.jar](https://raw.githubusercontent.com/Suwayomi/Tachidesk/android-jar/android.jar) and put it under `AndroidCompat/lib`.
|
- The extension will load Tachidesk library.
|
||||||
#### Automated download
|
- By manipulating filters you can browse your categories.
|
||||||
Run `AndroidCompat/getAndroid.sh`(MacOS/Linux) or `AndroidCompat/getAndroid.ps1`(Windows) from project's root directory to download and rebuild the jar file from Google's repository.
|
|
||||||
### Prerequisite: Software dependencies
|
### Other methods
|
||||||
You need this software packages installed in order to build this project:
|
Checkout [this issue](https://github.com/Suwayomi/Tachidesk-Server/issues/159) for tracking progress.
|
||||||
- Java Development Kit and Java Runtime Environment version 8 or newer(both Oracle JDK and OpenJDK works)
|
|
||||||
- Nodejs LTS or latest
|
## Troubleshooting and Support
|
||||||
- Yarn
|
See [this troubleshooting wiki page](https://github.com/Suwayomi/Tachidesk/wiki/Troubleshooting).
|
||||||
- Git
|
|
||||||
### building the full-blown jar
|
## Contributing and Technical info
|
||||||
Run `./gradlew :webUI:copyBuild server:shadowJar`, the resulting built jar file will be `server/build/Tachidesk-vX.Y.Z-rxxx.jar`.
|
See [CONTRIBUTING.md](./CONTRIBUTING.md).
|
||||||
### building without `webUI` bundled(server only)
|
|
||||||
Delete the `server/src/main/resources/react` directory if exists from previous runs, then run `./gradlew server:shadowJar`, the resulting built jar file will be `server/build/Tachidesk-vX.Y.Z-rxxx.jar`.
|
|
||||||
### building the Windows package
|
|
||||||
Run `./gradlew :server:windowsPackage` to build a server only bundle and `./gradlew :webUI:copyBuild :server:windowsPackage` to get a full bundle , the resulting built zip package file will be `server/build/Tachidesk-vX.Y.Z-rxxx-win32.zip`.
|
|
||||||
## Running for development purposes
|
|
||||||
### `server` module
|
|
||||||
Follow [Get Android stubs jar](#prerequisite-get-android-stubs-jar) then run `./gradlew :server:run --stacktrace` to run the server
|
|
||||||
### `webUI` module
|
|
||||||
How to do it is described in `webUI/react/README.md` but for short,
|
|
||||||
first cd into `webUI/react` then run `yarn` to install the node modules(do this only once)
|
|
||||||
then `yarn start` to start the development server, if a new browser window doesn't get opned automatically,
|
|
||||||
then open `http://127.0.0.1:3000` in a modern browser. This is a `create-react-app` project
|
|
||||||
and supports HMR and all the other goodies you'll need.
|
|
||||||
|
|
||||||
## Credit
|
## Credit
|
||||||
This project is a spiritual successor of [TachiWeb-Server](https://github.com/Tachiweb/TachiWeb-server), Many of the ideas and the groundwork adopted in this project comes from TachiWeb.
|
This project is a spiritual successor of [TachiWeb-Server](https://github.com/Tachiweb/TachiWeb-server), Many of the ideas and the groundwork adopted in this project comes from TachiWeb.
|
||||||
|
|
||||||
The `AndroidCompat` module was originally developed by [@null-dev](https://github.com/null-dev) for [TachiWeb-Server](https://github.com/Tachiweb/TachiWeb-server) and is licensed under `Apache License Version 2.0`.
|
The `AndroidCompat` module was originally developed by [@null-dev](https://github.com/null-dev) for [TachiWeb-Server](https://github.com/Tachiweb/TachiWeb-server) and is licensed under `Apache License Version 2.0` and `Copyright 2019 Andy Bao and contributors`.
|
||||||
|
|
||||||
Parts of [tachiyomi](https://github.com/tachiyomiorg/tachiyomi) is adopted into this codebase, also licensed under `Apache License Version 2.0`.
|
Parts of [tachiyomi](https://github.com/tachiyomiorg/tachiyomi) is adopted into this codebase, also licensed under `Apache License Version 2.0` and `Copyright 2015 Javier Tomás`.
|
||||||
|
|
||||||
You can obtain a copy of `Apache License Version 2.0` from http://www.apache.org/licenses/LICENSE-2.0
|
You can obtain a copy of `Apache License Version 2.0` from http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
|||||||
+30
-62
@@ -1,83 +1,51 @@
|
|||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
|
||||||
|
import org.jmailen.gradle.kotlinter.tasks.FormatTask
|
||||||
|
import org.jmailen.gradle.kotlinter.tasks.LintTask
|
||||||
|
|
||||||
|
@Suppress("DSL_SCOPE_VIOLATION")
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm") version "1.4.32"
|
alias(libs.plugins.kotlin.jvm)
|
||||||
|
alias(libs.plugins.kotlin.serialization)
|
||||||
|
alias(libs.plugins.kotlinter)
|
||||||
|
alias(libs.plugins.buildconfig) apply false
|
||||||
|
alias(libs.plugins.download)
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
group = "ir.armor.tachidesk"
|
group = "suwayomi"
|
||||||
|
|
||||||
version = "1.0"
|
version = "1.0"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven("https://maven.google.com/")
|
google()
|
||||||
|
maven("https://github.com/Suwayomi/Tachidesk-Server/raw/android-jar/")
|
||||||
maven("https://jitpack.io")
|
maven("https://jitpack.io")
|
||||||
maven("https://oss.sonatype.org/content/repositories/snapshots/")
|
|
||||||
maven("https://dl.google.com/dl/android/maven2/")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val projects = listOf(
|
subprojects {
|
||||||
project(":AndroidCompat"),
|
plugins.withType<JavaPlugin> {
|
||||||
project(":AndroidCompat:Config"),
|
extensions.configure<JavaPluginExtension> {
|
||||||
project(":server")
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
)
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
|
||||||
configure(projects) {
|
|
||||||
apply(plugin = "org.jetbrains.kotlin.jvm")
|
|
||||||
|
|
||||||
java {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
|
||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.withType<KotlinCompile> {
|
|
||||||
kotlinOptions {
|
|
||||||
jvmTarget = JavaVersion.VERSION_1_8.toString()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
tasks {
|
||||||
// Kotlin
|
withType<KotlinJvmCompile> {
|
||||||
implementation(kotlin("stdlib-jdk8"))
|
dependsOn("formatKotlin")
|
||||||
implementation(kotlin("reflect"))
|
kotlinOptions {
|
||||||
testImplementation(kotlin("test"))
|
jvmTarget = JavaVersion.VERSION_1_8.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// coroutines
|
withType<LintTask> {
|
||||||
val coroutinesVersion = "1.4.3"
|
source(files("src/kotlin"))
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
|
}
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:$coroutinesVersion")
|
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion")
|
|
||||||
|
|
||||||
|
withType<FormatTask> {
|
||||||
// Dependency Injection
|
source(files("src/kotlin"))
|
||||||
implementation("org.kodein.di:kodein-di-conf-jvm:7.5.0")
|
}
|
||||||
|
|
||||||
// Logging
|
|
||||||
implementation("org.slf4j:slf4j-api:1.7.30")
|
|
||||||
implementation("ch.qos.logback:logback-classic:1.2.3")
|
|
||||||
implementation("io.github.microutils:kotlin-logging:2.0.6")
|
|
||||||
|
|
||||||
// RxJava
|
|
||||||
implementation("io.reactivex:rxjava:1.3.8")
|
|
||||||
implementation("io.reactivex:rxkotlin:1.0.0")
|
|
||||||
|
|
||||||
// JSoup
|
|
||||||
implementation("org.jsoup:jsoup:1.13.1")
|
|
||||||
|
|
||||||
|
|
||||||
// dependency of :AndroidCompat:Config
|
|
||||||
implementation("com.typesafe:config:1.4.1")
|
|
||||||
implementation("io.github.config4k:config4k:0.4.2")
|
|
||||||
|
|
||||||
// to get application content root
|
|
||||||
implementation("net.harawata:appdirs:1.2.1")
|
|
||||||
|
|
||||||
// dex2jar: https://github.com/DexPatcher/dex2jar/releases/tag/v2.1-20190905-lanchon
|
|
||||||
implementation("com.github.DexPatcher.dex2jar:dex-tools:v2.1-20190905-lanchon")
|
|
||||||
|
|
||||||
// APK parser
|
|
||||||
implementation("net.dongliu:apk-parser:2.6.10")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
plugins {
|
||||||
|
`kotlin-dsl`
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("net.lingala.zip4j:zip4j:2.9.0")
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import java.io.BufferedReader
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
const val MainClass = "suwayomi.tachidesk.MainKt"
|
||||||
|
|
||||||
|
// should be bumped with each stable release
|
||||||
|
val tachideskVersion = System.getenv("ProductVersion") ?: "v0.7.0"
|
||||||
|
|
||||||
|
val webUIRevisionTag = System.getenv("WebUIRevision") ?: "r983"
|
||||||
|
|
||||||
|
// counts commits on the master branch
|
||||||
|
val tachideskRevision = runCatching {
|
||||||
|
System.getenv("ProductRevision") ?: ProcessBuilder()
|
||||||
|
.command("git", "rev-list", "HEAD", "--count")
|
||||||
|
.start()
|
||||||
|
.let { process ->
|
||||||
|
process.waitFor()
|
||||||
|
val output = process.inputStream.use {
|
||||||
|
it.bufferedReader().use(BufferedReader::readText)
|
||||||
|
}
|
||||||
|
process.destroy()
|
||||||
|
"r" + output.trim()
|
||||||
|
}
|
||||||
|
}.getOrDefault("r0")
|
||||||
|
|
||||||
@@ -0,0 +1,216 @@
|
|||||||
|
[versions]
|
||||||
|
kotlin = "1.8.0"
|
||||||
|
coroutines = "1.6.4"
|
||||||
|
serialization = "1.4.1"
|
||||||
|
okhttp = "5.0.0-alpha.11" # Major version is locked by Tachiyomi extensions
|
||||||
|
javalin = "4.6.6" # Javalin 5.0.0+ requires Java 11
|
||||||
|
jackson = "2.13.3" # jackson version locked by javalin, ref: `io.javalin.core.util.OptionalDependency`
|
||||||
|
exposed = "0.40.1"
|
||||||
|
dex2jar = "v59"
|
||||||
|
rhino = "1.7.14"
|
||||||
|
settings = "1.0.0-RC"
|
||||||
|
twelvemonkeys = "3.9.4"
|
||||||
|
playwright = "1.28.0"
|
||||||
|
|
||||||
|
[libraries]
|
||||||
|
# Kotlin
|
||||||
|
kotlin-stdlib-jdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "kotlin" }
|
||||||
|
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" }
|
||||||
|
kotlin-test-junit5 = { module = "org.jetbrains.kotlin:kotlin-test-junit5", version.ref = "kotlin" }
|
||||||
|
|
||||||
|
# Coroutines
|
||||||
|
coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }
|
||||||
|
coroutines-jdk8 = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8", version.ref = "coroutines" }
|
||||||
|
coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" }
|
||||||
|
|
||||||
|
# Serialization
|
||||||
|
serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization" }
|
||||||
|
serialization-protobuf = { module = "org.jetbrains.kotlinx:kotlinx-serialization-protobuf", version.ref = "serialization" }
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
slf4japi = "org.slf4j:slf4j-api:2.0.6"
|
||||||
|
logback = "ch.qos.logback:logback-classic:1.3.5"
|
||||||
|
kotlinlogging = "io.github.microutils:kotlin-logging:3.0.5"
|
||||||
|
|
||||||
|
# OkHttp
|
||||||
|
okhttp-core = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
|
||||||
|
okhttp-logging = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okhttp" }
|
||||||
|
okhttp-dnsoverhttps = { module = "com.squareup.okhttp3:okhttp-dnsoverhttps", version.ref = "okhttp" }
|
||||||
|
okio = "com.squareup.okio:okio:3.3.0"
|
||||||
|
|
||||||
|
# Javalin api
|
||||||
|
javalin-core = { module = "io.javalin:javalin", version.ref = "javalin" }
|
||||||
|
javalin-openapi = { module = "io.javalin:javalin-openapi", version.ref = "javalin" }
|
||||||
|
jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" }
|
||||||
|
jackson-kotlin = { module = "com.fasterxml.jackson.module:jackson-module-kotlin", version.ref = "jackson" }
|
||||||
|
jackson-annotations = { module = "com.fasterxml.jackson.core:jackson-annotations", version.ref = "jackson" }
|
||||||
|
|
||||||
|
# Exposed ORM
|
||||||
|
exposed-core = { module = "org.jetbrains.exposed:exposed-core", version.ref = "exposed" }
|
||||||
|
exposed-dao = { module = "org.jetbrains.exposed:exposed-dao", version.ref = "exposed" }
|
||||||
|
exposed-jdbc = { module = "org.jetbrains.exposed:exposed-jdbc", version.ref = "exposed" }
|
||||||
|
exposed-javatime = { module = "org.jetbrains.exposed:exposed-java-time", version.ref = "exposed" }
|
||||||
|
h2 = "com.h2database:h2:1.4.200" # current database driver, can't update to h2 v2 without sql migration
|
||||||
|
|
||||||
|
# Exposed Migrations
|
||||||
|
exposed-migrations = "com.github.Suwayomi:exposed-migrations:3.2.0"
|
||||||
|
|
||||||
|
# Dependency Injection
|
||||||
|
kodein = "org.kodein.di:kodein-di-conf-jvm:7.15.0"
|
||||||
|
|
||||||
|
# tray icon
|
||||||
|
systemtray-core = "com.dorkbox:SystemTray:4.2.1"
|
||||||
|
systemtray-utils = "com.dorkbox:Utilities:1.39" # version locked by SystemTray
|
||||||
|
systemtray-desktop = "com.dorkbox:Desktop:1.0"
|
||||||
|
|
||||||
|
# dependencies of Tachiyomi extensions
|
||||||
|
injekt = "com.github.inorichi.injekt:injekt-core:65b0440"
|
||||||
|
rxjava = "io.reactivex:rxjava:1.3.8"
|
||||||
|
jsoup = "org.jsoup:jsoup:1.15.3"
|
||||||
|
|
||||||
|
# Config
|
||||||
|
config = "com.typesafe:config:1.4.2"
|
||||||
|
config4k = "io.github.config4k:config4k:0.5.0"
|
||||||
|
|
||||||
|
# Sort
|
||||||
|
sort = "com.github.gpanther:java-nat-sort:natural-comparator-1.1"
|
||||||
|
|
||||||
|
# Android stub library
|
||||||
|
android-stubs = "com.github.Suwayomi:android-jar:1.0.0"
|
||||||
|
|
||||||
|
# Asm modificiation
|
||||||
|
asm = "org.ow2.asm:asm:9.4" # version locked by Dex2Jar
|
||||||
|
dex2jar-translator = { module = "com.github.ThexXTURBOXx.dex2jar:dex-translator", version.ref = "dex2jar" }
|
||||||
|
dex2jar-tools = { module = "com.github.ThexXTURBOXx.dex2jar:dex-tools", version.ref = "dex2jar" }
|
||||||
|
|
||||||
|
# APK
|
||||||
|
apk-parser = "net.dongliu:apk-parser:2.6.10"
|
||||||
|
apksig = "com.android.tools.build:apksig:7.2.1"
|
||||||
|
|
||||||
|
# Xml
|
||||||
|
xmlpull = "xmlpull:xmlpull:1.1.3.4a"
|
||||||
|
|
||||||
|
# Disk & File
|
||||||
|
appdirs = "net.harawata:appdirs:1.2.1"
|
||||||
|
zip4j = "net.lingala.zip4j:zip4j:2.11.2"
|
||||||
|
junrar = "com.github.junrar:junrar:7.5.3"
|
||||||
|
|
||||||
|
# CloudflareInterceptor
|
||||||
|
playwright = { module = "com.microsoft.playwright:playwright", version.ref = "playwright" }
|
||||||
|
|
||||||
|
# AES/CBC/PKCS7Padding Cypher provider
|
||||||
|
bouncycastle = "org.bouncycastle:bcprov-jdk18on:1.72"
|
||||||
|
|
||||||
|
# AndroidX annotations
|
||||||
|
android-annotations = "androidx.annotation:annotation:1.5.0"
|
||||||
|
|
||||||
|
# Substitute for duktape-android
|
||||||
|
rhino-runtime = { module = "org.mozilla:rhino-runtime", version.ref = "rhino" } # slimmer version of 'org.mozilla:rhino'
|
||||||
|
rhino-engine = { module = "org.mozilla:rhino-engine", version.ref = "rhino" } # provides the same interface as 'javax.script' a.k.a Nashorn
|
||||||
|
|
||||||
|
# Settings
|
||||||
|
settings-core = { module = "com.russhwolf:multiplatform-settings-jvm", version.ref = "settings" }
|
||||||
|
settings-serialization = { module = "com.russhwolf:multiplatform-settings-serialization-jvm", version.ref = "settings" }
|
||||||
|
|
||||||
|
# ICU4J
|
||||||
|
icu4j = "com.ibm.icu:icu4j:72.1"
|
||||||
|
|
||||||
|
# Image Decoding implementation provider
|
||||||
|
twelvemonkeys-common-lang = { module = "com.twelvemonkeys.common:common-lang", version.ref = "twelvemonkeys" }
|
||||||
|
twelvemonkeys-common-io = { module = "com.twelvemonkeys.common:common-io", version.ref = "twelvemonkeys" }
|
||||||
|
twelvemonkeys-common-image = { module = "com.twelvemonkeys.common:common-image", version.ref = "twelvemonkeys" }
|
||||||
|
twelvemonkeys-imageio-core = { module = "com.twelvemonkeys.imageio:imageio-core", version.ref = "twelvemonkeys" }
|
||||||
|
twelvemonkeys-imageio-metadata = { module = "com.twelvemonkeys.imageio:imageio-metadata", version.ref = "twelvemonkeys" }
|
||||||
|
twelvemonkeys-imageio-jpeg = { module = "com.twelvemonkeys.imageio:imageio-jpeg", version.ref = "twelvemonkeys" }
|
||||||
|
twelvemonkeys-imageio-webp = { module = "com.twelvemonkeys.imageio:imageio-webp", version.ref = "twelvemonkeys" }
|
||||||
|
|
||||||
|
# Testing
|
||||||
|
mockk = "io.mockk:mockk:1.13.2"
|
||||||
|
|
||||||
|
[plugins]
|
||||||
|
# Kotlin
|
||||||
|
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin"}
|
||||||
|
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin"}
|
||||||
|
|
||||||
|
# Linter
|
||||||
|
kotlinter = { id = "org.jmailen.kotlinter", version = "3.12.0"}
|
||||||
|
|
||||||
|
# Build config
|
||||||
|
buildconfig = { id = "com.github.gmazzo.buildconfig", version = "3.1.0"}
|
||||||
|
|
||||||
|
# Download
|
||||||
|
download = { id = "de.undercouch.download", version = "5.3.0"}
|
||||||
|
|
||||||
|
# ShadowJar
|
||||||
|
shadowjar = { id = "com.github.johnrengelman.shadow", version = "7.1.2"}
|
||||||
|
|
||||||
|
[bundles]
|
||||||
|
shared = [
|
||||||
|
"kotlin-stdlib-jdk8",
|
||||||
|
"kotlin-reflect",
|
||||||
|
"coroutines-core",
|
||||||
|
"coroutines-jdk8",
|
||||||
|
"serialization-json",
|
||||||
|
"serialization-protobuf",
|
||||||
|
"kodein",
|
||||||
|
"slf4japi",
|
||||||
|
"logback",
|
||||||
|
"kotlinlogging",
|
||||||
|
"appdirs",
|
||||||
|
"rxjava",
|
||||||
|
"jsoup",
|
||||||
|
"config",
|
||||||
|
"config4k",
|
||||||
|
"dex2jar-translator",
|
||||||
|
"dex2jar-tools",
|
||||||
|
"apk-parser",
|
||||||
|
"jackson-annotations"
|
||||||
|
]
|
||||||
|
|
||||||
|
sharedTest = [
|
||||||
|
"kotlin-test-junit5",
|
||||||
|
"coroutines-test",
|
||||||
|
]
|
||||||
|
|
||||||
|
okhttp = [
|
||||||
|
"okhttp-core",
|
||||||
|
"okhttp-logging",
|
||||||
|
"okhttp-dnsoverhttps",
|
||||||
|
]
|
||||||
|
javalin = [
|
||||||
|
"javalin-core",
|
||||||
|
"javalin-openapi",
|
||||||
|
]
|
||||||
|
jackson = [
|
||||||
|
"jackson-databind",
|
||||||
|
"jackson-kotlin",
|
||||||
|
"jackson-annotations",
|
||||||
|
]
|
||||||
|
exposed = [
|
||||||
|
"exposed-core",
|
||||||
|
"exposed-dao",
|
||||||
|
"exposed-jdbc",
|
||||||
|
"exposed-javatime",
|
||||||
|
]
|
||||||
|
systemtray = [
|
||||||
|
"systemtray-core",
|
||||||
|
"systemtray-utils",
|
||||||
|
"systemtray-desktop"
|
||||||
|
]
|
||||||
|
rhino = [
|
||||||
|
"rhino-runtime",
|
||||||
|
"rhino-engine",
|
||||||
|
]
|
||||||
|
settings = [
|
||||||
|
"settings-core",
|
||||||
|
"settings-serialization",
|
||||||
|
]
|
||||||
|
twelvemonkeys = [
|
||||||
|
"twelvemonkeys-common-lang",
|
||||||
|
"twelvemonkeys-common-io",
|
||||||
|
"twelvemonkeys-common-image",
|
||||||
|
"twelvemonkeys-imageio-core",
|
||||||
|
"twelvemonkeys-imageio-metadata",
|
||||||
|
"twelvemonkeys-imageio-jpeg",
|
||||||
|
"twelvemonkeys-imageio-webp",
|
||||||
|
]
|
||||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env sh
|
#!/bin/sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright 2015 the original author or authors.
|
# Copyright © 2015-2021 the original authors.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@@ -17,67 +17,101 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
##
|
#
|
||||||
## Gradle start up script for UN*X
|
# Gradle start up script for POSIX generated by Gradle.
|
||||||
##
|
#
|
||||||
|
# Important for running:
|
||||||
|
#
|
||||||
|
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||||
|
# noncompliant, but you have some other compliant shell such as ksh or
|
||||||
|
# bash, then to run this script, type that shell name before the whole
|
||||||
|
# command line, like:
|
||||||
|
#
|
||||||
|
# ksh Gradle
|
||||||
|
#
|
||||||
|
# Busybox and similar reduced shells will NOT work, because this script
|
||||||
|
# requires all of these POSIX shell features:
|
||||||
|
# * functions;
|
||||||
|
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||||
|
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||||
|
# * compound commands having a testable exit status, especially «case»;
|
||||||
|
# * various built-in commands including «command», «set», and «ulimit».
|
||||||
|
#
|
||||||
|
# Important for patching:
|
||||||
|
#
|
||||||
|
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||||
|
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||||
|
#
|
||||||
|
# The "traditional" practice of packing multiple parameters into a
|
||||||
|
# space-separated string is a well documented source of bugs and security
|
||||||
|
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||||
|
# options in "$@", and eventually passing that to Java.
|
||||||
|
#
|
||||||
|
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||||
|
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||||
|
# see the in-line comments for details.
|
||||||
|
#
|
||||||
|
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||||
|
# Darwin, MinGW, and NonStop.
|
||||||
|
#
|
||||||
|
# (3) This script is generated from the Groovy template
|
||||||
|
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
|
# within the Gradle project.
|
||||||
|
#
|
||||||
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
# Attempt to set APP_HOME
|
# Attempt to set APP_HOME
|
||||||
|
|
||||||
# Resolve links: $0 may be a link
|
# Resolve links: $0 may be a link
|
||||||
PRG="$0"
|
app_path=$0
|
||||||
# Need this for relative symlinks.
|
|
||||||
while [ -h "$PRG" ] ; do
|
# Need this for daisy-chained symlinks.
|
||||||
ls=`ls -ld "$PRG"`
|
while
|
||||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||||
if expr "$link" : '/.*' > /dev/null; then
|
[ -h "$app_path" ]
|
||||||
PRG="$link"
|
do
|
||||||
else
|
ls=$( ls -ld "$app_path" )
|
||||||
PRG=`dirname "$PRG"`"/$link"
|
link=${ls#*' -> '}
|
||||||
fi
|
case $link in #(
|
||||||
|
/*) app_path=$link ;; #(
|
||||||
|
*) app_path=$APP_HOME$link ;;
|
||||||
|
esac
|
||||||
done
|
done
|
||||||
SAVED="`pwd`"
|
|
||||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||||
APP_HOME="`pwd -P`"
|
|
||||||
cd "$SAVED" >/dev/null
|
|
||||||
|
|
||||||
APP_NAME="Gradle"
|
APP_NAME="Gradle"
|
||||||
APP_BASE_NAME=`basename "$0"`
|
APP_BASE_NAME=${0##*/}
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD="maximum"
|
MAX_FD=maximum
|
||||||
|
|
||||||
warn () {
|
warn () {
|
||||||
echo "$*"
|
echo "$*"
|
||||||
}
|
} >&2
|
||||||
|
|
||||||
die () {
|
die () {
|
||||||
echo
|
echo
|
||||||
echo "$*"
|
echo "$*"
|
||||||
echo
|
echo
|
||||||
exit 1
|
exit 1
|
||||||
}
|
} >&2
|
||||||
|
|
||||||
# OS specific support (must be 'true' or 'false').
|
# OS specific support (must be 'true' or 'false').
|
||||||
cygwin=false
|
cygwin=false
|
||||||
msys=false
|
msys=false
|
||||||
darwin=false
|
darwin=false
|
||||||
nonstop=false
|
nonstop=false
|
||||||
case "`uname`" in
|
case "$( uname )" in #(
|
||||||
CYGWIN* )
|
CYGWIN* ) cygwin=true ;; #(
|
||||||
cygwin=true
|
Darwin* ) darwin=true ;; #(
|
||||||
;;
|
MSYS* | MINGW* ) msys=true ;; #(
|
||||||
Darwin* )
|
NONSTOP* ) nonstop=true ;;
|
||||||
darwin=true
|
|
||||||
;;
|
|
||||||
MINGW* )
|
|
||||||
msys=true
|
|
||||||
;;
|
|
||||||
NONSTOP* )
|
|
||||||
nonstop=true
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
@@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
|||||||
if [ -n "$JAVA_HOME" ] ; then
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
# IBM's JDK on AIX uses strange locations for the executables
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||||
else
|
else
|
||||||
JAVACMD="$JAVA_HOME/bin/java"
|
JAVACMD=$JAVA_HOME/bin/java
|
||||||
fi
|
fi
|
||||||
if [ ! -x "$JAVACMD" ] ; then
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
@@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
|
|||||||
location of your Java installation."
|
location of your Java installation."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD="java"
|
JAVACMD=java
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
@@ -106,80 +140,101 @@ location of your Java installation."
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# Increase the maximum file descriptors if we can.
|
||||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
MAX_FD_LIMIT=`ulimit -H -n`
|
case $MAX_FD in #(
|
||||||
if [ $? -eq 0 ] ; then
|
max*)
|
||||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
MAX_FD="$MAX_FD_LIMIT"
|
warn "Could not query maximum file descriptor limit"
|
||||||
fi
|
esac
|
||||||
ulimit -n $MAX_FD
|
case $MAX_FD in #(
|
||||||
if [ $? -ne 0 ] ; then
|
'' | soft) :;; #(
|
||||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
*)
|
||||||
fi
|
ulimit -n "$MAX_FD" ||
|
||||||
else
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Darwin, add options to specify how the application appears in the dock
|
|
||||||
if $darwin; then
|
|
||||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
|
||||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
|
||||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
|
||||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
|
||||||
|
|
||||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
|
||||||
|
|
||||||
# We build the pattern for arguments to be converted via cygpath
|
|
||||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
|
||||||
SEP=""
|
|
||||||
for dir in $ROOTDIRSRAW ; do
|
|
||||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
|
||||||
SEP="|"
|
|
||||||
done
|
|
||||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
|
||||||
# Add a user-defined pattern to the cygpath arguments
|
|
||||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
|
||||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
|
||||||
fi
|
|
||||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
|
||||||
i=0
|
|
||||||
for arg in "$@" ; do
|
|
||||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
|
||||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
|
||||||
|
|
||||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
|
||||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
|
||||||
else
|
|
||||||
eval `echo args$i`="\"$arg\""
|
|
||||||
fi
|
|
||||||
i=`expr $i + 1`
|
|
||||||
done
|
|
||||||
case $i in
|
|
||||||
0) set -- ;;
|
|
||||||
1) set -- "$args0" ;;
|
|
||||||
2) set -- "$args0" "$args1" ;;
|
|
||||||
3) set -- "$args0" "$args1" "$args2" ;;
|
|
||||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
|
||||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
|
||||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
|
||||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
|
||||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
|
||||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Escape application args
|
# Collect all arguments for the java command, stacking in reverse order:
|
||||||
save () {
|
# * args from the command line
|
||||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
# * the main class name
|
||||||
echo " "
|
# * -classpath
|
||||||
}
|
# * -D...appname settings
|
||||||
APP_ARGS=`save "$@"`
|
# * --module-path (only if needed)
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||||
|
|
||||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
if "$cygwin" || "$msys" ; then
|
||||||
|
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||||
|
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||||
|
|
||||||
|
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||||
|
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
for arg do
|
||||||
|
if
|
||||||
|
case $arg in #(
|
||||||
|
-*) false ;; # don't mess with options #(
|
||||||
|
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||||
|
[ -e "$t" ] ;; #(
|
||||||
|
*) false ;;
|
||||||
|
esac
|
||||||
|
then
|
||||||
|
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||||
|
fi
|
||||||
|
# Roll the args list around exactly as many times as the number of
|
||||||
|
# args, so each arg winds up back in the position where it started, but
|
||||||
|
# possibly modified.
|
||||||
|
#
|
||||||
|
# NB: a `for` loop captures its iteration list before it begins, so
|
||||||
|
# changing the positional parameters here affects neither the number of
|
||||||
|
# iterations, nor the values presented in `arg`.
|
||||||
|
shift # remove old arg
|
||||||
|
set -- "$@" "$arg" # push replacement arg
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Collect all arguments for the java command;
|
||||||
|
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||||
|
# shell script including quotes and variable substitutions, so put them in
|
||||||
|
# double quotes to make sure that they get re-expanded; and
|
||||||
|
# * put everything else in single quotes, so that it's not re-expanded.
|
||||||
|
|
||||||
|
set -- \
|
||||||
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
|
-classpath "$CLASSPATH" \
|
||||||
|
org.gradle.wrapper.GradleWrapperMain \
|
||||||
|
"$@"
|
||||||
|
|
||||||
|
# Stop when "xargs" is not available.
|
||||||
|
if ! command -v xargs >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "xargs is not available"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Use "xargs" to parse quoted args.
|
||||||
|
#
|
||||||
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
#
|
||||||
|
# In Bash we could simply go:
|
||||||
|
#
|
||||||
|
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||||
|
# set -- "${ARGS[@]}" "$@"
|
||||||
|
#
|
||||||
|
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||||
|
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||||
|
# character that might be a shell metacharacter, then use eval to reverse
|
||||||
|
# that process (while maintaining the separation between arguments), and wrap
|
||||||
|
# the whole thing up as a single "set" statement.
|
||||||
|
#
|
||||||
|
# This will of course break if any of these variables contains a newline or
|
||||||
|
# an unmatched quote.
|
||||||
|
#
|
||||||
|
|
||||||
|
eval "set -- $(
|
||||||
|
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||||
|
xargs -n1 |
|
||||||
|
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||||
|
tr '\n' ' '
|
||||||
|
)" '"$@"'
|
||||||
|
|
||||||
exec "$JAVACMD" "$@"
|
exec "$JAVACMD" "$@"
|
||||||
|
|||||||
Vendored
+8
-6
@@ -14,7 +14,7 @@
|
|||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%" == "" @echo off
|
@if "%DEBUG%"=="" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@rem
|
@rem
|
||||||
@rem Gradle startup script for Windows
|
@rem Gradle startup script for Windows
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
if "%OS%"=="Windows_NT" setlocal
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
set DIRNAME=%~dp0
|
||||||
if "%DIRNAME%" == "" set DIRNAME=.
|
if "%DIRNAME%"=="" set DIRNAME=.
|
||||||
set APP_BASE_NAME=%~n0
|
set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
|||||||
|
|
||||||
set JAVA_EXE=java.exe
|
set JAVA_EXE=java.exe
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if "%ERRORLEVEL%" == "0" goto execute
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
@@ -75,13 +75,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
|||||||
|
|
||||||
:end
|
:end
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem End local scope for the variables with windows NT shell
|
||||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||||
|
|
||||||
:fail
|
:fail
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
rem the _cmd.exe /c_ return code!
|
rem the _cmd.exe /c_ return code!
|
||||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
set EXIT_CODE=%ERRORLEVEL%
|
||||||
exit /b 1
|
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||||
|
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||||
|
exit /b %EXIT_CODE%
|
||||||
|
|
||||||
:mainEnd
|
:mainEnd
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user