Compare commits
1121 Commits
e9a970a75b
..
v3.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 3cef074c9e | |||
| b24f858369 | |||
| 72bb5b42af | |||
| f53bb28b66 | |||
| 2957a45c4b | |||
| c7e5c1fce8 | |||
| 8731f58948 | |||
| 7b64258af6 | |||
| 122ff2d216 | |||
| c0abb0d50d | |||
| 1ff312d236 | |||
| b80f801d23 | |||
| 9fcd1a0d23 | |||
| 9200e22a7e | |||
| d5ff55e23e | |||
| 5dc613cd79 | |||
| 03af183fb3 | |||
| 144cf71368 | |||
| 5eafa37cdd | |||
| 1d86c6da01 | |||
| a2692e1469 | |||
| ed3d14b131 | |||
| 50429a3513 | |||
| b4e1ced3ed | |||
| b92b281050 | |||
| c980fddfa1 | |||
| 613e6d6503 | |||
| 4d0b6b93bc | |||
| f5bcc9b851 | |||
| 152576e85d | |||
| 609b132106 | |||
| d0f2a865bc | |||
| 5940cf24a0 | |||
| 60b5b5d312 | |||
| bffd27ae5b | |||
| 13573f4b3f | |||
| 1bdb7f4e3a | |||
| f9b895b32c | |||
| 3a95d0da01 | |||
| fcd7723f73 | |||
| 47f6c44c17 | |||
| 34b2901566 | |||
| 1adee07127 | |||
| 3c60976efa | |||
| 053b801262 | |||
| 1a37fd0ca4 | |||
| f14d70ea35 | |||
| b6283b3469 | |||
| b19e248383 | |||
| c07905c360 | |||
| da32d0d9e7 | |||
| 4a6c53703f | |||
| 4c84673bdf | |||
| 715f2bc907 | |||
| b78d568d9f | |||
| 3b1e3ea62c | |||
| e65dd33084 | |||
| bec78e84e6 | |||
| e6a343c7ec | |||
| f05dccd384 | |||
| 41f67cabc0 | |||
| bc5e7445d9 | |||
| 2883b4c35b | |||
| 6d199244ef | |||
| 1c27a29238 | |||
| bd64f7bd86 | |||
| a07d954f1c | |||
| 511c8ea79d | |||
| db33707e5e | |||
| ed5431680f | |||
| f1fcde2142 | |||
| 9f2fb716f7 | |||
| 14b4969a65 | |||
| 15feac81c9 | |||
| 2bbf0d1b82 | |||
| 0b06bed1db | |||
| 2055d7a07f | |||
| da92ce3a46 | |||
| dcad1840c4 | |||
| f6694031a1 | |||
| cfddaaae13 | |||
| 8524472d38 | |||
| 863612d1a1 | |||
| e446fc47ce | |||
| e33a887055 | |||
| 78951a3bc4 | |||
| 44318d1ecd | |||
| a6fb44e1ab | |||
| 374d2d1962 | |||
| 3ad143228d | |||
| 4ea14c853e | |||
| 38bbc1c6f5 | |||
| 9a34daa2bc | |||
| e5e3f5f0a3 | |||
| 899a89cb3b | |||
| 63cb564818 | |||
| e93511fde7 | |||
| eeac5c6c45 | |||
| f7b48333df | |||
| cb88a6fd9c | |||
| 7b95546b80 | |||
| 5f9ea6c06a | |||
| d54d1d964d | |||
| 868f271588 | |||
| 7606c9d325 | |||
| 3c66a6a1c1 | |||
| bf900e7468 | |||
| 52cbcb9128 | |||
| 97e7ba25a6 | |||
| bc9ff23372 | |||
| c176ed8861 | |||
| 63c0653006 | |||
| fbf899465d | |||
| 603e478794 | |||
| 347d23641b | |||
| c4e973e83b | |||
| d22abe300b | |||
| 2bab3119b0 | |||
| ea3d7b8892 | |||
| 7eb2f78174 | |||
| 7db04440ff | |||
| 062beb718d | |||
| b8f3cf1b47 | |||
| c280c1339b | |||
| 543acc9fff | |||
| 55d609c82b | |||
| f144c1cdbd | |||
| 1531535151 | |||
| 4fe4c8bb03 | |||
| 1302682900 | |||
| 62e0821be2 | |||
| 856e616247 | |||
| 71fdba3c4a | |||
| 7803bd5c06 | |||
| 8dc9e01439 | |||
| 1d6ce13a6c | |||
| 6a907b1542 | |||
| bef759e358 | |||
| 63023c5266 | |||
| b6f2f9998e | |||
| 6d9115f593 | |||
| 02f7d7c74d | |||
| eeb4ec0e73 | |||
| 9efa05d4de | |||
| 72a8483a23 | |||
| d4da49512c | |||
| 6437970f7f | |||
| bf79618221 | |||
| dbeac1f8eb | |||
| 1625b8a665 | |||
| 5ab202e5c9 | |||
| 2f4fbc9d49 | |||
| 613ffefeb3 | |||
| 89e93be091 | |||
| 9b42077f7a | |||
| 81b88477bd | |||
| 52376e10a5 | |||
| b8b3f9e7ec | |||
| 194eb30042 | |||
| b52aa9ac76 | |||
| c825c41aed | |||
| 6d8f704542 | |||
| 10a399f7e6 | |||
| d59a118e83 | |||
| 07570f9e8a | |||
| 90972e938e | |||
| 4297eb34c9 | |||
| 507f9c3c22 | |||
| 33551089ad | |||
| c8301c6ad6 | |||
| c3396780d7 | |||
| 8ea2b0b63b | |||
| e170d02bff | |||
| 1f872a9b0c | |||
| bcdc1d8915 | |||
| f577435e98 | |||
| bf94550a84 | |||
| a900b04254 | |||
| 3fe5a9d222 | |||
| a07a7676b7 | |||
| 593cc03962 | |||
| 820f255929 | |||
| 7db4146c8d | |||
| 91a6916f4c | |||
| 78374d0301 | |||
| 9185ee0cf9 | |||
| e2de51832c | |||
| 759f16d5b9 | |||
| d0ddedc2b2 | |||
| 4291005161 | |||
| ee144ccb2b | |||
| 7fea21f221 | |||
| 9a4b40f242 | |||
| c2d353b973 | |||
| 8b6cecdbf8 | |||
| 83d8f2821a | |||
| 0225204b4d | |||
| 478957803d | |||
| 0181cb26d2 | |||
| 2ddb3595c7 | |||
| 76e49d1bd0 | |||
| 91f1ee748e | |||
| 9bddf64510 | |||
| 2200ae143e | |||
| 80d9a2ca7d | |||
| cbd1bf35c6 | |||
| c1be57b205 | |||
| 4848bef0dd | |||
| a8f374dd43 | |||
| d43e41e1ba | |||
| 437ac4c59b | |||
| de218409ab | |||
| 060ed859d4 | |||
| 0783c43169 | |||
| b5a317e021 | |||
| 15c1f6dadf | |||
| efda9991f2 | |||
| 9fb651a04e | |||
| 55c652a02a | |||
| 2be706fb3f | |||
| 3e2cc8bfae | |||
| a6c339e13a | |||
| b0174f3acc | |||
| a343d9999e | |||
| 0a2cca6e40 | |||
| bca00f46a9 | |||
| 5848c02d50 | |||
| 29ddcfa1f9 | |||
| 831bb83f4e | |||
| b8a8babc88 | |||
| 4a35aa7272 | |||
| 2ded7d9b1f | |||
| 19f674cf5f | |||
| 790bf5eac3 | |||
| e1adc6a3bc | |||
| bcedab5113 | |||
| adca914d67 | |||
| 8583ab19f0 | |||
| 1aa16a43ee | |||
| e6661d3b0d | |||
| 678e0dc6ac | |||
| bdc10fb729 | |||
| 584fa87bbd | |||
| ac155bbf4c | |||
| 0f6f65045d | |||
| 843b9ddffd | |||
| e283d4cd21 | |||
| 4fe02d27c8 | |||
| 5a269c68ae | |||
| 570a1c85af | |||
| f7ff1ef2bd | |||
| 04530a801c | |||
| 756cd0921b | |||
| 292eee33b9 | |||
| 583c834ba8 | |||
| 33949dbdb1 | |||
| fd79ea4b9b | |||
| b3bff6b43f | |||
| 80aa55b706 | |||
| 76c16ce294 | |||
| 715e6648ae | |||
| 984fad811c | |||
| eafd2c8a13 | |||
| 82fb243ffe | |||
| 6cbf1b2eac | |||
| 043e411a98 | |||
| f93b666bbf | |||
| 7e28aa1474 | |||
| 1deef51df0 | |||
| 6f7934badc | |||
| 2f2680be3c | |||
| 4cd8f4a94c | |||
| a417980a81 | |||
| af69955801 | |||
| 214d49f1d9 | |||
| c4e36a1f97 | |||
| 5de6a1bea6 | |||
| 74a20a0e14 | |||
| 820d08017a | |||
| 258afec391 | |||
| 0cf5aac591 | |||
| 59fd34a4b4 | |||
| 1da3d252e8 | |||
| 3c1cc59d59 | |||
| 1692098d5d | |||
| fbab53af22 | |||
| ce1e263d57 | |||
| 9f99320fda | |||
| 20e1df43d0 | |||
| 728c5434bb | |||
| 542ac4f4e1 | |||
| d23fc228d7 | |||
| 4ff3e47d54 | |||
| 96b22eb557 | |||
| 9187107751 | |||
| c6812b5b11 | |||
| adb584623e | |||
| 120e8de9d1 | |||
| 21726b63f8 | |||
| 04f910ee03 | |||
| edace32213 | |||
| 5e527e434a | |||
| 1d90f7588b | |||
| f8b8a35152 | |||
| fa4c95a9b6 | |||
| a478fc4805 | |||
| febb28e9c4 | |||
| c78a39af50 | |||
| 21e6049c16 | |||
| 6e418337cc | |||
| 48f34053ab | |||
| abfe263750 | |||
| 9ba003b16d | |||
| 48793f3a95 | |||
| d8cf98fd64 | |||
| 78e12d5bee | |||
| bdb8bdf76c | |||
| 88b79eb3a5 | |||
| b6428197ac | |||
| a46138c8b9 | |||
| 1211ca277b | |||
| e6f395c643 | |||
| 1979646b4b | |||
| 5c0eb20cb4 | |||
| 009966a5c7 | |||
| 4427b3b291 | |||
| 3dda4d6540 | |||
| c9df0be874 | |||
| ca2627d3cf | |||
| 47e6527b0e | |||
| 7decbb6eef | |||
| 68da1d0551 | |||
| a6f21b6606 | |||
| 06a4e0c93b | |||
| 0ca1df24ed | |||
| 1d12a906d4 | |||
| 7bd7518963 | |||
| a9c5765be5 | |||
| 2292f63fb6 | |||
| db92b9f5ff | |||
| f538639882 | |||
| 56bc8c2890 | |||
| 1cba4d3fa7 | |||
| 4c7820ceac | |||
| 118dcd8fa0 | |||
| a142ade923 | |||
| 57ab10a87c | |||
| 8c1c3cd634 | |||
| 2d3634d6bf | |||
| 217f29f068 | |||
| 58c3eee153 | |||
| d9e1fb620b | |||
| a3f5b92484 | |||
| 8b96e0ab98 | |||
| eef2d451b7 | |||
| 371e66a6df | |||
| 0d12144744 | |||
| ba39724813 | |||
| af6e6bfc67 | |||
| 315b5a1048 | |||
| c410d4e9f5 | |||
| 299d976622 | |||
| e8587f99c9 | |||
| 63ab96b71b | |||
| e998438135 | |||
| 5fd7d64d21 | |||
| f05037c7d6 | |||
| d0fd654bf7 | |||
| 7165bd91cd | |||
| d3431a5d53 | |||
| fa6c865000 | |||
| fd680a93e0 | |||
| 38b604ad41 | |||
| 2ca67bb61a | |||
| 95b814b751 | |||
| 9963f3f988 | |||
| fde7d4a25a | |||
| 895b2c4f19 | |||
| 427ea9baab | |||
| df718e4498 | |||
| 00956f5bba | |||
| e48d216d79 | |||
| 489f178c7c | |||
| 3bd4eda789 | |||
| fc6c7b8dc6 | |||
| deef1f2c8a | |||
| 38bd38a487 | |||
| 40de64078a | |||
| 780bd5e65a | |||
| 2cd74b4ea9 | |||
| 0cd3df391e | |||
| 854d2b4c27 | |||
| 7227fc7c43 | |||
| 73dcb44121 | |||
| 54fd394ef5 | |||
| fda71166df | |||
| 69b6055353 | |||
| 1bdd0449e0 | |||
| a6fdf9010b | |||
| 941dae0625 | |||
| 4a715bfd17 | |||
| 0b70c7e490 | |||
| 0539836714 | |||
| c08b0e654b | |||
| b3cb48319a | |||
| 44553cc375 | |||
| fbe287a702 | |||
| 5863dcdf67 | |||
| f77bee25ef | |||
| c11328a064 | |||
| d04de2fba0 | |||
| d2b435618c | |||
| 7525bb78e5 | |||
| 2075a572fe | |||
| 73723ba6ba | |||
| 0791820a6c | |||
| 931f352873 | |||
| 7c7d2e0fa4 | |||
| 3372fb6f74 | |||
| bc856269ff | |||
| 06bae231ef | |||
| 65a0edc3a6 | |||
| b7c322d473 | |||
| 0776a04362 | |||
| e51fc5a585 | |||
| 3afc068a02 | |||
| 5cdad44abf | |||
| 43762df998 | |||
| 95228c6dd9 | |||
| 205fcf8487 | |||
| 336e8921ee | |||
| ef149b9fcf | |||
| 766b4c13c3 | |||
| f5605258e3 | |||
| 2ba4d2f2b7 | |||
| 2e050c066e | |||
| 3f83514427 | |||
| 8c227843c9 | |||
| ba084c0a10 | |||
| 3fdd42706d | |||
| b49b51a671 | |||
| e5bb386dd2 | |||
| 2867bb3bc3 | |||
| 416fd02069 | |||
| 581963cfb4 | |||
| 3b14543e66 | |||
| 5dd2194eba | |||
| 5b7880f817 | |||
| bafe1c5781 | |||
| d760be58c3 | |||
| 3da9b70632 | |||
| b7c5902f67 | |||
| 9a22b25564 | |||
| 44c3dec9dc | |||
| 87f3afd8fd | |||
| 53f1129242 | |||
| 74216f75e2 | |||
| ed8eca0c1d | |||
| dc8e6e53c7 | |||
| 989ab5a432 | |||
| ec26c03d58 | |||
| 3b1b3387e7 | |||
| 62c03d1334 | |||
| 51e12184d7 | |||
| 8c01eb9c00 | |||
| bf264d5add | |||
| 8b3bd38bad | |||
| ba0de8800a | |||
| cd5ae4cb7f | |||
| 6575542281 | |||
| bf2559da80 | |||
| fedc207de2 | |||
| 0d58478a73 | |||
| abf24d1942 | |||
| afe3f2f3f3 | |||
| 1d1cb567da | |||
| 699bbee544 | |||
| 9c54915e73 | |||
| ed4390b99d | |||
| 039d9bae68 | |||
| 93ab48ac9a | |||
| c95e312acb | |||
| 9279bc7060 | |||
| fe61576dcd | |||
| 3f6e3074f2 | |||
| 53a8e2aa57 | |||
| 44ab6f181c | |||
| 3a3a830706 | |||
| 1a6e3e73c5 | |||
| 7d508e5a7d | |||
| 370c224d3a | |||
| 7bce501069 | |||
| 9d15445eba | |||
| 16ee13f1f7 | |||
| 8d25eb0acd | |||
| 9cb13a91cd | |||
| 30f8930773 | |||
| 05eaa8d3e0 | |||
| a32ffdf6d4 | |||
| 0f97de1b09 | |||
| e8d6ccec9a | |||
| 005434f79b | |||
| fe997d8b01 | |||
| 7291932a0b | |||
| 49ade03a9a | |||
| dd6dbd25da | |||
| 50bf90fada | |||
| abb81b6390 | |||
| 36da3d3cba | |||
| ae71a99aa4 | |||
| a7034d6351 | |||
| 6010b4c252 | |||
| 8330f4fba9 | |||
| dc6e153b92 | |||
| a2655ee6a5 | |||
| 13248962af | |||
| b698982186 | |||
| 5a299b21c5 | |||
| bb90f11ec8 | |||
| 12369ba2ec | |||
| f5720bde14 | |||
| 0d59a4de48 | |||
| 73c74d0477 | |||
| 70ffd7ded8 | |||
| 92a3a8d6fa | |||
| 6e9cd02b2b | |||
| d0f90af251 | |||
| c53eb27c6f | |||
| 38773e89ff | |||
| 19cb30d360 | |||
| 50a734b977 | |||
| b988758ac2 | |||
| 2567328e8b | |||
| a7568fcbbf | |||
| 27a06ae90c | |||
| 211fd19031 | |||
| fe18611b4b | |||
| 5e9b45ad5f | |||
| af833daee4 | |||
| 1ad5317d6e | |||
| 7cf5df80ce | |||
| d6b880d110 | |||
| cf58a4376e | |||
| a76dcb289a | |||
| 48ec6224e7 | |||
| 127dd8baf4 | |||
| d25c3ff4fc | |||
| f0e9de4cf9 | |||
| 92607a788e | |||
| 82948c1f55 | |||
| 714929c72f | |||
| 98f0d384cb | |||
| e3c87ecf65 | |||
| 1fb9e98eeb | |||
| 01d7c8ec36 | |||
| 22d8d5a0b8 | |||
| 631ed997ba | |||
| 01930ab0cf | |||
| b8fe4c937e | |||
| a7a5b08ad8 | |||
| faaac72b81 | |||
| 8f41139076 | |||
| e1a67acde1 | |||
| 4ab2af51a5 | |||
| 9ffc4eaa40 | |||
| 5eda2581f4 | |||
| 21ceb4fdc4 | |||
| edcf43efba | |||
| eb1ef16b5e | |||
| 6b9c8b7a87 | |||
| a05b96e9a0 | |||
| 699f67aa75 | |||
| 76e469e444 | |||
| 8df630ee0c | |||
| b0c4c53880 | |||
| 116a9c9de0 | |||
| e63f8ab8b8 | |||
| 424245df18 | |||
| 094a11ec64 | |||
| 6b03c9c99f | |||
| 3d116af011 | |||
| cbd965d8e5 | |||
| c9d972fc12 | |||
| da9979494e | |||
| f5c907af33 | |||
| 906fc2dd3d | |||
| a62df536dd | |||
| 7db674b65d | |||
| 784deaa6ea | |||
| 8bc41c2c32 | |||
| 79afc7649d | |||
| 2eee3736df | |||
| a8ba38ef1e | |||
| d3ddbc0c72 | |||
| 6c4085398e | |||
| 2308578622 | |||
| 47cd87e653 | |||
| 87c9684c71 | |||
| 0b66d73178 | |||
| 24cd238eaf | |||
| 72bb9b80ad | |||
| 3d42ac8e44 | |||
| 205ab3b16d | |||
| bb25da274d | |||
| b56de35664 | |||
| 0655ac82f2 | |||
| 166dbfa491 | |||
| 9348977548 | |||
| 769c3eea9b | |||
| e7095af5b8 | |||
| fd42d72423 | |||
| 1382c455a2 | |||
| 1d7fbc841e | |||
| a8a168b0a7 | |||
| dbd1d02485 | |||
| 1c307daa03 | |||
| 7a31f84d34 | |||
| a2a4dd9862 | |||
| 3d8e0f6c23 | |||
| 146da2d072 | |||
| 6a9964e889 | |||
| 318e7c7458 | |||
| f8e2d27bb0 | |||
| 44544f3289 | |||
| 76a5c99b08 | |||
| 70f0f91a17 | |||
| f1394239a3 | |||
| 9e810502c2 | |||
| c67a1752c5 | |||
| d87e40ada5 | |||
| 86bbaa437e | |||
| 96b6b56d95 | |||
| 1f6e5e71ef | |||
| a55f1df17f | |||
| e654226e60 | |||
| 189dc93a6e | |||
| 76cb52878c | |||
| 8d3f0a9f4d | |||
| fe674ef2ea | |||
| 33b165518e | |||
| ff9d509137 | |||
| 278fd5bd59 | |||
| 8ddbc24dd4 | |||
| e93f429906 | |||
| 1dccb1bb64 | |||
| 6d9e67b9f2 | |||
| 4803d48ec7 | |||
| 7c6a12ea8e | |||
| a17d5d01a7 | |||
| cdd909f2dd | |||
| d0e9728c26 | |||
| c8ae428df8 | |||
| a9692f7db4 | |||
| d05a426d00 | |||
| a842b4c4d9 | |||
| 101abaeda1 | |||
| bb99167433 | |||
| e5b57e5ff9 | |||
| 2bd598f7f8 | |||
| b008c5f07f | |||
| a59aa2c30f | |||
| 93de0d4bf3 | |||
| 7a0ac2077c | |||
| 952f459e70 | |||
| 4702196c6e | |||
| f77e064f4e | |||
| c74a9a30bf | |||
| 1d43b36380 | |||
| 736f4edfbd | |||
| c7e2540f6f | |||
| f796296286 | |||
| eb206d2abb | |||
| bff62fb105 | |||
| 5fc83d7615 | |||
| 552a324e08 | |||
| b155d7d1ba | |||
| e4571bf668 | |||
| 53cc929a72 | |||
| 20f5a4cc91 | |||
| 2aabe559bf | |||
| dcf0902c5b | |||
| 0e8219b200 | |||
| 5f7fa0557f | |||
| 63fb4d57e2 | |||
| b5d6f44f4c | |||
| b21c8f8c3a | |||
| fe7c7660d3 | |||
| 56de33c821 | |||
| 1d442cd0e2 | |||
| c79d7957f6 | |||
| 1b9216b341 | |||
| 6d97e5fa5d | |||
| 162af35254 | |||
| abe03811f1 | |||
| e85a869733 | |||
| 0c32d5302c | |||
| f310196937 | |||
| c828dfd596 | |||
| d0b4e092b3 | |||
| 91d7d78621 | |||
| 2bc21f13d4 | |||
| 833edc9568 | |||
| 9d8efce26d | |||
| 6d778ca223 | |||
| 1e739e94e2 | |||
| 8c013aa2a9 | |||
| fb0a0b0dc2 | |||
| ab3d9ddb13 | |||
| a67b32b3ce | |||
| e15e690c5d | |||
| 55c4c25663 | |||
| 202ff53c41 | |||
| 992da7c7be | |||
| f47998a553 | |||
| f4d24420e7 | |||
| 308bdb3d46 | |||
| 20b99dce48 | |||
| e4f7c6add9 | |||
| 80110d1a48 | |||
| 0a0b45fb8e | |||
| 4ef29ae26f | |||
| ead4b89874 | |||
| e827fb2eb2 | |||
| 4f161fb891 | |||
| 8c30a013c7 | |||
| 9f3f877bfd | |||
| 84a75788af | |||
| f3615117d8 | |||
| 48a701ef87 | |||
| 41c72e0a8e | |||
| a83b875b66 | |||
| dcef08009d | |||
| eddba3c652 | |||
| f0c9a458bb | |||
| 62c9e271d8 | |||
| 871a25364d | |||
| e67abae3e0 | |||
| c50565dfda | |||
| 60c44da974 | |||
| ba6d9d0c23 | |||
| 8c55f38b07 | |||
| 568cf5e2ad | |||
| 5e843f7a4f | |||
| 090ada5807 | |||
| 0e17c57856 | |||
| 74464992e6 | |||
| a1d9c21337 | |||
| 248fc15716 | |||
| e38ddebfb6 | |||
| 57fc8b2f1a | |||
| b7fac8bcbc | |||
| 12f2eed5b3 | |||
| 3f39fd487f | |||
| 950bf14d95 | |||
| a279995982 | |||
| a2eb9734f1 | |||
| cb23991841 | |||
| 769d24d196 | |||
| af61f4f1db | |||
| f8f77075ec | |||
| 34bb5f9928 | |||
| ca3cced6ad | |||
| be905ac7be | |||
| 53f3ccc888 | |||
| c304670f47 | |||
| 6388894aa4 | |||
| c27b11bf25 | |||
| 11f395f65f | |||
| 63a0adaa6e | |||
| 0ddeb02d23 | |||
| c23acf9e9e | |||
| 54635bf0d3 | |||
| 6fdd9ed48b | |||
| a0399b7f5e | |||
| 387f6bcad4 | |||
| 0b43431543 | |||
| 34862f9ace | |||
| cd465ca35a | |||
| 93251e0029 | |||
| c2402ddb72 | |||
| d3dcb320f4 | |||
| fd9f734de1 | |||
| 9ea9bf4035 | |||
| f9b70d65d8 | |||
| 90621bb1e3 | |||
| 6ff339b552 | |||
| 9854f4eb2d | |||
| d46b046f2d | |||
| d02e8dcd4e | |||
| 07b1fe8e47 | |||
| 7c368ae029 | |||
| d6b5f92d6c | |||
| 2b70a49e09 | |||
| 8cfa20be1e | |||
| 246f6caf20 | |||
| 7750366654 | |||
| 0f963a93f1 | |||
| ea5b63af18 | |||
| 5e89675c9c | |||
| 5777c1ab27 | |||
| 8eda0aeab3 | |||
| 23c430fadc | |||
| aa423cfa5b | |||
| eb753a3f32 | |||
| 4a300a3cb2 | |||
| c4e16418e0 | |||
| 27e7a67a9a | |||
| ce9f140ddf | |||
| 85c3240b54 | |||
| 9c12e11375 | |||
| 630dbee817 | |||
| 18dc02c700 | |||
| 3d7e509f9a | |||
| ed27e6b8e4 | |||
| 631ce7645f | |||
| 181382b2b7 | |||
| ca15e69ae0 | |||
| ba64ba0bd0 | |||
| 1df4d32d69 | |||
| 5d380453a4 | |||
| ba629f1764 | |||
| f2edcaff85 | |||
| 6d358d4087 | |||
| 46dd50a744 | |||
| 3c2058f0e1 | |||
| c22c407ee5 | |||
| 1ed1dfc78a | |||
| 5797a1d8e5 | |||
| 6d5d40b8e3 | |||
| 90c6b18cbb | |||
| ecb7d5ef10 | |||
| e2b347c783 | |||
| 88a988d876 | |||
| fbeecc0479 | |||
| 413188c995 | |||
| 77818f9342 | |||
| c9ec161ccc | |||
| 20443f8a4d | |||
| 299ceac557 | |||
| 9365e5bfb9 | |||
| 3e75841a83 | |||
| 74b8a0f10f | |||
| c291729ed6 | |||
| a70245a3b1 | |||
| dde022d179 | |||
| 0d12c64c47 | |||
| 27d0a88b36 | |||
| ca55141276 | |||
| e20b9d054d | |||
| c1e3645d57 | |||
| 50db137dea | |||
| 5b109c2b79 | |||
| 25b7093302 | |||
| 38cbb87a62 | |||
| 0c0a978886 | |||
| fb5f368894 | |||
| 9454ffd1af | |||
| 16f35d9a34 | |||
| bb6a64790d | |||
| b9378118dd | |||
| b6485f91ae | |||
| e1e8ca9633 | |||
| 72f476a750 | |||
| f897809202 | |||
| 647d085c5f | |||
| 9d0f99c509 | |||
| fd25a23d91 | |||
| 7fdf165ff3 | |||
| b3e27da26d | |||
| 2479dc4096 | |||
| 7e7a5e692e | |||
| f628a6c3d6 | |||
| 5b0f95fed9 | |||
| 6aa98d5eac | |||
| 8e1fe9558e | |||
| 38c3e53ce7 | |||
| 9627766f7d | |||
| 57697142a2 | |||
| beb32755a3 | |||
| cb6e71e544 | |||
| 1487dcbadc | |||
| a4b27fdeab | |||
| 1137c11c59 | |||
| 14cd84dab7 | |||
| b5c5cd9586 | |||
| 85cc4cb8f7 | |||
| cf6732fb29 | |||
| 1207f5abad | |||
| 6e9394ec7a | |||
| 2c9e32b6c4 | |||
| fc470d0622 | |||
| a3270041e3 | |||
| 956068d0d6 | |||
| 3776e32364 | |||
| fb5a54dd17 | |||
| 916d564f82 | |||
| 364def188a | |||
| d1228a085b | |||
| 6c5a29fb48 | |||
| a83aecaa69 | |||
| 3d885ec262 | |||
| 6fdace07c8 | |||
| 8711658e75 | |||
| e25dc46863 | |||
| f53f54af7f | |||
| 763aa8865b | |||
| 2194cb65a2 | |||
| 60435d505f | |||
| af983c76b8 | |||
| ef161bbb31 | |||
| ac364e5ab7 | |||
| 2e2b1c6f18 | |||
| 1fa1496d7f | |||
| 8fb9365eaa | |||
| 92ab8331d0 | |||
| 603d373cee | |||
| aca2c3a9dd | |||
| f544dab3e0 | |||
| c489940f8b | |||
| dc7ddeaa9b | |||
| 9b5f42cda9 | |||
| 4022e4969d | |||
| ed62d06b5e | |||
| f11e4f6626 | |||
| 59eec5241a | |||
| d287486165 | |||
| f70270a0b3 | |||
| 36380fe5fd | |||
| dc7fca4f4c | |||
| 977759145e | |||
| 76c3660cb2 | |||
| fa10a67811 | |||
| 8d95fd0ca0 | |||
| 332e95701e | |||
| 124b24ab76 | |||
| 6ccd1e43bc | |||
| 5c09d04912 | |||
| 119325c3a2 | |||
| 462a559bd3 | |||
| 1bd58a0103 | |||
| 6c97d08027 | |||
| 0ebda9d224 | |||
| 808fc8dc0d | |||
| aefed73f5a | |||
| ea47750ea4 | |||
| 0f02bfd2c3 | |||
| 8e5a5baf52 | |||
| 3deb8eb488 | |||
| 1dd7f0371d | |||
| 7d032bb684 | |||
| ecc4a40eea | |||
| 83c6914a50 | |||
| 0f06d88e18 | |||
| ea5f7b65f3 | |||
| 9ce95da8f4 | |||
| abd1fd3efb | |||
| 90ab8dac27 | |||
| c96d556094 | |||
| 26f68a890e | |||
| cd5b7b17f6 | |||
| 14cfa69060 | |||
| d6d1b0eeef | |||
| 393d089229 | |||
| 706d9b1f6f | |||
| 0e9228ba7c | |||
| 5a17badfae | |||
| 437c6f8262 | |||
| 65d55d6660 | |||
| 7ba1aabc09 | |||
| 470fdd62bb | |||
| 6434d10e52 | |||
| 2ed4fc9fbf | |||
| b418895d9d | |||
| 8939927543 | |||
| 0bbe6a0a12 | |||
| 767784a79c | |||
| 64abfd4408 | |||
| 872e2f9753 | |||
| 09f7225eb7 | |||
| 95bb0ac6d4 | |||
| f97596689f | |||
| 204be84c0f | |||
| 93d8ba0b0f | |||
| b07c50e580 | |||
| fc0dc8aea0 | |||
| 284ed9dea1 | |||
| 1651a90dea | |||
| a888427777 | |||
| 6b53b78ee3 | |||
| c2faa605d3 | |||
| 8bf5a6e0bc | |||
| 80551124f1 | |||
| 652f8227b5 | |||
| 42f68f61c6 | |||
| fcb4104856 | |||
| a0139f4157 | |||
| 6c78060876 | |||
| b9b2f9f2c3 | |||
| 87d5cb78b2 | |||
| cdf421f0f1 | |||
| 2e58757bc9 | |||
| c689836208 | |||
| 4efc320f23 | |||
| 6c1a602bdc | |||
| 0ae994de56 | |||
| e7f4a5bd59 | |||
| 180973d49f | |||
| 705910d9e0 | |||
| b5dfc337ec | |||
| 8996b562bc | |||
| 1ae6186647 | |||
| 2848417cf5 | |||
| d3506acd94 | |||
| 9e9ea41bdd | |||
| 7b0aa7b770 | |||
| 3a25d108fe | |||
| d98e213b92 | |||
| 4d44562ada | |||
| b733b3c59f | |||
| 7b54988514 | |||
| ec4da47af6 | |||
| 633d59c13b | |||
| c06a92e0ae | |||
| 18bd9d62cb | |||
| 0bce6c6a46 | |||
| 0465442803 | |||
| eb667bc436 | |||
| c81628a66e | |||
| 50d3631bc4 | |||
| e971069595 | |||
| ac4c0ec1f6 | |||
| fe3d2e0af4 | |||
| a4b762e1b1 | |||
| daa0015fbd | |||
| 804248d6ad | |||
| 78c4c67a6c | |||
| c23be53bfd | |||
| d7e3e70430 | |||
| e95a859ee9 | |||
| 1a3704e700 | |||
| f49048c6e1 | |||
| 59226365c5 | |||
| 683ce431db | |||
| 8d4e796f42 | |||
| 3da1fbf6ca | |||
| 419e25df23 | |||
| 7fddf80c09 | |||
| fa85e61d6f | |||
| ebac0db0df | |||
| 0404f30c87 | |||
| 769fd7b524 | |||
| 4b5553abef | |||
| e730eb3a32 | |||
| 2933b6e732 | |||
| 94ae2f2658 | |||
| 3453451df9 | |||
| 80d4a2b242 | |||
| c9b1a062ce | |||
| 717ffe560f | |||
| 109e2fa82d | |||
| d03fc2fcf1 | |||
| d0111e7741 | |||
| 5e76d6d865 | |||
| 90e67b22b4 | |||
| 92ba6c9802 | |||
| 0286a51525 | |||
| b552e2cda8 | |||
| 0feb56cb3e | |||
| e1a0acdf4a | |||
| 6586f933ff | |||
| 4ec770da63 | |||
| 39b84a083d | |||
| 28857473b2 | |||
| 2bfc10dab4 | |||
| 1dce1157f4 | |||
| 08d53d52e7 | |||
| 2918d97fd0 | |||
| 701e170e19 | |||
| 71ee669fc5 | |||
| 661ac8c6f4 | |||
| 210f6b51df | |||
| 20611b6e4b | |||
| 689e4b8d23 | |||
| d0378ea528 | |||
| 5454ed3458 | |||
| 0070d46a20 | |||
| 540c10aaff | |||
| f5dfc3604a | |||
| b2c5304efe | |||
| fa512f16c6 | |||
| cbfb25b390 | |||
| b1e55201cf | |||
| 8beeb64127 | |||
| 2d2938c8ad | |||
| e9005d57da | |||
| 69f7c8a500 | |||
| 98fd24ffdc | |||
| 21c3e90b58 | |||
| 49281e0d15 | |||
| e597f81b45 | |||
| 9f6047aebd | |||
| 0745f964c1 | |||
| 18b1ad7b62 | |||
| 9448936e32 | |||
| f1dc436a07 | |||
| f163e24201 | |||
| 81f4f1c46f | |||
| a82e74381f | |||
| 7459896bac | |||
| dd2783b040 | |||
| 23ff2c3ab4 | |||
| ad51191a77 | |||
| 8ef5ab6fe9 | |||
| 2218f9781b | |||
| d08d727917 | |||
| 8cf030585f | |||
| c29515db38 | |||
| d9e27bfaf1 | |||
| 2e8830b9d3 | |||
| 4d3d6ea9a7 | |||
| e69f344ab2 |
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"defaultHomeserver": 0,
|
||||
"homeserverList": ["matrix.lotusguild.org"],
|
||||
"allowCustomHomeservers": false,
|
||||
"featuredCommunities": {
|
||||
"openAsDefault": false,
|
||||
"spaces": [],
|
||||
"rooms": [],
|
||||
"servers": []
|
||||
},
|
||||
"hashRouter": {
|
||||
"enabled": false,
|
||||
"basename": "/"
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"defaultHomeserver": 0,
|
||||
"homeserverList": [
|
||||
"matrix.lotusguild.org"
|
||||
],
|
||||
"allowCustomHomeservers": false,
|
||||
"featuredCommunities": {
|
||||
"openAsDefault": false,
|
||||
"spaces": [],
|
||||
"rooms": [],
|
||||
"servers": []
|
||||
},
|
||||
"hashRouter": {
|
||||
"enabled": false,
|
||||
"basename": "/"
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
VITE_SENTRY_DSN=https://264a5e95c5d31fe080a2e92fb008294d@o4511430568378368.ingest.us.sentry.io/4511430571982849
|
||||
VITE_APP_VERSION=lotus
|
||||
@@ -0,0 +1,2 @@
|
||||
experiment
|
||||
node_modules
|
||||
@@ -0,0 +1,64 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
browser: true,
|
||||
es2021: true,
|
||||
},
|
||||
extends: [
|
||||
"eslint:recommended",
|
||||
"plugin:react/recommended",
|
||||
"plugin:react-hooks/recommended",
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
'airbnb',
|
||||
'prettier',
|
||||
],
|
||||
parser: "@typescript-eslint/parser",
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
},
|
||||
"globals": {
|
||||
JSX: "readonly"
|
||||
},
|
||||
plugins: [
|
||||
'react',
|
||||
'@typescript-eslint'
|
||||
],
|
||||
rules: {
|
||||
'linebreak-style': 0,
|
||||
'no-underscore-dangle': 0,
|
||||
"no-shadow": "off",
|
||||
|
||||
"import/prefer-default-export": "off",
|
||||
"import/extensions": "off",
|
||||
"import/no-unresolved": "off",
|
||||
"import/no-extraneous-dependencies": [
|
||||
"error",
|
||||
{
|
||||
devDependencies: true,
|
||||
},
|
||||
],
|
||||
|
||||
'react/no-unstable-nested-components': [
|
||||
'error',
|
||||
{ allowAsProps: true },
|
||||
],
|
||||
"react/jsx-filename-extension": [
|
||||
"error",
|
||||
{
|
||||
extensions: [".tsx", ".jsx"],
|
||||
},
|
||||
],
|
||||
|
||||
"react/require-default-props": "off",
|
||||
"react/jsx-props-no-spreading": "off",
|
||||
"react-hooks/rules-of-hooks": "error",
|
||||
"react-hooks/exhaustive-deps": "error",
|
||||
|
||||
"@typescript-eslint/no-unused-vars": "error",
|
||||
"@typescript-eslint/no-shadow": "error"
|
||||
},
|
||||
};
|
||||
@@ -1,64 +0,0 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [lotus]
|
||||
pull_request:
|
||||
branches: [lotus]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build & Quality Checks
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: npm
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
# ── Critical gate — if this fails, nothing deploys ──────────────────
|
||||
- name: Build
|
||||
run: npm run build
|
||||
env:
|
||||
NODE_OPTIONS: '--max_old_space_size=4096'
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
VITE_APP_VERSION: ${{ github.sha }}
|
||||
|
||||
# ── Quality checks (informational — pre-existing issues exist) ───────
|
||||
- name: TypeScript
|
||||
run: npm run typecheck
|
||||
continue-on-error: true
|
||||
|
||||
- name: ESLint
|
||||
run: npm run check:eslint
|
||||
continue-on-error: true
|
||||
|
||||
- name: Prettier
|
||||
run: npm run check:prettier
|
||||
continue-on-error: true
|
||||
|
||||
# ── Security ─────────────────────────────────────────────────────────
|
||||
- name: Audit (high/critical)
|
||||
run: npm audit --audit-level=high --omit=dev
|
||||
continue-on-error: true
|
||||
|
||||
# ── Bundle size report ───────────────────────────────────────────────
|
||||
- name: Report bundle sizes
|
||||
run: |
|
||||
echo "### Bundle sizes" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| File | Size | Gzip |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|------|------|------|" >> $GITHUB_STEP_SUMMARY
|
||||
find dist/assets -name "*.js" -not -name "*.map" | sort | while read f; do
|
||||
name=$(basename "$f")
|
||||
size=$(du -sh "$f" | cut -f1)
|
||||
gzip_size=$(gzip -c "$f" | wc -c | awk '{printf "%.1f kB", $1/1024}')
|
||||
echo "| $name | $size | $gzip_size |" >> $GITHUB_STEP_SUMMARY
|
||||
done
|
||||
@@ -1,30 +0,0 @@
|
||||
name: Trigger Desktop Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [lotus]
|
||||
|
||||
jobs:
|
||||
trigger:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Bump cinny submodule
|
||||
env:
|
||||
TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
run: |
|
||||
CINNY_SHA="${{ github.sha }}"
|
||||
git clone "https://x-access-token:$TOKEN@code.lotusguild.org/LotusGuild/cinny-desktop.git" desktop
|
||||
cd desktop
|
||||
git config user.email "ci@lotusguild.org"
|
||||
git config user.name "Lotus CI"
|
||||
git submodule update --init cinny
|
||||
git -C cinny fetch origin
|
||||
git -C cinny checkout "$CINNY_SHA"
|
||||
git add cinny
|
||||
if git diff --cached --quiet; then
|
||||
echo "Submodule already at $CINNY_SHA, nothing to do"
|
||||
else
|
||||
git commit -m "chore: bump cinny submodule to ${CINNY_SHA:0:8}"
|
||||
git push origin main
|
||||
echo "Pushed — cinny-desktop release.yml will start via on:push trigger"
|
||||
fi
|
||||
@@ -1,127 +0,0 @@
|
||||
labels: ['needs-confirmation']
|
||||
body:
|
||||
- type: markdown #add faqs in future
|
||||
attributes:
|
||||
value: |
|
||||
> [!IMPORTANT]
|
||||
> Please read through [the Discussion rules](https://github.com/cinnyapp/cinny/discussions/2653) and check for both existing [Discussions](https://github.com/cinnyapp/cinny/discussions?discussions_q=) and [Issues](https://github.com/cinnyapp/cinny/issues?q=sort%3Areactions-desc) prior to opening a new Discussion.
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: '# Issue Details'
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Issue Description
|
||||
description: |
|
||||
Provide a detailed description of the issue. Include relevant information, such as:
|
||||
- The feature or configuration option you encounter the issue with.
|
||||
- Screenshots, screen recordings, or other supporting media (as needed).
|
||||
- If this is a regression of an existing issue that was closed or resolved, please include the previous item reference (Discussion, Issue, PR, commit) in your description.
|
||||
placeholder: |
|
||||
When I try to send a message in a room, the message doesn't appear in the timeline.
|
||||
OR
|
||||
The application crashes when I click on the settings button.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: |
|
||||
Describe how you expect Cinny to behave in this situation.
|
||||
placeholder: |
|
||||
I expected the message to appear in the room timeline immediately after sending.
|
||||
OR
|
||||
The settings panel should open smoothly without any crashes.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Actual Behavior
|
||||
description: |
|
||||
Describe how Cinny actually behaves in this situation. If it is not immediately obvious how the actual behavior differs from the expected behavior described above, please be sure to mention the deviation specifically.
|
||||
placeholder: |
|
||||
The application freezes for 3 seconds and then shows a white screen.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Reproduction Steps
|
||||
description: |
|
||||
Provide a detailed set of step-by-step instructions for reproducing this issue.
|
||||
placeholder: |
|
||||
1. Open Cinny and log in to my account
|
||||
2. Navigate to the #general room
|
||||
3. Type a message in the message box
|
||||
4. Press Enter to send
|
||||
5. Notice that the message doesn't appear in the timeline
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Environement
|
||||
description: |
|
||||
Please provide information about your environment. Include the following:
|
||||
- OS:
|
||||
- Browser:
|
||||
- Cinny Web Version: (app.cinny.in or self hosted)
|
||||
- Cinny desktop Version: (appimage or deb or flatpak)
|
||||
- Matrix Homeserver:
|
||||
placeholder: |
|
||||
- OS: Windows 11
|
||||
- Browser: Chrome 120.0.6099.109
|
||||
- Cinny Web Version: 3.2.0 (app.cinny.in or self hosted)
|
||||
- Cinny desktop Version: 3.2.0 (appimage or deb or flatpak)
|
||||
- Matrix Homeserver: matrix.org (Synapse 1.97.0)
|
||||
render: text
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant Logs
|
||||
description: |
|
||||
If applicable, add browser console logs to help explain your problem.
|
||||
|
||||
**To get browser console logs:**
|
||||
- Chrome/Edge: Press F12 → Console tab
|
||||
- Firefox: Press F12 → Console tab
|
||||
- Safari: Develop → Show Web Inspector → Console
|
||||
|
||||
Please wrap large log outputs in code blocks with triple backticks (```).
|
||||
placeholder: |
|
||||
```
|
||||
Error: Failed to send message
|
||||
at MessageComposer.sendMessage (composer.js:245)
|
||||
at HTMLButtonElement.onClick (composer.js:189)
|
||||
TypeError: Cannot read property 'content' of undefined
|
||||
at RoomTimeline.render (timeline.js:567)
|
||||
```
|
||||
render: shell
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: |
|
||||
Add any other context about the problem here (e.g., when did this start happening, does it happen on different homeservers, etc.)
|
||||
placeholder: |
|
||||
- This started happening after I updated to version 3.2.0
|
||||
- It only happens in encrypted rooms, not in public rooms
|
||||
- I've tried on both Firefox and Chrome with the same result
|
||||
- It works fine on my phone using the same account
|
||||
- This happens on all homeservers I've tested (matrix.org, mozilla.org)
|
||||
validations:
|
||||
required: false
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
# User Acknowledgements
|
||||
> [!TIP]
|
||||
> Use these links to review the existing Cinny [Discussions](https://github.com/cinnyapp/cinny/discussions?discussions_q=) and [Issues](https://github.com/cinnyapp/cinny/issues?q=sort%3Areactions-desc).
|
||||
- type: checkboxes #add faqs in future
|
||||
attributes:
|
||||
label: 'I acknowledge that:'
|
||||
options:
|
||||
- label: I have searched the Cinny repository (both open and closed Discussions and Issues) and confirm this is not a duplicate of an existing issue or discussion.
|
||||
required: true
|
||||
- label: I have checked the "Preview" tab on all text fields to ensure that everything looks right, and have wrapped all configuration and code in code blocks with a group of three backticks (` ``` `) on separate lines.
|
||||
required: true
|
||||
@@ -0,0 +1,57 @@
|
||||
name: 🐞 Bug Report
|
||||
description: Report a bug
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
## First of all
|
||||
1. Please search for [existing issues](https://github.com/ajbura/cinny/issues?q=is%3Aissue) about this problem first.
|
||||
2. Make sure Cinny is up to date.
|
||||
3. Make sure it's an issue with Cinny and not something else you are using.
|
||||
4. Remember to be friendly.
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear description of what the bug is. Include screenshots if applicable.
|
||||
placeholder: Bug description
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: Reproduction
|
||||
description: Steps to reproduce the behavior.
|
||||
placeholder: |
|
||||
1. Go to ...
|
||||
2. Click on ...
|
||||
3. See error
|
||||
|
||||
- type: textarea
|
||||
id: expected-behavior
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
description: A clear description of what you expected to happen.
|
||||
|
||||
- type: textarea
|
||||
id: info
|
||||
attributes:
|
||||
label: Platform and versions
|
||||
description: "Provide OS, browser and Cinny version with your Homeserver."
|
||||
placeholder: |
|
||||
1. OS: [e.g. Windows 10, MacOS]
|
||||
2. Browser: [e.g. chrome 99.5, firefox 97.2]
|
||||
3. Cinny version: [e.g. 1.8.1 (app.cinny.in)]
|
||||
4. Matrix homeserver: [e.g. matrix.org]
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: context
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context about the problem here.
|
||||
@@ -1,5 +1,4 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Features, Bug Reports, Questions
|
||||
url: https://github.com/cinnyapp/cinny/discussions/new/choose
|
||||
about: Our preferred starting point if you have any questions or suggestions about features or behavior.
|
||||
- name: 💬 Matrix Chat
|
||||
url: https://matrix.to/#/#cinny:matrix.org
|
||||
about: Ask questions and talk to other Cinny users and the maintainers
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
name: 💡 Feature Request
|
||||
description: Suggest an idea
|
||||
|
||||
body:
|
||||
- type: textarea
|
||||
id: problem
|
||||
attributes:
|
||||
label: Describe the problem
|
||||
description: A clear description of the problem this feature would solve
|
||||
placeholder: "I'm always frustrated when..."
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: solution
|
||||
attributes:
|
||||
label: "Describe the solution you'd like"
|
||||
description: A clear description of what change you would like
|
||||
placeholder: "I would like to..."
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: alternatives
|
||||
attributes:
|
||||
label: Alternatives considered
|
||||
description: "Any alternative solutions you've considered"
|
||||
|
||||
- type: textarea
|
||||
id: context
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context about the problem here.
|
||||
@@ -1,9 +0,0 @@
|
||||
---
|
||||
name: Pre-Discussed and Approved Topics
|
||||
about: |-
|
||||
Only for topics already discussed and approved in the GitHub Discussions section.
|
||||
---
|
||||
|
||||
**DO NOT OPEN A NEW ISSUE. PLEASE USE THE DISCUSSIONS SECTION.**
|
||||
|
||||
**I DIDN'T READ THE ABOVE LINE. PLEASE CLOSE THIS ISSUE.**
|
||||
@@ -0,0 +1,22 @@
|
||||
<!-- Please read https://github.com/ajbura/cinny/blob/dev/CONTRIBUTING.md before submitting your pull request -->
|
||||
|
||||
### Description
|
||||
<!-- Please include a summary of the change. Please also include relevant motivation and context. List any dependencies that are required for this change. -->
|
||||
|
||||
|
||||
Fixes #
|
||||
|
||||
#### Type of change
|
||||
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
- [ ] This change requires a documentation update
|
||||
|
||||
### Checklist:
|
||||
|
||||
- [ ] My code follows the style guidelines of this project
|
||||
- [ ] I have performed a self-review of my own code
|
||||
- [ ] I have commented my code, particularly in hard-to-understand areas
|
||||
- [ ] I have made corresponding changes to the documentation
|
||||
- [ ] My changes generate no new warnings
|
||||
@@ -0,0 +1,3 @@
|
||||
# Reporting a Vulnerability
|
||||
|
||||
**If you've found a security vulnerability, please report it to cinnyapp@gmail.com**
|
||||
@@ -2,29 +2,29 @@
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
# - package-ecosystem: npm
|
||||
# directory: /
|
||||
# schedule:
|
||||
# interval: weekly
|
||||
# day: "tuesday"
|
||||
# time: "01:00"
|
||||
# timezone: "Asia/Kolkata"
|
||||
# open-pull-requests-limit: 15
|
||||
- package-ecosystem: npm
|
||||
directory: /
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: "tuesday"
|
||||
time: "01:00"
|
||||
timezone: "Asia/Kolkata"
|
||||
open-pull-requests-limit: 15
|
||||
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: 'tuesday'
|
||||
time: '01:00'
|
||||
timezone: 'Asia/Kolkata'
|
||||
day: "tuesday"
|
||||
time: "01:00"
|
||||
timezone: "Asia/Kolkata"
|
||||
open-pull-requests-limit: 5
|
||||
|
||||
- package-ecosystem: docker
|
||||
directory: /
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: 'tuesday'
|
||||
time: '01:00'
|
||||
timezone: 'Asia/Kolkata'
|
||||
day: "tuesday"
|
||||
time: "01:00"
|
||||
timezone: "Asia/Kolkata"
|
||||
open-pull-requests-limit: 5
|
||||
|
||||
@@ -1,26 +1,15 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:recommended",
|
||||
":dependencyDashboardApproval",
|
||||
":semanticCommits",
|
||||
"group:monorepos"
|
||||
"config:base",
|
||||
":dependencyDashboardApproval"
|
||||
],
|
||||
"labels": ["Dependencies"],
|
||||
"rebaseWhen": "conflicted",
|
||||
"labels": [ "Dependencies" ],
|
||||
"packageRules": [
|
||||
{
|
||||
"matchUpdateTypes": ["lockFileMaintenance"]
|
||||
},
|
||||
{
|
||||
"matchPackageNames": ["slate", "slate-dom", "slate-history", "slate-react"]
|
||||
},
|
||||
{
|
||||
"matchPackageNames": ["linkifyjs", "linkify-react"]
|
||||
"matchUpdateTypes": [ "lockFileMaintenance" ]
|
||||
}
|
||||
],
|
||||
"lockFileMaintenance": {
|
||||
"enabled": true
|
||||
},
|
||||
"lockFileMaintenance": { "enabled": true },
|
||||
"dependencyDashboard": true
|
||||
}
|
||||
}
|
||||
@@ -12,20 +12,20 @@ jobs:
|
||||
PR_NUMBER: ${{github.event.number}}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@v3.5.3
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
uses: actions/setup-node@v3.8.1
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
package-manager-cache: false
|
||||
node-version: 18.12.1
|
||||
cache: "npm"
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Build app
|
||||
env:
|
||||
NODE_OPTIONS: '--max_old_space_size=4096'
|
||||
NODE_OPTIONS: "--max_old_space_size=4096"
|
||||
run: npm run build
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
uses: actions/upload-artifact@v3.1.2
|
||||
with:
|
||||
name: preview
|
||||
path: dist
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
- name: Save pr number
|
||||
run: echo ${PR_NUMBER} > ./pr.txt
|
||||
- name: Upload pr number
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
uses: actions/upload-artifact@v3.1.2
|
||||
with:
|
||||
name: pr
|
||||
path: ./pr.txt
|
||||
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
- name: 'CLA Assistant'
|
||||
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
|
||||
# Beta Release
|
||||
uses: cla-assistant/github-action@ca4a40a7d1004f18d9960b404b97e5f30a505a08 # v2.6.1
|
||||
uses: cla-assistant/github-action@v2.3.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# the below token should have repo scope and must be manually added by you in the repository's secret
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
name: Deploy PR to Netlify
|
||||
run-name: 'Deploy PR to Netlify (${{ github.event.workflow_run.head_branch }})'
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ['Build pull request']
|
||||
types: [completed]
|
||||
workflows: ["Build pull request"]
|
||||
types: [completed]
|
||||
|
||||
jobs:
|
||||
deploy-pull-request:
|
||||
@@ -16,22 +15,16 @@ jobs:
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
steps:
|
||||
- name: Download pr number
|
||||
uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 # v21
|
||||
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615
|
||||
with:
|
||||
workflow: ${{ github.event.workflow.id }}
|
||||
run_id: ${{ github.event.workflow_run.id }}
|
||||
name: pr
|
||||
- name: Validate and output pr number
|
||||
- name: Output pr number
|
||||
id: pr
|
||||
run: |
|
||||
PR_ID=$(<pr.txt)
|
||||
if ! [[ "${PR_ID}" =~ ^[0-9]+$ ]]; then
|
||||
echo "::error::pr.txt contains non-numeric content: ${PR_ID}"
|
||||
exit 1
|
||||
fi
|
||||
echo "id=${PR_ID}" >> "${GITHUB_OUTPUT}"
|
||||
run: echo "id=$(<pr.txt)" >> $GITHUB_OUTPUT
|
||||
- name: Download artifact
|
||||
uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 # v21
|
||||
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615
|
||||
with:
|
||||
workflow: ${{ github.event.workflow.id }}
|
||||
run_id: ${{ github.event.workflow_run.id }}
|
||||
@@ -39,25 +32,25 @@ jobs:
|
||||
path: dist
|
||||
- name: Deploy to Netlify
|
||||
id: netlify
|
||||
uses: nwtgck/actions-netlify@4cbaf4c08f1a7bfa537d6113472ef4424e4eb654 # v3.0.0
|
||||
uses: nwtgck/actions-netlify@7a92f00dde8c92a5a9e8385ec2919775f7647352
|
||||
with:
|
||||
publish-dir: dist
|
||||
deploy-message: 'Deploy PR ${{ steps.pr.outputs.id }}'
|
||||
deploy-message: "Deploy PR ${{ steps.pr.outputs.id }}"
|
||||
alias: ${{ steps.pr.outputs.id }}
|
||||
# These don't work because we're in workflow_run
|
||||
enable-pull-request-comment: false
|
||||
enable-commit-comment: false
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN_PR }}
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID_PR_CINNY }}
|
||||
timeout-minutes: 1
|
||||
- name: Comment preview on PR
|
||||
uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b #v3.0.1
|
||||
uses: thollander/actions-comment-pull-request@1d3973dc4b8e1399c0620d3f2b1aa5e795465308
|
||||
env:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
pr-number: ${{ steps.pr.outputs.id }}
|
||||
comment-tag: ${{ steps.pr.outputs.id }}
|
||||
pr_number: ${{ steps.pr.outputs.id }}
|
||||
comment_tag: ${{ steps.pr.outputs.id }}
|
||||
message: |
|
||||
Preview: ${{ steps.netlify.outputs.deploy-url }}
|
||||
⚠️ Exercise caution. Use test accounts. ⚠️
|
||||
Preview: ${{ steps.netlify.outputs.deploy-url }}
|
||||
⚠️ Exercise caution. Use test accounts. ⚠️
|
||||
@@ -5,59 +5,15 @@ on:
|
||||
paths:
|
||||
- 'Dockerfile'
|
||||
- '.github/workflows/docker-pr.yml'
|
||||
- '.github/workflows/prod-deploy.yml'
|
||||
|
||||
jobs:
|
||||
docker-build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||
|
||||
- name: Login to Docker Hub #Do not update this action from a outside PR
|
||||
if: github.event.pull_request.head.repo.fork == false
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
continue-on-error: true
|
||||
|
||||
- name: Login to the Github Container registry #Do not update this action from a outside PR
|
||||
if: github.event.pull_request.head.repo.fork == false
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
continue-on-error: true
|
||||
|
||||
- name: Extract metadata (tags, labels) for Docker, GHCR
|
||||
id: meta
|
||||
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
|
||||
with:
|
||||
images: |
|
||||
ajbura/cinny
|
||||
ghcr.io/${{ github.repository }}
|
||||
|
||||
- name: Build Docker image (no push)
|
||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
|
||||
uses: actions/checkout@v3.5.3
|
||||
- name: Build Docker image
|
||||
uses: docker/build-push-action@v4.1.1
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64
|
||||
push: false
|
||||
load: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
- name: Show Docker images
|
||||
run: docker images
|
||||
|
||||
@@ -14,13 +14,13 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@v3.5.3
|
||||
- name: NPM Lockfile Changes
|
||||
uses: codepunkt/npm-lockfile-changes@b40543471c36394409466fdb277a73a0856d7891 # v1.0.0
|
||||
uses: codepunkt/npm-lockfile-changes@b40543471c36394409466fdb277a73a0856d7891
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Optional inputs, can be deleted safely if you are happy with default values.
|
||||
collapsibleThreshold: 25
|
||||
failOnDowngrade: false
|
||||
path: package-lock.json
|
||||
updateComment: true
|
||||
updateComment: true
|
||||
@@ -3,7 +3,7 @@ name: Deploy to Netlify (dev)
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- dev
|
||||
|
||||
jobs:
|
||||
deploy-to-netlify:
|
||||
@@ -11,23 +11,23 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@v3.5.3
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
uses: actions/setup-node@v3.8.1
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
package-manager-cache: false
|
||||
node-version: 18.12.1
|
||||
cache: "npm"
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Build app
|
||||
env:
|
||||
NODE_OPTIONS: '--max_old_space_size=4096'
|
||||
NODE_OPTIONS: "--max_old_space_size=4096"
|
||||
run: npm run build
|
||||
- name: Deploy to Netlify
|
||||
uses: nwtgck/actions-netlify@4cbaf4c08f1a7bfa537d6113472ef4424e4eb654 # v3.0.0
|
||||
uses: nwtgck/actions-netlify@7a92f00dde8c92a5a9e8385ec2919775f7647352
|
||||
with:
|
||||
publish-dir: dist
|
||||
deploy-message: 'Dev deploy ${{ github.sha }}'
|
||||
deploy-message: "Dev deploy ${{ github.sha }}"
|
||||
enable-commit-comment: false
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
production-deploy: true
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
name: Check PR title
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -10,23 +10,23 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@v3.5.3
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
uses: actions/setup-node@v3.8.1
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
package-manager-cache: false
|
||||
node-version: 18.12.1
|
||||
cache: "npm"
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Build app
|
||||
env:
|
||||
NODE_OPTIONS: '--max_old_space_size=4096'
|
||||
NODE_OPTIONS: "--max_old_space_size=4096"
|
||||
run: npm run build
|
||||
- name: Deploy to Netlify
|
||||
uses: nwtgck/actions-netlify@4cbaf4c08f1a7bfa537d6113472ef4424e4eb654 # v3.0.0
|
||||
uses: nwtgck/actions-netlify@7a92f00dde8c92a5a9e8385ec2919775f7647352
|
||||
with:
|
||||
publish-dir: dist
|
||||
deploy-message: 'Prod deploy ${{ github.ref_name }}'
|
||||
deploy-message: "Prod deploy ${{ github.ref_name }}"
|
||||
enable-commit-comment: false
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
production-deploy: true
|
||||
@@ -52,45 +52,45 @@ jobs:
|
||||
gpg --export | xxd -p
|
||||
echo '${{ secrets.GNUPG_PASSPHRASE }}' | gpg --batch --yes --pinentry-mode loopback --passphrase-fd 0 --armor --detach-sign cinny-${{ steps.vars.outputs.tag }}.tar.gz
|
||||
- name: Upload tagged release
|
||||
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
|
||||
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844
|
||||
with:
|
||||
files: |
|
||||
cinny-${{ steps.vars.outputs.tag }}.tar.gz
|
||||
cinny-${{ steps.vars.outputs.tag }}.tar.gz.asc
|
||||
|
||||
publish-image:
|
||||
name: Push Docker image to Docker Hub, GHCR
|
||||
name: Push Docker image to Docker Hub, ghcr
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@v3.5.3
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
|
||||
uses: docker/setup-qemu-action@v2.2.0
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||
- name: Login to Docker Hub #Do not update this action from a outside PR
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
||||
uses: docker/setup-buildx-action@v2.7.0
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Login to the Github Container registry #Do not update this action from a outside PR
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
||||
- name: Login to the Container registry
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Extract metadata (tags, labels) for Docker, GHCR
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
|
||||
uses: docker/metadata-action@v4.6.0
|
||||
with:
|
||||
images: |
|
||||
${{ secrets.DOCKER_USERNAME }}/cinny
|
||||
ghcr.io/${{ github.repository }}
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
|
||||
uses: docker/build-push-action@v4.1.1
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
|
||||
@@ -4,5 +4,3 @@ node_modules
|
||||
devAssets
|
||||
|
||||
.DS_Store
|
||||
.ideapackage-lock.json
|
||||
public/decorations/
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
# These are commented until we enable lint and typecheck
|
||||
# npx tsc -p tsconfig.json --noEmit
|
||||
# npx lint-staged
|
||||
@@ -1 +0,0 @@
|
||||
24.13.1
|
||||
@@ -1,2 +1,3 @@
|
||||
legacy-peer-deps=true
|
||||
save-exact=true
|
||||
save-exact=true
|
||||
@matrix-org:registry=https://gitlab.matrix.org/api/v4/projects/27/packages/npm/
|
||||
@@ -1,128 +0,0 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
- Demonstrating empathy and kindness toward other people
|
||||
- Being respectful of differing opinions, viewpoints, and experiences
|
||||
- Giving and gracefully accepting constructive feedback
|
||||
- Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
- Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
- The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
- Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
- Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
cinnyapp@gmail.com.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
@@ -5,7 +5,6 @@ First off, thanks for taking the time to contribute! ❤️
|
||||
All types of contributions are encouraged and valued. Please make sure to read the relevant section before making your contribution. It will make it a lot easier for us maintainers and smooth out the experience for all involved. The community looks forward to your contributions. 🎉
|
||||
|
||||
> And if you like the project, but just don't have time to contribute, that's fine. There are other easy ways to support the project and show your appreciation, which we would also be very happy about:
|
||||
>
|
||||
> - Star the project
|
||||
> - Tweet about it (tag @cinnyapp)
|
||||
> - Refer this project in your project's readme
|
||||
@@ -19,8 +18,7 @@ Bug reports and feature suggestions must use descriptive and concise titles and
|
||||
## Pull requests
|
||||
|
||||
> ### Legal Notice
|
||||
>
|
||||
> When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project license. You will also be asked to [sign the CLA](https://github.com/cinnyapp/cla) upon submiting your pull request.
|
||||
> When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project license.
|
||||
|
||||
**NOTE: If you want to add new features, please discuss with maintainers before coding or opening a pull request.** This is to ensure that we are on same track and following our roadmap.
|
||||
|
||||
@@ -28,9 +26,9 @@ Bug reports and feature suggestions must use descriptive and concise titles and
|
||||
|
||||
Example:
|
||||
|
||||
| Not ideal | Better |
|
||||
| ----------------------------------- | --------------------------------------------- |
|
||||
| Fixed markAllAsRead in RoomTimeline | Fix read marker when paginating room timeline |
|
||||
|Not ideal|Better|
|
||||
|---|----|
|
||||
|Fixed markAllAsRead in RoomTimeline|Fix read marker when paginating room timeline|
|
||||
|
||||
It is not always possible to phrase every change in such a manner, but it is desired.
|
||||
|
||||
@@ -41,7 +39,6 @@ Also, we use [ESLint](https://eslint.org/) for clean and stylistically consisten
|
||||
**For any query or design discussion, join our [Matrix room](https://matrix.to/#/#cinny:matrix.org).**
|
||||
|
||||
## Helpful links
|
||||
|
||||
- [BEM methodology](http://getbem.com/introduction/)
|
||||
- [Atomic design](https://bradfrost.com/blog/post/atomic-web-design/)
|
||||
- [Matrix JavaScript SDK documentation](https://matrix-org.github.io/matrix-js-sdk/index.html)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
## Builder
|
||||
FROM node:24.13.1-alpine AS builder
|
||||
FROM node:18.12.1-alpine3.15 as builder
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
@@ -11,10 +11,9 @@ RUN npm run build
|
||||
|
||||
|
||||
## App
|
||||
FROM nginx:1.29.8-alpine
|
||||
FROM nginx:1.25.1-alpine
|
||||
|
||||
COPY --from=builder /src/dist /app
|
||||
COPY --from=builder /src/docker-nginx.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
RUN rm -rf /usr/share/nginx/html \
|
||||
&& ln -s /app /usr/share/nginx/html
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
# Lotus Chat — Bug Report & Technical Audit
|
||||
**Date:** June 2026
|
||||
|
||||
This document tracks identified bugs, edge cases, and architectural discrepancies found during the audit of the Lotus Chat codebase. Recommended fixes are provided for each item.
|
||||
|
||||
---
|
||||
|
||||
## 🛡️ Critical Security & Privacy Regressions
|
||||
|
||||
### 1. E2EE Bypass in Media Gallery Downloads
|
||||
**File:** `src/app/features/room/MediaGallery.tsx` (Line 855)
|
||||
**Status:** **CRITICAL**
|
||||
|
||||
* **Issue:** The "Download" button in the Files tab uses `mxcUrlToHttp` directly and clicks an `<a>` link.
|
||||
* **Impact:** In encrypted rooms, this downloads the encrypted ciphertext rather than the decrypted file. Users cannot open the downloaded files.
|
||||
* **Recommended Fix:**
|
||||
1. Check if the event is encrypted.
|
||||
2. If encrypted, use the `decryptAttachment` logic (similar to `useDecryptedMediaUrl`) to decrypt the file in memory.
|
||||
3. Use `file-saver` or a Blob URL to trigger the download of the decrypted plaintext.
|
||||
|
||||
### 2. Privacy Leak in URL Previews
|
||||
**File:** `src/app/components/url-preview/UrlPreviewCard.tsx` (Line 1655)
|
||||
**Status:** **PRIVACY RISK**
|
||||
|
||||
* **Issue:** Generic URL preview cards fetch favicons directly from `https://www.google.com/s2/favicons?domain=...`.
|
||||
* **Impact:** This leaks the user's browsing/chat activity (domains of links they see) to Google. It bypasses the "proxied through Matrix" privacy standard.
|
||||
* **Recommended Fix:** Use the proxy URL returned by the Matrix `/_matrix/media/v3/preview_url` endpoint instead of contacting Google directly.
|
||||
|
||||
---
|
||||
|
||||
## 🚩 Functional & Logic Bugs
|
||||
|
||||
### 1. Presence Updater Reverts Status Updates
|
||||
**File:** `src/app/hooks/usePresenceUpdater.ts` (Line 20)
|
||||
**Status:** ✅ RESOLVED (June 2026)
|
||||
|
||||
* **Issue:** The `storedStatus` variable was captured once when the `useEffect` started.
|
||||
* **Impact:** If a user updated their status message in Profile Settings, the hook would continue broadcasting the old message on every activity event, silently reverting the change.
|
||||
* **Fix Applied:** Replaced the single `localStorage.getItem` read with a `readStatus()` function called inside every `setOnline` and `setUnavailable` invocation, ensuring the current value is always used.
|
||||
|
||||
### 2. Audio Playback Rate Reset
|
||||
**File:** `src/app/components/message/content/AudioContent.tsx` (Line 97)
|
||||
**Status:** UX Bug
|
||||
|
||||
* **Issue:** The `playbackRate` is set in a `useEffect` that only depends on `[playbackSpeed]`.
|
||||
* **Impact:** If a user selects a playback speed *before* the audio blob has finished loading, the `<audio>` element may reset its rate to 1.0 once the `<source>` is added.
|
||||
* **Recommended Fix:** Add `srcState.data` to the `useEffect` dependencies or set the `playbackRate` in an `onCanPlay` handler on the audio element.
|
||||
|
||||
### 3. Room Insights are Static (No Live Updates)
|
||||
**File:** `src/app/features/room-settings/RoomInsights.tsx` (Line 60)
|
||||
**Status:** Medium Priority
|
||||
|
||||
* **Issue:** Stats are calculated in a `useMemo` that only depends on `[room]`.
|
||||
* **Impact:** If new messages arrive while the Insights page is open, the statistics (message counts, top participants, etc.) do not update.
|
||||
* **Recommended Fix:** Add a listener for `RoomEvent.Timeline` inside the component to trigger a recalculation when new events are added to the room.
|
||||
|
||||
### 4. Incorrect Ringing in Voice Rooms
|
||||
**File:** `src/app/components/CallEmbedProvider.tsx`
|
||||
**Status:** ✅ RESOLVED (June 2026)
|
||||
|
||||
* **Issue:** Joining a static voice room (Public Space channel) triggered the "Incoming Call" ringing animation and sound.
|
||||
* **Root Cause:** `getStateEvent(room, StateEvent.SpaceParent)` always returned `undefined` because `m.space.parent` events use the parent space's room ID as the state key, not an empty string. The ringing suppression check silently failed.
|
||||
* **Fix Applied:** Replaced `getStateEvent` with `getStateEvents` (plural), which returns all events of a given type regardless of state key. A room with any `m.space.parent` event is correctly identified as a space channel and suppresses ringing.
|
||||
|
||||
---
|
||||
|
||||
## 🎨 UI/UX & Visual Consistency
|
||||
|
||||
### 1. Hardcoded Primary Color in Polls
|
||||
**File:** `src/app/components/message/content/PollContent.tsx` (Line 245)
|
||||
**Status:** TDS Violation
|
||||
|
||||
* **Issue:** Uses `rgba(var(--mx-primary-rgb, 0,132,255), ...)` for selected options and borders.
|
||||
* **Impact:** Polls look like standard Cinny and ignore the Lotus Terminal Design System (TDS) colors.
|
||||
* **Recommended Fix:** Use `var(--lt-accent-cyan)` or the primary theme accent color.
|
||||
|
||||
### 2. Inaccessible Room Menu on Mobile
|
||||
**File:** `src/app/features/room-nav/RoomNavItem.tsx` (Line 643)
|
||||
**Status:** **MOBILE BUG**
|
||||
|
||||
* **Issue:** The room menu icon (`VerticalDots`) is hidden on mobile because `hover` is never active.
|
||||
* **Impact:** Mobile users cannot access room settings, mark as read, or leave rooms from the sidebar.
|
||||
* **Recommended Fix:** Ensure the menu button is visible on mobile for the active room or provide an alternative trigger.
|
||||
|
||||
### 3. Inconsistent Settings Dropdown Styling
|
||||
**File:** `src/app/features/settings/general/General.tsx`
|
||||
**Status:** ✅ RESOLVED (June 2026)
|
||||
|
||||
* **Issue:** The dropdowns for "Join & Leave Sounds", "UI Font", and "Seasonal Theme" used raw HTML `<select>` elements, which render differently from the custom-styled `Menu`+`PopOut` used for "Message Layout" and other settings.
|
||||
* **Fix Applied:** All three raw `<select>` elements replaced with a reusable `SettingsSelect` component using the Menu+PopOut+FocusTrap pattern consistent with the rest of the settings UI.
|
||||
|
||||
### 4. No Camera Focus During Screenshare
|
||||
**File:** `src/app/features/call/CallControls.tsx`
|
||||
**Status:** UX Bug — blocked by Element Call internals
|
||||
|
||||
* **Issue:** When someone is screensharing and another participant turns on their camera, there is no way to switch the primary display to the camera or go fullscreen on it.
|
||||
* **Root Cause:** Element Call's spotlight/layout is controlled internally by EC. Lotus Chat injects the call iframe and cannot easily override EC's participant tile behavior without forking the EC widget.
|
||||
* **Recommended Fix:** Implement a "Pin/Focus" toggle on participant tiles that overrides the automatic screenshare spotlight — requires EC upstream changes or a custom message bridge.
|
||||
|
||||
### 5. Ringing Modal Fires in Persistent Voice Rooms
|
||||
**File:** `src/app/components/CallEmbedProvider.tsx` (line 337–342)
|
||||
**Status:** ✅ RESOLVED (June 2026)
|
||||
|
||||
* **Issue:** Joining a persistent voice room (not a DM or transient group call) showed the incoming call ringing modal and animation.
|
||||
* **Root Cause:** The `isPrivateGroup` condition included `JoinRule.Restricted` and `JoinRule.Knock` rooms. Lotus Guild voice rooms are `Restricted` join-rule rooms. Their `m.space.parent` state event was being checked but some rooms were set up with only the space-side `m.space.child` relationship, leaving no `m.space.parent` on the room itself — so they passed as `isPrivateGroup` and triggered ringing.
|
||||
* **Fix Applied:** Narrowed `isPrivateGroup` to only `JoinRule.Invite` to match the exact set of rooms where the call button is shown. Also added `room.isCallRoom()` early-exit so rooms with `m.join_rule.call` type never ring.
|
||||
|
||||
### 6. Animated Chat Backgrounds Affect Message Content
|
||||
**File:** `src/app/features/lotus/chatBackground.ts`
|
||||
**Status:** ✅ RESOLVED (June 2026)
|
||||
|
||||
* **Issue:** Animated backgrounds that use `filter: brightness()` or `opacity` animations (Digital Rain glow, Grid Pulse brightness, Fireflies glow/blink) applied those effects to the entire `<Page>` element, causing all message content and the composer to flash/flicker in sync with the animation.
|
||||
* **Root Cause:** `filter` and `opacity` CSS properties affect an element AND all its descendants. Applying these as part of the `animation` shorthand on the `Page` container made them "inherited" visually by everything inside the room view.
|
||||
* **Side Effect:** `filter` animation also created a CSS stacking context on Page, which pushed Seasonal Theme overlays (position:fixed; z-index:9997) behind the Page compositor layer.
|
||||
* **Fix Applied:** Removed `animRainGlowKeyframe`, `animGridBrightnessKeyframe`, `animFirefliesGlowKeyframe`, and `animFirefliesBlinkKeyframe` from `chatBackground.ts`. Only `backgroundPosition` / `backgroundSize` animations remain — these are safe and do not affect descendants or create stacking contexts.
|
||||
|
||||
### 7. Seasonal Themes Display Behind Chat Background
|
||||
**File:** `src/app/components/seasonal/SeasonalEffect.tsx`
|
||||
**Status:** ✅ RESOLVED (June 2026) — root cause was Bug #6
|
||||
|
||||
* **Issue:** Seasonal theme overlays (position:fixed; z-index:9997) appeared behind animated chat backgrounds.
|
||||
* **Root Cause:** The `filter` animation on `<Page>` created a CSS stacking context, causing Page's GPU compositing layer to render above the fixed-position seasonal overlay in some browsers. Removing the filter animations (Bug #6 fix) resolves the stacking context issue.
|
||||
* **Fix Applied:** See Bug #6. No additional changes to SeasonalEffect required.
|
||||
|
||||
### 8. Avatar Decoration Images Not Rendering in Settings
|
||||
**File:** `src/app/features/settings/account/ProfileDecoration.tsx`
|
||||
**Status:** ✅ RESOLVED (June 2026)
|
||||
|
||||
* **Issue:** Under Settings → Account → Avatar Decoration, no decoration images were visible.
|
||||
* **Root Cause:** The `DecorationPreviewCell` used `loading="lazy"` on decoration images. The browser's lazy-loading algorithm determines image visibility from the viewport, but the decoration grid is inside a nested `overflowY: auto` scroll container inside a settings panel — the browser did not correctly detect these images as near the viewport and never triggered them to load.
|
||||
* **Fix Applied:** Changed `loading="lazy"` to `loading="eager"` in `DecorationPreviewCell`. The settings panel is user-initiated, so eager loading is appropriate.
|
||||
@@ -1,470 +0,0 @@
|
||||
# Lotus Chat — Work Backlog
|
||||
|
||||
**Repo:** `lotus` branch at `https://code.lotusguild.org/LotusGuild/cinny`
|
||||
**Deploy:** push to `lotus` → CI → auto-deploy to `chat.lotusguild.org` (~11 min)
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ TDS DESIGN LAW — READ BEFORE TOUCHING ANY UI
|
||||
|
||||
> **ALL Lotus Terminal Design System (TDS) styling — colors, animations, glows, borders, fonts, spacing — MUST come exclusively from `/root/code/web_template/base.css` CSS variables.**
|
||||
> Do NOT hardcode hex values. Do NOT invent new variable names. Do NOT deviate from the design tokens defined in that file.
|
||||
> The canonical variable reference: `--lt-accent-orange`, `--lt-accent-cyan`, `--lt-accent-green`, `--lt-glow-orange`, `--lt-box-glow-*`, `--lt-border-color`, etc.
|
||||
> Reference implementation for code patterns: `/root/code/tinker_tickets/` (markdown.js, base.js, ticket.css)
|
||||
> This rule applies to EVERY task in this file without exception.
|
||||
|
||||
---
|
||||
|
||||
Completed features are documented in [LOTUS_FEATURES.md](./LOTUS_FEATURES.md).
|
||||
|
||||
---
|
||||
|
||||
Legend:
|
||||
|
||||
- `[AUDIT REQUIRED]` — at least one assumption needs code/server verification before implementing
|
||||
- `[SERVER CHECK]` — depends on a Synapse feature or MSC; verify on `matrix.lotusguild.org`
|
||||
- `[LOW PRIORITY]` — implement after all higher-priority items
|
||||
- `[EXTREME COMPLEXITY]` — multi-sprint, plan separately before touching
|
||||
- `[BLOCKED]` — cannot build until a server upgrade, upstream MSC, or dependency resolves
|
||||
- `[IMPROVE]` — feature exists in upstream Cinny; this task enhances it for Lotus Chat
|
||||
|
||||
Status: `[ ]` pending · `[~]` in progress · `[x]` completed
|
||||
|
||||
---
|
||||
|
||||
## Server Capabilities (as of June 2026)
|
||||
|
||||
- **Homeserver:** `matrix.lotusguild.org`
|
||||
- **Synapse version:** `1.153.0` (2026-05-19) — fully up to date
|
||||
- **Matrix spec:** up to `v1.12` formally; newer MSC features via `unstable_features`
|
||||
|
||||
### Confirmed facts
|
||||
|
||||
| Finding | Impact |
|
||||
| ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
|
||||
| **MSC flags ON:** `msc4140` · `msc3771` · `msc3440.stable` · `msc4133.stable` · `simplified_msc3575` | All safe to use now |
|
||||
| **MSC flags OFF:** `msc4306` (thread subscriptions) · `msc3882` · `msc3912` · `msc4155` | These features are BLOCKED |
|
||||
| **MSC3266** room summary: returns 404 | Room Preview feature BLOCKED |
|
||||
| **MSC3892** relation redaction: not in flags | Reaction Redaction feature BLOCKED |
|
||||
| **MSC4260** report user: server at v1.12, endpoint may not exist | Report User feature BLOCKED |
|
||||
| **MSC4151** report room: HTTP 405 on GET = endpoint exists (POST only) | Report Room live ✅ |
|
||||
| `folds AvatarImage` does NOT accept children | Add frame/overlay inside `UserAvatar.tsx` itself — optional `frameName` prop |
|
||||
| No in-app toast system exists (was) | Built `ToastProvider` + Jotai queue; at `App.tsx:65` |
|
||||
| `useUnverifiedDeviceCount()` hook exists | `src/app/hooks/useDeviceVerificationStatus.ts:65-106` |
|
||||
| Voice player: `AudioContent.tsx:44-223` | Playback rate on hidden `<audio>` at line 217 |
|
||||
| `CallControl.setMicrophone(bool)` at `CallControl.ts:206-212` | For AFK auto-mute |
|
||||
| `CallControl.toggleSound()` at `CallControl.ts:230-251` | Push-to-deafen — just wire a hotkey to this |
|
||||
| matrix-js-sdk has NO arbitrary profile field methods | Use `mx.http.authedRequest()` for MSC4133 |
|
||||
| Sanitizer (`sanitize.ts`) allows table, div, span, a, code, hr | LFG HTML card is safe locally; test on Element/FluffyChat |
|
||||
| Sanitizer STRIPS `<math>`/MathML tags | Math/LaTeX task must also modify sanitizer |
|
||||
| Service worker EXISTS at `src/sw.ts` | Quick-reply task: add `notificationclick` handler |
|
||||
| `knockSupported()` utility exists at `matrix.ts:376-391` | Knock UX: only need "Request to Join" in `RoomIntro.tsx` |
|
||||
| `KeywordMessages.tsx` already has custom keyword push rules | Full push rule editor: only non-keyword rule types need new UI |
|
||||
| `getMatrixToRoom()` in `matrix-to.ts` generates invite URLs | Invite link: just add QR code to room settings |
|
||||
| Cindy CANNOT inject audio into EC call stream | In-call soundboard must be redesigned as local-only |
|
||||
| Folds uses vanilla-extract in non-TDS, NOT CSS custom properties | Custom accent color: must create new vanilla-extract theme variant dynamically |
|
||||
| Theme presets need ~50 CSS custom properties each | Significant design work before coding |
|
||||
| `useCallSpeakers.ts` CSS MutationObserver polling | Visual speaking indicator: TDS ring animation on top of existing data |
|
||||
| MSC3489/3672 live location: BOTH false on server | Live Location BLOCKED |
|
||||
|
||||
---
|
||||
|
||||
## Key File Reference
|
||||
|
||||
| What you need | File | Lines |
|
||||
| -------------------------------- | ------------------------------------------------------------- | ------------------- |
|
||||
| Global keydown hook | `src/app/hooks/useKeyDown.ts` | whole file |
|
||||
| Room navigation | `src/app/hooks/useRoomNavigate.ts` | 19-72 |
|
||||
| All room IDs atom | `src/app/state/room-list/roomList.ts` | `allRoomsAtom` |
|
||||
| Room unread counts | `src/app/state/room/roomToUnread.ts` | `roomToUnreadAtom` |
|
||||
| Overlay portal provider | `src/app/pages/App.tsx` | 65 |
|
||||
| Portal container div | `index.html` | 101 |
|
||||
| Room settings tabs | `src/app/features/room-settings/RoomSettings.tsx` | 27-56 |
|
||||
| State event read/write pattern | `src/app/features/common-settings/general/RoomEncryption.tsx` | 42-52 |
|
||||
| Power level checker | `src/app/hooks/usePowerLevels.ts` | whole file |
|
||||
| Slash command registration | `src/app/hooks/useCommands.ts` | 140-537 |
|
||||
| Chat background picker | `src/app/features/settings/general/General.tsx` | 945-981 |
|
||||
| Chat backgrounds definition | `src/app/features/lotus/chatBackground.ts` | whole file |
|
||||
| Matrix.to URL builder | `src/app/plugins/matrix-to.ts` | `getMatrixToRoom()` |
|
||||
| Media event content types | `src/app/types/matrix/common.ts` | 46-91 |
|
||||
| Media URL conversion | `src/app/utils/matrix.ts` | `mxcUrlToHttp()` |
|
||||
| Message pagination (search) | `src/app/features/message-search/useMessageSearch.ts` | 74-121 |
|
||||
| Infinite pagination pattern | `src/app/features/message-search/MessageSearch.tsx` | 234-365 |
|
||||
| Poll event format | `src/app/components/message/content/PollContent.tsx` | 1-320 |
|
||||
| Theme class application | `src/app/hooks/useTheme.ts` | 25-60 |
|
||||
| Animations file | `src/app/styles/Animations.css.ts` | whole file |
|
||||
| Message status (EventStatus) | `src/app/features/room/message/Message.tsx` | 84-142 |
|
||||
| Call member change events | `src/app/hooks/useCall.ts` | 37-52 |
|
||||
| Mic control in calls | `src/app/plugins/call/CallControl.ts` | 206-212 |
|
||||
| Device verification hook | `src/app/hooks/useDeviceVerificationStatus.ts` | 65-106 |
|
||||
| Knock room support check | `src/app/utils/matrix.ts` | 376-391 |
|
||||
| Room join button location | `src/app/components/room-intro/RoomIntro.tsx` | 25-119 |
|
||||
| Notification mute via push rules | `src/app/hooks/useRoomsNotificationPreferences.ts` | 110-150 |
|
||||
| Message text body CSS | `src/app/components/message/layout/layout.css.ts` | 182-205 |
|
||||
|
||||
---
|
||||
|
||||
## Priority 3 — Higher complexity / lower daily frequency
|
||||
|
||||
### [ ] P3-4 · Accessibility Improvements (WCAG 2.1 AA)
|
||||
|
||||
**What:** Comprehensive audit and fix pass targeting the critical user paths:
|
||||
|
||||
- Room list navigation (keyboard-only)
|
||||
- Reading messages in the timeline (screen reader announces new messages)
|
||||
- Composing and sending a reply
|
||||
- Opening and closing modals (focus trap, return focus)
|
||||
- ARIA labels on all icon-only buttons
|
||||
**Scope:** Do NOT attempt to make every corner of the app AA-compliant in one pass — focus on the golden path (open app → find room → read → reply → send).
|
||||
**[AUDIT REQUIRED]** — Run an automated audit first: `npx axe-core` or browser DevTools accessibility tree. Document every violation before writing a single line of code. Prioritize by severity (critical > serious > moderate).
|
||||
**Complexity:** Medium-High (audit is the main work).
|
||||
|
||||
---
|
||||
|
||||
### [x] P3-6 · Configurable Composer Toolbar
|
||||
|
||||
**What:** Let users rearrange or hide individual composer toolbar buttons (GIF, Sticker, Emoji, File, Voice, Location). Changes stored in `settingsAtom`. Access via a small "⚙ Customize toolbar" option in toolbar overflow.
|
||||
**[AUDIT REQUIRED]** — Audit the current toolbar button rendering in `RoomInput.tsx`. Understand the layout system (is it a fixed array or already mapped from config?). Drag-to-reorder may require a DnD library; consider whether reorder is worth the complexity vs just toggle-visibility.
|
||||
**Complexity:** Medium-High (drag reorder adds significant complexity).
|
||||
|
||||
---
|
||||
|
||||
### [ ] P3-8 · Thread Panel (full side drawer)
|
||||
|
||||
**⚠️ LARGEST FEATURE — requires its own planning session before implementation.**
|
||||
**What:** A right-side drawer for threaded conversations. Currently "Reply in Thread" exists but there is no panel to read or write thread replies.
|
||||
Features:
|
||||
|
||||
- Click "Reply in Thread" → opens thread drawer on the right
|
||||
- Thread root event shown at the top of the panel
|
||||
- Full message rendering for all in-thread replies (reuse timeline components)
|
||||
- Reply input at the bottom (full composer with formatting, emoji, etc.)
|
||||
- Unread count badge on the thread button in the main timeline
|
||||
- Keyboard shortcut to close thread panel
|
||||
**Architecture:**
|
||||
- New Jotai atom: `activeThreadEventId: string | null`
|
||||
- New component: `src/app/features/room/thread/ThreadPanel.tsx`
|
||||
- Rendered alongside `RoomView` as a conditional right panel (mirror the members drawer pattern)
|
||||
- Filter events in timeline to `m.thread` relation for the active root event ID
|
||||
- Shares the same `mx` client and room reference as the main timeline
|
||||
**[AUDIT REQUIRED]** — Deeply audit how `m.thread` relation events are currently stored and retrieved in the matrix-js-sdk. Understand the thread aggregation API: `GET /rooms/{roomId}/relations/{eventId}/m.thread`. Check if `RoomTimeline.tsx` currently filters out thread replies from the main timeline (it should — confirm).
|
||||
**Complexity:** High.
|
||||
|
||||
---
|
||||
|
||||
## Priority 4 — Specialized, high complexity, or low priority
|
||||
|
||||
### [ ] P4-1 · Thread Notification Mode Per-Thread (MSC3771)
|
||||
|
||||
**Spec:** MSC3771 (stable). Depends on Thread Panel (#P3-8).
|
||||
**What:** Per-thread notification toggle: "All messages" vs "Mentions only". Accessible from the thread panel header. Tracks unread counts separately per thread.
|
||||
**[AUDIT REQUIRED]** — Implement after Thread Panel. Requires understanding how the SDK tracks per-thread unread counts.
|
||||
**Complexity:** Medium (after thread panel exists).
|
||||
|
||||
---
|
||||
|
||||
### [ ] P4-2 · Thread Subscriptions (MSC4306) [BLOCKED]
|
||||
|
||||
**Spec:** MSC4306 (Synapse experimental). Depends on Thread Panel (#P3-8).
|
||||
**What:** "Follow thread" button to receive notifications for a thread you haven't posted in. Uses MSC4306 subscription endpoint.
|
||||
**[SERVER CHECK]** — `org.matrix.msc4306 = false` on `matrix.lotusguild.org` — BLOCKED until server enables it.
|
||||
**Complexity:** Medium (after thread panel exists).
|
||||
|
||||
---
|
||||
|
||||
### [x] P4-3 · Knock-to-join Notifications for Admins
|
||||
|
||||
**Note:** The basic knock-to-join UX is covered in P1-11 (completed). This task adds the admin notification side.
|
||||
**What:** Space/room admins see a notification badge when there are pending knock requests. A "Pending Join Requests" section in the members drawer or room settings. Approve (invite) or deny (kick) each knock.
|
||||
**Complexity:** Medium.
|
||||
|
||||
---
|
||||
|
||||
### [ ] P4-4 · Math / LaTeX Rendering in Messages (LOW PRIORITY)
|
||||
|
||||
**Spec:** CS-API §11.5 (stable) — `formatted_body` can contain LaTeX.
|
||||
**What:** Render `$...$` or `$$...$$` LaTeX expressions in message bodies. Use KaTeX (lightweight, ~100KB, renders server-side-compatible CSS). Must gracefully fall back to raw LaTeX text if KaTeX fails.
|
||||
**Note:** This is LOW PRIORITY — only useful for academic/technical communities. Implement last.
|
||||
**[AUDIT REQUIRED]** — Confirm KaTeX bundle size impact on the Vite bundle. Check if matrix-js-sdk's HTML sanitizer strips LaTeX before it reaches the renderer. The formatted_body sanitization pipeline is the main risk here.
|
||||
**Complexity:** Low-Medium.
|
||||
|
||||
---
|
||||
|
||||
### [ ] P4-5 · Live Location Sharing (MSC3489 + MSC3672) (LOW PRIORITY, HIGH COMPLEXITY) [BLOCKED]
|
||||
|
||||
**Spec:** MSC3489 + MSC3672. Implemented in Element Web.
|
||||
**Note:** Static location sharing is already implemented. This adds live/real-time GPS beacons. Very low priority per user preference.
|
||||
**What:** Start sharing live location → creates `m.beacon_info` state event → client posts `m.beacon` events on a timer → other users see your position update live on a map.
|
||||
**[SERVER CHECK]** — `org.matrix.msc3489 = false` AND `org.matrix.msc3672 = false` on `matrix.lotusguild.org` — BLOCKED.
|
||||
**Complexity:** High. Requires background geolocation API + live map rendering.
|
||||
|
||||
---
|
||||
|
||||
### [ ] P4-6 · OIDC / SSO Next-Gen Auth (MSC3861) (EXTREME COMPLEXITY, LOW PRIORITY)
|
||||
|
||||
**Spec:** MSC3861, merged Matrix spec v1.15. Uses Matrix Authentication Service (MAS).
|
||||
**Context:** ~80% of homeserver users have LLDAP/Authelia/SSO accounts. SSO is currently enabled on `matrix.lotusguild.org` but accounts are not yet linked. This would allow users to log in via their SSO credentials.
|
||||
**What:** OAuth 2.0 / OIDC login flow, token refresh, account management page linking Matrix identity to SSO identity.
|
||||
**EXTREME COMPLEXITY** — requires: MAS deployment/configuration on the homeserver, significant auth flow changes in the client, token refresh handling, session management overhaul.
|
||||
**[SERVER CHECK]** — Before any client work, audit whether MAS is already deployed on `compute-storage-01`. Check: `pct exec 151 -- systemctl status matrix-authentication-service` or similar.
|
||||
**Complexity:** Extreme. Multi-sprint project. Plan separately.
|
||||
|
||||
---
|
||||
|
||||
## Priority 5 — Gamer / Aesthetic / Customization
|
||||
|
||||
### [ ] P5-1 · Custom Accent Color Picker (non-TDS mode only)
|
||||
|
||||
**What:** A hex/HSL color picker in Settings → Appearance. Chosen color replaces the primary accent throughout the UI: buttons, badges, active states, highlights, presence dot, links. Applied via a CSS custom property override injected into `<head>`.
|
||||
**IMPORTANT:** This feature is completely inactive when TDS is enabled — TDS has its own fixed palette. Add this setting under a "Non-TDS Themes" section that is hidden when TDS is active.
|
||||
**[AUDIT REQUIRED]** Identify all CSS custom properties that constitute the "accent color" in non-TDS mode. Map them to the folds/vanilla-extract token names.
|
||||
**Complexity:** Medium.
|
||||
|
||||
---
|
||||
|
||||
### [ ] P5-2 · Additional Color Theme Presets
|
||||
|
||||
**What:** 5 new one-click theme presets alongside TDS. Each must be a complete, polished system with proper contrast ratios (WCAG AA). All implemented as vanilla-extract themes matching the existing TDS pattern.
|
||||
Themes:
|
||||
|
||||
1. **Cyberpunk** — deep navy bg (`#0a0015`), electric purple (`#bf5fff`) + hot pink (`#ff2d9b`) accents, neon glow
|
||||
2. **Ocean** — deep sea blue bg (`#020b18`), teal (`#00c9b1`) + aqua (`#0096d6`) accents, soft feel
|
||||
3. **Blood Red** — near-black bg (`#0d0203`), deep crimson (`#7a0010`) + bright red (`#ff2233`) accents
|
||||
4. **Classic Matrix** — pure black bg (`#000000`), phosphor green (`#00ff41`) text + accents
|
||||
5. **Midnight** — dark charcoal (`#111827`), cool blue-grey (`#6b7ca8`) accents, clean minimal
|
||||
**[AUDIT REQUIRED]** Study `src/lotus-terminal.css.ts` for the full token list before designing themes. All tokens must be covered.
|
||||
**Complexity:** Medium (design effort is the main cost).
|
||||
|
||||
---
|
||||
|
||||
### [MOVED] P5-9 · LFG (Looking for Group) Command → LotusBot
|
||||
|
||||
**Decision:** Implemented as `!lfg` in LotusBot rather than a client slash command. Bot-side rendering works consistently across all Matrix clients; client-side enhanced cards would only be visible to Lotus Chat users and require sanitizer auditing. The bot can also support richer flows (list active LFGs, DM interested players, auto-expire posts).
|
||||
|
||||
---
|
||||
|
||||
### [x] P5-10 · Voice Channel User Limit
|
||||
|
||||
**What:** Admins set max participants via custom state event `io.lotus.voice_limit: { max_users: N }`. Show "Channel Full (5/5)" to users over the limit. Local enforcement only.
|
||||
**[AUDIT REQUIRED]** Check if Element Call has its own participant limit that should be integrated with rather than duplicated.
|
||||
**Complexity:** Medium.
|
||||
**Done:** `RoomVoiceLimit` admin control in Room Settings → General → Voice; `CallPrescreen` disables Join + shows "Channel Full (N/N)" when at capacity (rejoiners exempt). State event `StateEvent.LotusVoiceLimit`. **Hard enforcement is server-side for ALL clients** via `voice-limit-guard` (matrix repo `livekit/voice-limit-guard.py`) — a fail-open sidecar fronting `lk-jwt-service` (guard `:8070`, lk-jwt `:8071`) that refuses the LiveKit JWT (403) when the room is at capacity. The client check is UX-only. EC has only a global `max_participants` (50), so per-room limits were not duplicating an EC feature.
|
||||
|
||||
---
|
||||
|
||||
### [x] P5-11 · AFK / Idle Auto-Mute in Voice
|
||||
|
||||
**What:** Auto-mute mic after X minutes of silence (detected via Web Audio AnalyserNode). Show "You were auto-muted due to inactivity" toast with click-to-unmute. Admin-configurable via `io.lotus.afk_timeout` state event. Disableable in Settings → Calls.
|
||||
**[AUDIT REQUIRED]** Verify auto-mute must go through the same CallControl bridge as manual mute.
|
||||
**Complexity:** Medium.
|
||||
|
||||
---
|
||||
|
||||
### [x] P5-12 · Seasonal / Event Themes
|
||||
|
||||
**What:** Automatic + manually toggleable seasonal overlays with CSS particle effects and accent color variants:
|
||||
|
||||
- **Halloween** (Oct 15–Nov 1): purple particles, orange accents, spider web pattern
|
||||
- **Christmas** (Dec 10–Jan 2): snow fall, red/green accents, snowflake pattern
|
||||
- **New Year** (Dec 31–Jan 1): firework burst animation, gold accents
|
||||
- **Pride** (June): rainbow gradient accent cycle
|
||||
All toggleable manually in Settings → Appearance regardless of date. Respects `prefers-reduced-motion`.
|
||||
**[AUDIT REQUIRED]** Design against existing CSS animation system in `lotus-terminal.css.ts`.
|
||||
**Complexity:** Medium.
|
||||
|
||||
---
|
||||
|
||||
### [x] P5-13 · Avatar Frame / Border Decorations
|
||||
|
||||
**What:** Decorative CSS rings/frames rendered around user avatars. Built-in options: TDS Glow (animated orange pulsing), Cyberpunk (rotating gradient), Minimal (thin ring), Gold (supporter cosmetic). Stored in Matrix account data `io.lotus.avatar_frame`. Only visible in Lotus Chat.
|
||||
**[AUDIT REQUIRED]** Verify folds Avatar component allows overlay decoration without breaking child-type constraints (see previous white-circle avatar bug).
|
||||
**Complexity:** Medium.
|
||||
|
||||
---
|
||||
|
||||
### [x] P5-14 · Animated Avatar Overlay Decorations (Discord-style)
|
||||
|
||||
**What:** Animated WebM/GIF overlays that float around avatars (transparent center showing avatar). Curated built-in set OR user-uploaded mxc:// overlay. Stored in account data. Only Lotus Chat users see them.
|
||||
**[AUDIT REQUIRED]** See #P5-13 audit. Also decide: curated set only vs user-uploadable.
|
||||
**Complexity:** Medium.
|
||||
|
||||
---
|
||||
|
||||
### [ ] P5-15 · In-Call Soundboard
|
||||
|
||||
**What:** Grid of short audio clips playable into the call audio stream via Web Audio API (AudioBufferSourceNode → MediaStreamDestinationNode → mixed with mic). Built-in clips + user-uploadable custom clips (stored as mxc://). Accessible from call controls bar.
|
||||
**[AUDIT REQUIRED]** Verify the Element Call integration exposes the mic MediaStream for mixing. This is the highest-risk part of this feature.
|
||||
**Complexity:** High.
|
||||
|
||||
---
|
||||
|
||||
### [x] P5-16 · Custom Join / Leave Sound Effects
|
||||
|
||||
**What:** Local-only sounds when participants join/leave a call you're in. Built-in options + per-user settable. Detect via Element Call participant list change events.
|
||||
**[AUDIT REQUIRED]** Find how Element Call exposes join/leave participant events to the parent window via postMessage bridge.
|
||||
**Complexity:** Medium.
|
||||
**Done:** Detected via `MatrixRTCSession` membership changes (`useCallMembersChange`) rather than the EC postMessage bridge — more reliable, identity tracked by `sender|deviceId`. Sounds synthesized with Web Audio (no assets). Styles Off/Chime/Soft/Retro in Settings → Calls. Hook `useCallJoinLeaveSounds`, util `callSounds.ts`.
|
||||
|
||||
---
|
||||
|
||||
### [ ] P5-20 · Quick Reply from Browser Notification
|
||||
|
||||
**What:** Inline reply field in browser notification toasts via Notification Actions API. Reply sends as threaded reply to the triggering message.
|
||||
**[AUDIT REQUIRED]** (1) Verify browser Notification Actions API support in target browsers. (2) This requires a Service Worker to handle the reply event — confirm if Lotus Chat has one or needs one.
|
||||
**Complexity:** Medium-High.
|
||||
|
||||
---
|
||||
|
||||
### [x] P5-21 · Custom @Mention Highlight Color
|
||||
|
||||
**What:** Each user sets their own mention highlight color in Settings → Appearance. Applied as `--user-mention-color` CSS property override on mention-highlighted message rows.
|
||||
**Complexity:** Low.
|
||||
|
||||
---
|
||||
|
||||
### [x] P5-22 · Font Selector for the UI
|
||||
|
||||
**What:** Font picker in Settings → Appearance. Options: JetBrains Mono, Inter, Geist, Fira Code, OpenDyslexic, System Default. Applied via CSS custom property overrides.
|
||||
**[AUDIT REQUIRED]** Check if any fonts are already globally loaded to avoid double-loading.
|
||||
**Complexity:** Low-Medium.
|
||||
|
||||
---
|
||||
|
||||
### [x] P5-27 · Notification Profile Presets (Gaming / Work / Sleep)
|
||||
|
||||
**What:** Saved presets that change all notification settings atomically. Gaming (mentions only), Work (DMs + mentions), Sleep (all off). Quick-switch from sidebar or settings.
|
||||
**Complexity:** Medium.
|
||||
|
||||
---
|
||||
|
||||
### [ ] P5-30 · Advanced ML Noise Suppression (Krisp-style)
|
||||
|
||||
**What:** High-end background noise cancellation using a pre-trained ML model (e.g. RNNoise) running in the browser. Removes dogs, fans, and keyboard clicks from the mic stream.
|
||||
**Note:** This is a top-tier feature request and an EXTREME COMPLEXITY project.
|
||||
**[AUDIT REQUIRED]** Must verify if mixing a processed stream into Element Call's WebRTC implementation causes latency or AEC (Echo Cancellation) issues.
|
||||
**Complexity:** Extreme.
|
||||
|
||||
---
|
||||
|
||||
### [ ] P5-31 · Granular Voice & Screenshare Quality Controls (Discord-style)
|
||||
|
||||
**What:** Let users (or room admins via room settings) adjust audio bitrates (e.g., 64kbps to 512kbps) and screenshare quality (resolution: 720p/1080p/Source, framerate: 15/30/60fps).
|
||||
**Note:** Requires tight integration with the LiveKit SFU and custom state events for per-room quality caps.
|
||||
**[AUDIT REQUIRED]** Must verify if current `lk-jwt-service` can be extended with custom bitrate/resolution claims or if a new sidecar (similar to `voice-limit-guard`) is needed for server-side enforcement.
|
||||
**Complexity:** Extreme.
|
||||
|
||||
---
|
||||
|
||||
### [x] P5-34 · User-to-User Private Notes
|
||||
|
||||
**What:** A private "Notes" field on user profiles visible only to you. Syncs across all your devices.
|
||||
**Matrix Tech:** Store in `io.lotus.user_notes` account data. Must be keyed by `userId`.
|
||||
**Complexity:** Medium.
|
||||
|
||||
---
|
||||
|
||||
### [ ] P5-35 · Desktop — Notification Click Opens Room (DEFERRED)
|
||||
|
||||
**What:** Clicking a system tray notification navigates to the relevant room. Quick-reply from the notification toast would send the reply without opening the window.
|
||||
**Status:** Deferred — `tauri-plugin-notification` has no Rust click/action callback API. Quick-reply would need a custom WinRT toast activator + COM registration, which can't be compile-tested without a Windows build environment.
|
||||
**Note:** Tray icon and `matrix:` deep links already bring the window forward on most interactions. Revisit when tauri-plugin-notification gains click handler support upstream.
|
||||
**Complexity:** High (platform-specific native code required).
|
||||
|
||||
---
|
||||
|
||||
### [ ] P5-36 · Desktop — Windows Jump List (DEFERRED)
|
||||
|
||||
**What:** Right-clicking the taskbar icon shows a jump list with recent/favorite rooms for quick navigation.
|
||||
**Status:** Deferred — implementing the Windows COM jump list API in Tauri requires iterating on C++/COM code that can only be compile-checked on Windows, making blind CI iteration impractical.
|
||||
**Action when unblocked:** Revisit when a Tauri plugin abstracts the Windows Shell `ICustomDestinationList` interface, or when a Windows build environment is available for local iteration.
|
||||
**Complexity:** High (Windows-only native COM).
|
||||
|
||||
---
|
||||
|
||||
## Blocked Features
|
||||
|
||||
These features are confirmed desirable but cannot be built until the listed dependency is resolved.
|
||||
Check back after each Synapse upgrade — re-run `/matrix/client/versions` and `unstable_features` to see if they've become available.
|
||||
|
||||
### [BLOCKED] · Live Location Sharing (MSC3489 + MSC3672)
|
||||
|
||||
**Blocked by:** `org.matrix.msc3489 = false` AND `org.matrix.msc3672 = false` on `matrix.lotusguild.org` (confirmed from unstable_features).
|
||||
**What it would do:** Real-time GPS beacon streaming upgrading the existing static location share.
|
||||
**Action when unblocked:** Both MSCs must be enabled on the homeserver before any client work.
|
||||
|
||||
### [BLOCKED] · Reaction / Relation Redaction (MSC3892)
|
||||
|
||||
**Blocked by:** `org.matrix.msc3892` = false on `matrix.lotusguild.org`
|
||||
**What it would do:** Cleanly remove a reaction without redacting the parent message.
|
||||
**Current behavior:** Full event redaction — acceptable fallback, no user-facing issue.
|
||||
**Action when unblocked:** Find `onReactionToggle` redaction call site; swap in MSC3892 endpoint with fallback.
|
||||
|
||||
### [BLOCKED] · Room Preview Before Joining (MSC3266)
|
||||
|
||||
**Blocked by:** `GET /v1/rooms/{id}/summary` returns 404 — endpoint not available on this server
|
||||
**What it would do:** Show room name, topic, avatar, member count before joining.
|
||||
**Action when unblocked:** Build pre-join preview card; trigger on unjoined room navigation.
|
||||
|
||||
### [BLOCKED] · Thread Subscriptions (MSC4306)
|
||||
|
||||
**Blocked by:** `org.matrix.msc4306` = false on `matrix.lotusguild.org`
|
||||
**What it would do:** Follow a thread without posting; get notifications for replies.
|
||||
**Action when unblocked:** Add "Follow thread" button in the thread panel header (depends on #P3-8 Thread Panel).
|
||||
|
||||
### [BLOCKED] · Report User (MSC4260)
|
||||
|
||||
**Blocked by:** Server declares only spec v1.12; MSC4260 merged in v1.14 — endpoint may not exist
|
||||
**What it would do:** Report a specific user to homeserver admins (separate from reporting a message).
|
||||
**Note:** Report Message already exists in upstream Cinny. This would add Report User to the profile panel.
|
||||
**Action when unblocked:** Test `POST /_matrix/client/v3/users/{userId}/report`; if 200, add button to user profile.
|
||||
|
||||
---
|
||||
|
||||
## Pending Audits
|
||||
|
||||
### [ ] Audit-3 · Profile banner image — Matrix protocol support
|
||||
|
||||
Research whether Matrix spec or MSC4133 (v1.16) defines a standard profile banner field. `uk.tcpip.msc4133.stable = true` on our server — check if a `banner_url` or similar field is defined. If no cross-client standard exists, do not implement.
|
||||
|
||||
---
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
### ⚠️ TDS DESIGN LAW (repeated here for emphasis)
|
||||
|
||||
> Every TDS color, animation, glow, border, shadow, and font value MUST come from `/root/code/web_template/base.css`.
|
||||
> Never hardcode hex values. Never invent CSS variable names.
|
||||
> Key variables: `--lt-accent-orange` · `--lt-accent-cyan` · `--lt-accent-green` · `--lt-glow-*` · `--lt-box-glow-*` · `--lt-border-color` · `--lt-font-mono`
|
||||
> Reference implementation: `/root/code/tinker_tickets/` (markdown.js, base.js, ticket.css)
|
||||
> This applies without exception to every task marked `[IMPROVE]`, `[Build]`, or any UI change.
|
||||
|
||||
### Design Rules
|
||||
|
||||
- All new components must respect both TDS dark (`LotusTerminalTheme`) and TDS light (`LotusTerminalLightTheme`) modes
|
||||
- Non-TDS theme work (custom accent color, theme presets) uses vanilla-extract theme files — match the pattern in `src/lotus-terminal.css.ts`
|
||||
- Code syntax highlighting token classes: `.tok-kw .tok-str .tok-num .tok-cmt .tok-fn` (defined in `web_template/base.css`)
|
||||
- `folds AvatarImage` does NOT accept children — wrap Avatar components externally for overlays/frames/borders
|
||||
|
||||
### CI/CD Pipeline
|
||||
|
||||
```
|
||||
edit → commit → git push origin lotus
|
||||
→ Gitea Actions: tsc --noEmit, eslint, prettier (~3 min)
|
||||
→ Webhook: lotus_deploy.sh on LXC 106 polls CI, then npm ci && npm run build → rsync
|
||||
→ Live at chat.lotusguild.org (~11 min total)
|
||||
```
|
||||
|
||||
### Per-Feature Checklist (before marking complete)
|
||||
|
||||
- [ ] `npx tsc --noEmit` — zero TypeScript errors
|
||||
- [ ] `npx eslint src/` — zero new errors (warnings OK if pre-existing)
|
||||
- [ ] `npx prettier --check src/` — formatting passes
|
||||
- [ ] `README.md` updated (Lotus-custom features only — not upstream Cinny features)
|
||||
- [ ] `landing/index.html` updated if the feature appears in the comparison table
|
||||
- [ ] Visually tested at `chat.lotusguild.org` after CI deploys
|
||||
|
||||
### Homeserver Access (for server audits)
|
||||
|
||||
- **Synapse (Matrix):** LXC 151 on `compute-storage-01` — `pct exec 151 -- bash`
|
||||
- **Config:** `/etc/matrix-synapse/homeserver.yaml`
|
||||
- **Version check:** `curl -s https://matrix.lotusguild.org/_matrix/client/versions`
|
||||
@@ -1,234 +0,0 @@
|
||||
# Lotus Chat — Technical Implementation Field Guide
|
||||
**Date:** June 2026
|
||||
|
||||
This document provides exhaustive, low-level implementation details for the remaining items in `LOTUS_TODO.md`. Follow these patterns to ensure code is "Lotus-perfect" (idiomatic, performant, and TDS-compliant).
|
||||
|
||||
---
|
||||
|
||||
## 🧵 Priority 3 — Higher Complexity
|
||||
|
||||
### P3-8 · Thread Panel (Full Side Drawer)
|
||||
**Architecture:** Mirror the `MembersDrawer` pattern but with a specialized timeline.
|
||||
|
||||
* **1. State (src/app/state/room/thread.ts):**
|
||||
```typescript
|
||||
export const activeThreadIdAtom = atom<string | null>(null);
|
||||
```
|
||||
* **2. Layout (src/app/features/room/Room.tsx):**
|
||||
Insert the `ThreadPanel` conditionally alongside the `RoomTimeline`.
|
||||
```tsx
|
||||
{activeThreadId && (
|
||||
<>
|
||||
<Line variant="Background" direction="Vertical" size="300" />
|
||||
<ThreadPanel roomId={roomId} threadId={activeThreadId} />
|
||||
</>
|
||||
)}
|
||||
```
|
||||
* **3. Component (src/app/features/room/thread/ThreadPanel.tsx):**
|
||||
* Use `room.getThread(threadId)` from the SDK.
|
||||
* Render a `Header` with a "Close" button that sets `activeThreadIdAtom` to `null`.
|
||||
* Reuse `RoomTimeline` but pass a filtered `EventTimelineSet`.
|
||||
* **Pro Tip:** Use `thread.timelineSet` directly for the most accurate thread view.
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Priority 5 — Gamer / Aesthetic / Customization
|
||||
|
||||
### P5-1 · Custom Accent Color Picker (Non-TDS only)
|
||||
**Mechanism:** Dynamic CSS variable injection.
|
||||
|
||||
* **1. Setting (src/app/state/settings.ts):**
|
||||
Add `customAccentColor: string` (hex).
|
||||
* **2. Manager (src/app/pages/ThemeManager.tsx):**
|
||||
Inside the `useEffect` that monitors theme changes:
|
||||
```typescript
|
||||
if (!lotusTerminal && customAccentColor) {
|
||||
document.documentElement.style.setProperty('--lt-accent-orange', customAccentColor);
|
||||
// Also derive a 'glow' version (e.g. 50% opacity)
|
||||
document.documentElement.style.setProperty('--lt-accent-orange-glow', `${customAccentColor}80`);
|
||||
}
|
||||
```
|
||||
* **3. UI (src/app/features/settings/general/General.tsx):**
|
||||
Use a `<Input type="color">` component. Hide this section if `lotusTerminal` is `true`.
|
||||
|
||||
### P5-14 · Animated Avatar Overlay
|
||||
**Mechanism:** CSS Pseudo-element wrapping.
|
||||
|
||||
* **1. Wrapper (src/app/components/user-avatar/UserAvatar.tsx):**
|
||||
```tsx
|
||||
const avatar = (
|
||||
<AvatarImage className={classNames(css.UserAvatar, className)} ... />
|
||||
);
|
||||
if (!frame) return avatar;
|
||||
return (
|
||||
<div className={css.AvatarFrameContainer} data-frame={frame}>
|
||||
{avatar}
|
||||
<div className={css.AvatarFrameEffect} />
|
||||
</div>
|
||||
);
|
||||
```
|
||||
* **2. CSS (src/app/components/user-avatar/UserAvatar.css.ts):**
|
||||
Define animations like `rotate` or `pulse`. Use `position: absolute; inset: -4px` on the effect div to create a glowing ring around the avatar.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Priority 4 — Specialized Features
|
||||
|
||||
### P4-4 · Math / LaTeX Rendering
|
||||
**Mechanism:** KaTeX injection into the HTML parser.
|
||||
|
||||
* **1. Sanitizer (src/app/utils/sanitize.ts):**
|
||||
You must allow KaTeX-specific tags and classes (e.g., `span`, `annotation`, `math`). Use a specialized allowed list for math blocks.
|
||||
* **2. Parser (src/app/plugins/react-custom-html-parser.tsx):**
|
||||
Detect `$ ... $` and `$$ ... $$` patterns in text nodes.
|
||||
```tsx
|
||||
if (node.type === 'text') {
|
||||
const parts = node.data.split(/(\$\$.*?\$\$|\$.*?\$)/g);
|
||||
return parts.map(p => {
|
||||
if (p.startsWith('$')) return <KaTeX math={p.replace(/\$/g, '')} />;
|
||||
return p;
|
||||
});
|
||||
}
|
||||
```
|
||||
* **3. CSS (src/app/styles/CustomHtml.css.ts):**
|
||||
Import `katex/dist/katex.min.css` only when a math block is rendered to save initial bundle size.
|
||||
|
||||
### P4-6 · OIDC / SSO Next-Gen Auth (MSC3861)
|
||||
**Mechanism:** Matrix Authentication Service (MAS) Integration.
|
||||
|
||||
* **Architecture:** Shift from password-based `/login` to OAuth2 `authorization_code` flow.
|
||||
* **Key Files:** `src/app/pages/auth/Login.tsx` and `src/app/hooks/useAuth.ts`.
|
||||
* **Implementation:**
|
||||
1. Use `oidc-client-ts` or a similar lightweight OIDC library.
|
||||
2. Check for `m.authentication` in `/.well-known/matrix/client`.
|
||||
3. Redirect to the MAS authorization endpoint.
|
||||
4. Handle the callback in a new `OidcCallback` route and store the OIDC `refresh_token`.
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Priority 5 — Gamer / Aesthetic / Customization
|
||||
|
||||
### P5-12 · Seasonal / Event Themes
|
||||
**Mechanism:** Date-aware global overlays.
|
||||
|
||||
* **1. Component (src/app/components/seasonal/SeasonalEffect.tsx):**
|
||||
```tsx
|
||||
const isHalloween = now.month === 9 && now.day >= 15; // etc.
|
||||
if (!isHalloween) return null;
|
||||
return <div className={css.HalloweenSpiderWeb} />;
|
||||
```
|
||||
* **2. Styles (src/app/styles/Animations.css.ts):**
|
||||
Use `repeating-linear-gradient` for spider webs or `keyframes` for falling snow.
|
||||
* **3. Mounting:** Place at the very end of `App.tsx` (above the `LotusToastContainer`) with `pointer-events: none`.
|
||||
|
||||
### P5-13 · Avatar Frame / Border Decorations
|
||||
**Mechanism:** Static variant of P5-14.
|
||||
|
||||
* **Implementation:** Use a simple `border` or `box-shadow` in `UserAvatar.tsx` based on the `io.lotus.avatar_frame` account data. Unlike the animated version, this should avoid `keyframes` to save CPU on long member lists.
|
||||
|
||||
### P5-2 · Additional Color Theme Presets
|
||||
**Mechanism:** Standard vanilla-extract theme multiplication.
|
||||
|
||||
* **Implementation:** Replicate the `lotusTerminalTheme` object in `src/colors.css.ts` for each new theme (Cyberpunk, Ocean, etc.). Ensure each theme defines all 50+ tokens required by the `folds` library and TDS.
|
||||
|
||||
### P5-15 · In-Call Soundboard
|
||||
**Mechanism:** Local-to-Global Audio Bridge.
|
||||
|
||||
* **Architecture:** Use the `Web Audio API` to mix sounds into the `MediaStream` before it enters the Element Call widget.
|
||||
* **Implementation:**
|
||||
1. Create an `AudioContext`.
|
||||
2. Create a `MediaStreamDestinationNode`.
|
||||
3. Create an `AudioBufferSourceNode` for the clip.
|
||||
4. Route the mic `MediaStream` and the clip source to the destination.
|
||||
5. Pass the destination's `.stream` to the call bridge.
|
||||
|
||||
### P5-20 · Quick Reply from Browser Notification
|
||||
**Mechanism:** Service Worker `notificationclick` Action.
|
||||
|
||||
* **1. Registration (src/sw.ts):**
|
||||
```typescript
|
||||
self.addEventListener('notificationclick', (event) => {
|
||||
if (event.action === 'reply' && event.reply) {
|
||||
const { roomId, threadId } = event.notification.data;
|
||||
const session = sessions.get(event.clientId); // Uses existing session mapping
|
||||
// Send via direct fetch to bypass SDK loading
|
||||
fetch(`${session.baseUrl}/_matrix/client/v3/rooms/${roomId}/send/m.room.message`, {
|
||||
method: 'POST',
|
||||
headers: { Authorization: `Bearer ${session.accessToken}` },
|
||||
body: JSON.stringify({
|
||||
msgtype: 'm.text',
|
||||
body: event.reply,
|
||||
'm.relates_to': threadId ? { rel_type: 'm.thread', event_id: threadId } : undefined
|
||||
})
|
||||
});
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔬 Extreme Complexity Projects
|
||||
|
||||
### P5-30 · Advanced ML Noise Suppression (Krisp-style)
|
||||
**Mechanism:** RNNoise WASM + Web Audio Worklet Pipeline.
|
||||
|
||||
* **Objective:** Filter non-vocal noise from the microphone stream in real-time.
|
||||
* **Architecture:**
|
||||
1. **Engine:** Use `RNNoise` (Recurrent Neural Network for noise suppression). It is lightweight and highly effective for speech.
|
||||
2. **Pipeline:** `Mic Stream` -> `AudioWorkletNode` (Processing) -> `MediaStreamDestination` -> `Element Call`.
|
||||
* **Implementation Steps:**
|
||||
1. **WASM Wrapper:** Compile the `RNNoise` C library to WebAssembly. Use a library like `rnnoise-wasm` or `noise-suppression-js`.
|
||||
2. **Audio Worklet:** Create `src/app/utils/audio/RnnoiseWorklet.ts`. This must handle 480-sample chunks (10ms of audio at 48kHz), which is the standard frame size for RNNoise.
|
||||
3. **Client Integration:**
|
||||
* In `CallControl.ts`, intercept the `localStream`.
|
||||
* Pass the stream through the Worklet.
|
||||
* Crucially, you must ensure that the processed stream is used by the `RTCPeerConnection` within the Element Call iframe.
|
||||
### P5-31 · Granular Voice & Screenshare Quality Controls
|
||||
**Mechanism:** WebRTC Encoding Parameters + Backend Quality Guard.
|
||||
|
||||
* **Objective:** Per-room and per-user control over audio fidelity and screenshare smoothness.
|
||||
* **Architecture:**
|
||||
1. **State Event:** `io.lotus.room_quality` (state key `""`) containing:
|
||||
```json
|
||||
{
|
||||
"audio_bitrate": 128000,
|
||||
"screen_max_res": "1080p",
|
||||
"screen_max_fps": 60
|
||||
}
|
||||
```
|
||||
2. **Client-Side (RoomInput / CallControl):**
|
||||
* **Screenshare:** In `src/app/plugins/call/CallControl.ts`, when initiating screenshare, map the "Quality" setting to `getDisplayMedia` constraints:
|
||||
```typescript
|
||||
const constraints = {
|
||||
video: {
|
||||
width: { ideal: 1920 }, // 1080p
|
||||
frameRate: { ideal: 60 }
|
||||
}
|
||||
};
|
||||
```
|
||||
* **Audio Bitrate:** After the call joins, find the `RTCRtpSender` for the audio track and update parameters:
|
||||
```typescript
|
||||
const sender = peerConnection.getSenders().find(s => s.track?.kind === 'audio');
|
||||
const params = sender.getParameters();
|
||||
params.encodings[0].maxBitrate = roomBitrate || 128000;
|
||||
await sender.setParameters(params);
|
||||
```
|
||||
3. **Backend Sidecar (The "Quality Guard"):**
|
||||
* **Pattern:** Extend the `voice-limit-guard.py` (on LXC 151) to handle quality metadata.
|
||||
* **Mechanism:** When a user requests a LiveKit JWT to join a room, the Guard fetches the `io.lotus.room_quality` event for that room via the Synapse Admin API.
|
||||
* **Enforcement:** The Guard injects these limits into the LiveKit token claims (if supported) or simply returns them to the client as an authorized "config" packet that the client must respect.
|
||||
* **Challenges:**
|
||||
* **LiveKit Compatibility:** Ensuring the SFU doesn't over-compress a high-bitrate stream from a "Pro" user.
|
||||
* **Network Stability:** High bitrates (512kbps audio + 60fps 1080p video) require significant upstream bandwidth. Implement a "Network Warning" UI if packets are dropped.
|
||||
|
||||
### P5-34 · User-to-User Private Notes
|
||||
**Mechanism:** Encrypted account data map.
|
||||
|
||||
* **Objective:** Private, cross-session notes about other users.
|
||||
* **Key Files:**
|
||||
* `src/app/hooks/useUserNotes.ts`: New hook for CRUD operations.
|
||||
* `src/app/components/user-profile/UserRoomProfile.tsx`: UI site.
|
||||
* **Implementation:**
|
||||
1. Store as a single map in `io.lotus.user_notes` account data: `{ "@alice:server": "Cool dev", "@bob:server": "Needs moderation" }`.
|
||||
2. Wrap the entire map in E2EE if the client supports local account data encryption, or rely on standard Matrix account data privacy.
|
||||
3. Add a "Notes" tab or textarea to the user profile popout.
|
||||
@@ -1,163 +1,114 @@
|
||||
# Lotus Chat
|
||||
# Cinny
|
||||
<p>
|
||||
<a href="https://github.com/ajbura/cinny/releases">
|
||||
<img alt="GitHub release downloads" src="https://img.shields.io/github/downloads/ajbura/cinny/total?logo=github&style=social"></a>
|
||||
<a href="https://hub.docker.com/r/ajbura/cinny">
|
||||
<img alt="DockerHub downloads" src="https://img.shields.io/docker/pulls/ajbura/cinny?logo=docker&style=social"></a>
|
||||
<a href="https://fosstodon.org/@cinnyapp">
|
||||
<img alt="Follow on Mastodon" src="https://img.shields.io/mastodon/follow/106845779685925461?domain=https%3A%2F%2Ffosstodon.org&logo=mastodon&style=social"></a>
|
||||
<a href="https://twitter.com/intent/follow?screen_name=cinnyapp">
|
||||
<img alt="Follow on Twitter" src="https://img.shields.io/twitter/follow/cinnyapp?logo=twitter&style=social"></a>
|
||||
<a href="https://cinny.in/#sponsor">
|
||||
<img alt="Sponsor Cinny" src="https://img.shields.io/opencollective/all/cinny?logo=opencollective&style=social"></a>
|
||||
</p>
|
||||
|
||||
A Matrix chat client built for Lotus Guild — fast, private, and packed with the features you actually want.
|
||||
A Matrix client focusing primarily on simple, elegant and secure interface. The main goal is to have an instant messaging application that is easy on people and has a modern touch.
|
||||
- [Roadmap](https://github.com/orgs/cinnyapp/projects/1)
|
||||
- [Contributing](./CONTRIBUTING.md)
|
||||
|
||||
**Deployed at [chat.lotusguild.org](https://chat.lotusguild.org)** | Forked from [Cinny](https://github.com/cinnyapp/cinny) v4.12.1
|
||||
<img align="center" src="https://raw.githubusercontent.com/cinnyapp/cinny-site/main/assets/preview2-light.png" height="380">
|
||||
|
||||
---
|
||||
## Getting started
|
||||
Web app is available at https://app.cinny.in and gets updated on each new release. The `dev` branch is continuously deployed at https://dev.cinny.in but keep in mind that it could have things broken.
|
||||
|
||||
## Licensing & Attribution
|
||||
You can also download our desktop app from [cinny-desktop repository](https://github.com/cinnyapp/cinny-desktop).
|
||||
|
||||
The source code is licensed under [AGPLv3](LICENSE), the same license as the upstream Cinny project. The source for this fork is public at [code.lotusguild.org/LotusGuild/cinny](https://code.lotusguild.org/LotusGuild/cinny).
|
||||
To host Cinny on your own, download tarball of the app from [GitHub release](https://github.com/cinnyapp/cinny/releases/latest).
|
||||
You can serve the application with a webserver of your choice by simply copying `dist/` directory to the webroot.
|
||||
To set default Homeserver on login and register page, place a customized [`config.json`](config.json) in webroot of your choice.
|
||||
|
||||
The Lotus Chat logo (`lotus_chat.png`) is a derivative work based on the original Cinny logo by Ajay Bura and contributors, used under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). The modified logo is © Lotus Guild and is also made available under CC BY 4.0.
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
### Messaging
|
||||
|
||||
- See who has read each message, and track delivery status (sending / sent / failed)
|
||||
- Bookmark any message and revisit saved messages from the sidebar
|
||||
- Schedule messages to send at a specific time
|
||||
- Click "edited" on any message to see the full edit history
|
||||
- Drafts are saved automatically and survive page reloads
|
||||
- Long messages collapse automatically — click "Read more" to expand
|
||||
- Forward messages to other rooms
|
||||
- Create and view polls directly in chat
|
||||
- Share your location with an inline map embed
|
||||
- Add captions to image and video uploads
|
||||
- Optionally compress images before uploading — shows before/after file sizes
|
||||
- GIF links from Giphy and Tenor auto-preview inline
|
||||
- Search for and send GIFs from a built-in GIF picker
|
||||
- Control voice message playback speed: 0.75× / 1× / 1.5× / 2×
|
||||
- Search messages with a date range filter
|
||||
- Room topics support rich formatting (bold, links, italics)
|
||||
- Deleted messages show a placeholder instead of disappearing
|
||||
- Code blocks highlight syntax for JS/TS, Python, and Rust
|
||||
- Rich link preview cards for YouTube, GitHub, Twitter/X, Reddit, Spotify, Twitch, Steam, Wikipedia, Discord, npm, Stack Overflow, and IMDb
|
||||
|
||||
### Calls & Voice
|
||||
|
||||
- Push to Talk with a configurable keybind (default: Space)
|
||||
- Push to Deafen with the M key
|
||||
- Camera starts turned off by default when joining a call
|
||||
- Screenshare requires confirmation before going live
|
||||
- Toggle noise suppression on or off
|
||||
- Calls float in a draggable picture-in-picture window when you navigate away
|
||||
- Your chat background shows through the call view
|
||||
- Dark/light mode inside calls matches your Lotus Chat theme
|
||||
- Calls are available in DMs and private groups only — no accidental mass rings
|
||||
- AFK auto-mute: mic is automatically silenced after a configurable idle timeout (1–30 min); a toast confirms the action
|
||||
- Voice channel user limit: admins can cap how many people can be in a room's call — enforced server-side for every Matrix client (not just Lotus Chat); others see "Channel Full" until a spot opens
|
||||
- Custom join/leave sound effects when someone enters or leaves your call — choose Chime, Soft, Retro, or off
|
||||
|
||||
### Customization & Appearance
|
||||
|
||||
- LotusGuild Terminal Design System (TDS) — a CRT terminal-inspired dark theme
|
||||
- TDS light mode variant for daytime use
|
||||
- 20+ static chat background patterns
|
||||
- 5 animated chat backgrounds: Digital Rain, Star Drift, Grid Pulse, Aurora Flow, Fireflies (with improved per-layer looping, phosphor-flicker rain, fluid aurora sweep, and organic firefly bioluminescence)
|
||||
- 11 seasonal & holiday theme overlays — Halloween, Christmas, New Year, Autumn, Valentine's Day, St. Patrick's Day, Earth Day, Lunar New Year, April Fools', Deep Space, and Retro Arcade; auto-selected by date with a manual override in Settings → Appearance
|
||||
- Avatar decorations — 99 animated APNG overlays (Gaming, Cyber, Space, Fantasy, Nature, Spooky, Cozy, and more) that frame your avatar across the timeline, members list, and @mention autocomplete; visible to all Lotus Chat users; select in Settings → Account → Avatar Decoration
|
||||
- Toggle to pause background animations
|
||||
- Glassmorphism sidebar — frosted glass effect that lets the background show through
|
||||
- Night Light / blue light filter with an adjustable intensity slider
|
||||
- Emoji prefixes on room names render larger in the sidebar (e.g. 🎮 general)
|
||||
- Rename any room for yourself only — other members see the original name
|
||||
- Emoji picker on all room name inputs
|
||||
|
||||
### Presence & Profile
|
||||
|
||||
- Discord-style presence selector: Online, Idle, Do Not Disturb, Invisible, or Auto
|
||||
- Custom status message with emoji and an optional auto-clear timer (changing your status is never silently overwritten by activity events)
|
||||
- Colored presence ring on member avatars (green / yellow / red)
|
||||
- Profile fields for pronouns and timezone
|
||||
- When a user's timezone is set, their current local time appears in their profile
|
||||
- Private notes on any user's profile — freeform text visible only to you, auto-saves and syncs across devices
|
||||
- Unread count shown in the browser tab title
|
||||
|
||||
### Moderation & Privacy
|
||||
|
||||
- Report any room to homeserver admins from the room menu
|
||||
- View policy lists and ban lists (Draupnir-compatible, read-only)
|
||||
- Toggle private read receipts so others can't see when you've read messages
|
||||
- Optional warning when an encrypted room contains unverified devices
|
||||
- Full push rule editor in notification settings
|
||||
- View and edit Server ACL rules in room settings
|
||||
- Filterable room activity / mod log (joins, kicks, bans, power level changes, etc.)
|
||||
- Room stats and insights panel (active members, top reactions, media breakdown, activity heatmap)
|
||||
- Export room history as plain text, JSON, or HTML with optional date range filter
|
||||
|
||||
### Notifications
|
||||
|
||||
- In-app toast notifications appear bottom-right when the window is focused
|
||||
- Custom notification sounds per category (messages, invites)
|
||||
- Quiet hours — suppress notifications during a configured time window
|
||||
- Click a toast to jump directly to the room or DM
|
||||
|
||||
### UX
|
||||
|
||||
- Filter and search rooms in the sidebar
|
||||
- Favorite rooms sync across devices and appear in a pinned section
|
||||
- Sort rooms by recent activity, alphabetical, or unread first
|
||||
- DM rows show a message preview and relative timestamp
|
||||
- Right-click a room for a context menu: mute with duration, copy link, mark as read
|
||||
- Quick emoji reactions appear on message hover — one click to react
|
||||
- Knock-to-join: request access to a room; admins approve or deny from the members list
|
||||
- Media gallery drawer: browse all images, videos, and files shared in a room
|
||||
- Invite link and QR code in room settings
|
||||
- Pending knock requests shown in the members list for room admins with a live badge count on the Members button
|
||||
- Homeserver support contact displayed in Help & About (MSC1929)
|
||||
- Server notice rooms are visually distinct from regular DMs
|
||||
|
||||
---
|
||||
|
||||
## Desktop App
|
||||
|
||||
Lotus Chat has a desktop app for Windows, macOS, and Linux. It wraps the same web client in a native window with automatic background updates — no need to reinstall for new versions.
|
||||
|
||||
### Download
|
||||
|
||||
Download the latest release from the [Releases page on code.lotusguild.org](https://code.lotusguild.org).
|
||||
|
||||
### SmartScreen Warning (Windows)
|
||||
|
||||
When you first run the installer on Windows, you may see a popup that says **"Windows protected your PC"** with the app listed as an unknown publisher. This is normal.
|
||||
|
||||
**Why it happens:** Windows SmartScreen flags any app that does not have an expensive commercial code-signing certificate from a major CA. Lotus Chat is signed with its own key for update verification, but that key is not in Microsoft's pre-approved list.
|
||||
|
||||
**How to install anyway:**
|
||||
|
||||
1. Click **"More info"** in the SmartScreen dialog.
|
||||
2. A **"Run anyway"** button will appear.
|
||||
3. Click it to proceed with installation.
|
||||
|
||||
After the first install, automatic in-app updates handle all future versions — you will not see this prompt again for updates.
|
||||
|
||||
---
|
||||
|
||||
## For Developers
|
||||
|
||||
The source code lives in `/root/code/cinny`. All changes should be made on the `lotus` branch. Push to `origin/lotus` and CI will automatically build and deploy to [chat.lotusguild.org](https://chat.lotusguild.org) in approximately 11 minutes — no manual build or deploy steps required.
|
||||
|
||||
See [LOTUS_FEATURES.md](LOTUS_FEATURES.md) for the full feature changelog and [LOTUS_TODO.md](LOTUS_TODO.md) for the work backlog.
|
||||
|
||||
### Build
|
||||
|
||||
```bash
|
||||
npm ci && npm run build # outputs to dist/
|
||||
Alternatively you can just pull the [DockerHub image](https://hub.docker.com/r/ajbura/cinny) by:
|
||||
```
|
||||
docker pull ajbura/cinny
|
||||
```
|
||||
or [ghcr image](https://github.com/cinnyapp/cinny/pkgs/container/cinny) by:
|
||||
```
|
||||
docker pull ghcr.io/cinnyapp/cinny:latest
|
||||
```
|
||||
|
||||
If the build is killed due to out-of-memory:
|
||||
|
||||
```bash
|
||||
NODE_OPTIONS=--max_old_space_size=6144 npm run build
|
||||
```
|
||||
|
||||
### CI/CD
|
||||
<details>
|
||||
<summary>PGP Public Key to verify tarball</summary>
|
||||
|
||||
```
|
||||
edit → commit → git push → ~11 min → live at chat.lotusguild.org
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQGNBGJw/g0BDAC8qQeLqDMzYzfPyOmRlHVEoguVTo+eo1aVdQH2X7OELdjjBlyj
|
||||
6d6c1adv/uF2g83NNMoQY7GEeHjRnXE4m8kYSaarb840pxrYUagDc0dAbJOGaCBY
|
||||
FKTo7U1Kvg0vdiaRuus0pvc1NVdXSxRNQbFXBSwduD+zn66TI3HfcEHNN62FG1cE
|
||||
K1jWDwLAU0P3kKmj8+CAc3h9ZklPu0k/+t5bf/LJkvdBJAUzGZpehbPL5f3u3BZ0
|
||||
leZLIrR8uV7PiV5jKFahxlKR5KQHld8qQm+qVhYbUzpuMBGmh419I6UvTzxuRcvU
|
||||
Frn9ttCEzV55Y+so4X2e4ZnB+5gOnNw+ecifGVdj/+UyWnqvqqDvLrEjjK890nLb
|
||||
Pil4siecNMEpiwAN6WSmKpWaCwQAHEGDVeZCc/kT0iYfj5FBcsTVqWiO6eaxkUlm
|
||||
jnulqWqRrlB8CJQQvih/g//uSEBdzIibo+ro+3Jpe120U/XVUH62i9HoRQEm6ADG
|
||||
4zS5hIq4xyA8fL8AEQEAAbQdQ2lubnlBcHAgPGNpbm55YXBwQGdtYWlsLmNvbT6J
|
||||
AdQEEwEIAD4WIQSRri2MHidaaZv+vvuUMwx6UK/M8wUCYnD+DQIbAwUJA8JnAAUL
|
||||
CQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRCUMwx6UK/M88ApC/9HAdbum1lYBC0s
|
||||
1k7GwP2A7B4sQtBWjy771BzybWlHeaeG+BGJwg4YiuowXZMm5dubFJFoI/CfeY07
|
||||
B5aK40/bmT6Xcfkp0VA74c1wUpubBUEJN7tH5HG/OGd9BKeq9E/HHtVaJLVT1k3w
|
||||
Rhv9VuHO6nR30EEp7IDthftotl5S4lio3+W0pKk4TAKV8vjaCNp3y/lAHzoP1BU9
|
||||
bUSao+7GXVeArKBjuqxN+t1uuiaxPH4L0oe2pMVjTig04zGJM5fTVoly859MEcC/
|
||||
R7Taq9RWGfXFmgCXy8Dviz3eOD90vqpCzhX4+ypK0cp2X0UwhMH4dpKUzExmdbhl
|
||||
eBO5GcHB4VxvloRBNf9/Lr7YOTgWejMUw+MlhZE2RE8unfW1LnM/cjL4dhXzO/XB
|
||||
FUHHNq8d6d4e02rfWqw7mZo2/NVJgFRcvzw2rgx7w7CKtCNwF4lNjUetB2waZzDb
|
||||
fAE0kwhK4Iuwvy12JOBzL0Yy9MxANtwUryr/LQz9AmdT4Rwnp0S5AY0EYnD+DQEM
|
||||
ANOu/d6ZMF8bW+Df9RDCUQKytbaZfa+ZbIHBus7whCD/SQMOhPKntv3HX7SmMCs+
|
||||
5i27kJMu4YN623JCS7hdCoXVO1R5kXCEcneW/rPBMDutaM472YvIWMIqK9Wwl5+0
|
||||
Piu2N+uTkKhe9uS2u7eN+Khef3d7xfjGRxoppM+xI9dZO+jhYiy8LuC0oBohTjJq
|
||||
QPqfGDpowBwRkkOsGz/XVcesJ1Pzg4bKivTS9kZjZSyT9RRSY8As0sVUN57AwYul
|
||||
s1+eh00n/tVpi2Jj9pCm7S0csSXvXj8v2OTdK1jt4YjpzR0/rwh4+/xlOjDjZEqH
|
||||
vMPhpzpbgnwkxZ3X8BFne9dJ3maC5zQ3LAeCP5m1W0hXzagYhfyjo74slJgD1O8c
|
||||
LDf2Oxc5MyM8Y/UK497zfqSPfgT3NhQmhHzk83DjXw3I6Z3A3U+Jp61w0eBRI1nx
|
||||
H1UIG+gldcAKUTcfwL0lghoT3nmi9JAbvek0Smhz00Bbo8/dx8vwQRxDUxlt7Exx
|
||||
NwARAQABiQG8BBgBCAAmFiEEka4tjB4nWmmb/r77lDMMelCvzPMFAmJw/g0CGwwF
|
||||
CQPCZwAACgkQlDMMelCvzPPT7Qv8CjXUEhphZFLwpBfaNOzRNfIXJST9aDit8zHW
|
||||
IMmfSpORVfpU71IyIB3o/DtTUPwCeb8nvNJs7aj1QT1ZUSsqFa3yY2S16V/g8+WN
|
||||
sHca6oDSc1J+A0eEpEL1HbG1b5OPBC0AeGvvMOoqrbqThBZVKg1Jc/0SD3cvKElv
|
||||
aHeCZCNNmfcZ2Ib4HYhhc8//ZtC9TeI+5J/YesctY1M12EoWMxMrc27Y3P5Pa0BI
|
||||
Uc3qxWggPq1vOFYsEshL0w99HyJvREJmQA7Fa0crV+rICxyrBxJeNnEvjH/0KCBU
|
||||
LCkEonLY1QwrxyeeV3VpxGE3zHHE3azOdAjTIoAdzX5f/qhbgYlM68GL2f8xdDkp
|
||||
O0igSGHWhO4F8BfmE7IOTx1Bi7daczp8nCFxh73cKpKB0RUsd9xxrqYpovjmEAlo
|
||||
w7aHpdzt64NQcsrbK10OSVDF3gFa9Vz20/NQvdUrp8jGmAb/8+nYqI94Jsc28H36
|
||||
UeGsouhyuITLwEhScounZDqop+Dx
|
||||
=Zg+6
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
```
|
||||
</details>
|
||||
|
||||
## Local development
|
||||
> We recommend using a version manager as versions change very quickly. You will likely need to switch
|
||||
between multiple Node.js versions based on the needs of different projects you're working on. [NVM on windows](https://github.com/coreybutler/nvm-windows#installation--upgrades) on Windows and [nvm](https://github.com/nvm-sh/nvm) on Linux/macOS are pretty good choices. Also recommended nodejs version Hydrogen LTS (v18).
|
||||
|
||||
Execute the following commands to start a development server:
|
||||
```sh
|
||||
npm ci # Installs all dependencies
|
||||
npm start # Serve a development version
|
||||
```
|
||||
|
||||
To build the app:
|
||||
```sh
|
||||
npm run build # Compiles the app into the dist/ directory
|
||||
```
|
||||
|
||||
### Running with Docker
|
||||
This repository includes a Dockerfile, which builds the application from source and serves it with Nginx on port 80. To
|
||||
use this locally, you can build the container like so:
|
||||
```
|
||||
docker build -t cinny:latest .
|
||||
```
|
||||
|
||||
You can then run the container you've built with a command similar to this:
|
||||
```
|
||||
docker run -p 8080:80 cinny:latest
|
||||
```
|
||||
|
||||
This will forward your `localhost` port 8080 to the container's port 80. You can visit the app in your browser by navigating to `http://localhost:8080`.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Redirects from what the browser requests to what we serve
|
||||
/login /
|
||||
/register /
|
||||
@@ -1,3 +0,0 @@
|
||||
export default {
|
||||
base: '/',
|
||||
};
|
||||
@@ -1,16 +1,13 @@
|
||||
{
|
||||
"defaultHomeserver": 0,
|
||||
"homeserverList": ["matrix.lotusguild.org", "matrix.org", "mozilla.org"],
|
||||
"allowCustomHomeservers": true,
|
||||
"featuredCommunities": {
|
||||
"openAsDefault": false,
|
||||
"spaces": [],
|
||||
"rooms": [],
|
||||
"servers": []
|
||||
},
|
||||
"hashRouter": {
|
||||
"enabled": false,
|
||||
"basename": "/"
|
||||
},
|
||||
"gifApiKey": ""
|
||||
"defaultHomeserver": 3,
|
||||
"homeserverList": [
|
||||
"0wnz.at",
|
||||
"converser.eu",
|
||||
"envs.net",
|
||||
"matrix.org",
|
||||
"monero.social",
|
||||
"mozilla.org",
|
||||
"xmr.se"
|
||||
],
|
||||
"allowCustomHomeservers": true
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
# more info: https://caddyserver.com/docs/caddyfile/patterns#single-page-apps-spas
|
||||
cinny.domain.tld {
|
||||
root * /path/to/cinny/dist
|
||||
try_files {path} / index.html
|
||||
file_server
|
||||
}
|
||||
@@ -1,34 +1,27 @@
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name cinny.domain.tld;
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name cinny.domain.tld;
|
||||
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
location /.well-known/acme-challenge/ {
|
||||
alias /var/lib/letsencrypt/.well-known/acme-challenge/;
|
||||
}
|
||||
location /.well-known/acme-challenge/ {
|
||||
alias /var/lib/letsencrypt/.well-known/acme-challenge/;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl;
|
||||
server_name cinny.domain.tld;
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl;
|
||||
server_name cinny.domain.tld;
|
||||
|
||||
location / {
|
||||
root /opt/cinny/dist/;
|
||||
|
||||
rewrite ^/config.json$ /config.json break;
|
||||
rewrite ^/manifest.json$ /manifest.json break;
|
||||
|
||||
rewrite ^/sw.js$ /sw.js break;
|
||||
rewrite ^/pdf.worker.min.js$ /pdf.worker.min.js break;
|
||||
|
||||
rewrite ^/public/(.*)$ /public/$1 break;
|
||||
rewrite ^/assets/(.*)$ /assets/$1 break;
|
||||
|
||||
rewrite ^(.+)$ /index.html break;
|
||||
}
|
||||
location / {
|
||||
root /opt/cinny/dist/;
|
||||
index index.html;
|
||||
}
|
||||
location ~* ^\/(login|register) {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
rewrite ^/config.json$ /config.json break;
|
||||
rewrite ^/manifest.json$ /manifest.json break;
|
||||
|
||||
rewrite ^/sw.js$ /sw.js break;
|
||||
rewrite ^/pdf.worker.min.js$ /pdf.worker.min.js break;
|
||||
|
||||
rewrite ^/public/(.*)$ /public/$1 break;
|
||||
rewrite ^/assets/(.*)$ /assets/$1 break;
|
||||
|
||||
rewrite ^(.+)$ /index.html break;
|
||||
}
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
import { FlatCompat } from '@eslint/eslintrc';
|
||||
import js from '@eslint/js';
|
||||
import tsPlugin from '@typescript-eslint/eslint-plugin';
|
||||
import tsParser from '@typescript-eslint/parser';
|
||||
import reactPlugin from 'eslint-plugin-react';
|
||||
import reactHooksPlugin from 'eslint-plugin-react-hooks';
|
||||
import jsxA11yPlugin from 'eslint-plugin-jsx-a11y';
|
||||
import eslintConfigPrettier from 'eslint-config-prettier';
|
||||
import globals from 'globals';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
const compat = new FlatCompat({
|
||||
baseDirectory: __dirname,
|
||||
recommendedConfig: js.configs.recommended,
|
||||
allConfig: js.configs.all,
|
||||
});
|
||||
|
||||
export default [
|
||||
{ ignores: ['node_modules/**', 'dist/**', 'experiment/**'] },
|
||||
js.configs.recommended,
|
||||
tsPlugin.configs['flat/eslint-recommended'],
|
||||
...tsPlugin.configs['flat/recommended'],
|
||||
reactPlugin.configs.flat.recommended,
|
||||
reactHooksPlugin.configs.flat['recommended'],
|
||||
// Register jsx-a11y plugin (rules selectively enabled below)
|
||||
{ plugins: { 'jsx-a11y': jsxA11yPlugin } },
|
||||
// airbnb-base via FlatCompat (JS/import rules; no React plugin, no getFilename issue)
|
||||
...compat.extends('airbnb-base'),
|
||||
eslintConfigPrettier,
|
||||
{
|
||||
languageOptions: {
|
||||
parser: tsParser,
|
||||
globals: {
|
||||
...globals.browser,
|
||||
...globals.es2021,
|
||||
JSX: 'readonly',
|
||||
},
|
||||
parserOptions: {
|
||||
ecmaFeatures: { jsx: true },
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
},
|
||||
},
|
||||
settings: {
|
||||
react: {
|
||||
version: '18.2.0',
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'linebreak-style': 0,
|
||||
'no-unused-vars': 'off', // handled by @typescript-eslint/no-unused-vars
|
||||
'no-underscore-dangle': 0,
|
||||
'no-shadow': 'off',
|
||||
|
||||
// Stylistic rules — off for this codebase
|
||||
'no-console': 'off',
|
||||
'no-continue': 'off',
|
||||
'no-nested-ternary': 'off',
|
||||
'no-plusplus': 'off',
|
||||
'no-param-reassign': 'off',
|
||||
'no-restricted-syntax': 'off',
|
||||
'no-restricted-globals': 'off',
|
||||
'no-constant-condition': 'off',
|
||||
'prefer-destructuring': 'off',
|
||||
'no-useless-assignment': 'off',
|
||||
'preserve-caught-error': 'off',
|
||||
'consistent-return': 'off',
|
||||
'no-use-before-define': 'off',
|
||||
|
||||
'import/prefer-default-export': 'off',
|
||||
'import/extensions': 'off',
|
||||
'import/no-unresolved': 'off',
|
||||
'import/no-extraneous-dependencies': [
|
||||
'error',
|
||||
{
|
||||
devDependencies: true,
|
||||
},
|
||||
],
|
||||
|
||||
'react/no-unstable-nested-components': ['error', { allowAsProps: true }],
|
||||
'react/jsx-filename-extension': [
|
||||
'error',
|
||||
{
|
||||
extensions: ['.tsx', '.jsx'],
|
||||
},
|
||||
],
|
||||
|
||||
'react/display-name': 'off',
|
||||
'react/require-default-props': 'off',
|
||||
'react/jsx-props-no-spreading': 'off',
|
||||
'react-hooks/rules-of-hooks': 'error',
|
||||
'react-hooks/exhaustive-deps': 'error',
|
||||
// React Compiler rules added in react-hooks v7 — disabled until React Compiler is adopted
|
||||
'react-hooks/react-compiler': 'off',
|
||||
'react-hooks/incompatible-library': 'off',
|
||||
'react-hooks/refs': 'off',
|
||||
'react-hooks/set-state-in-effect': 'off',
|
||||
'react-hooks/set-state-in-render': 'off',
|
||||
'react-hooks/immutability': 'off',
|
||||
'react-hooks/purity': 'off',
|
||||
'react-hooks/use-memo': 'off',
|
||||
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'error',
|
||||
{ argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrorsIgnorePattern: '^_' },
|
||||
],
|
||||
'@typescript-eslint/no-shadow': 'error',
|
||||
'@typescript-eslint/no-explicit-any': 'warn',
|
||||
|
||||
// jsx-a11y — media captions not required for this app
|
||||
'jsx-a11y/media-has-caption': 'off',
|
||||
'jsx-a11y/no-noninteractive-element-interactions': 'off',
|
||||
'jsx-a11y/alt-text': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.ts', '**/*.tsx'],
|
||||
rules: {
|
||||
'no-undef': 'off',
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -1,42 +1,36 @@
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Lotus Chat</title>
|
||||
<meta name="name" content="Lotus Chat" />
|
||||
<meta name="author" content="Lotus Guild" />
|
||||
<title>Cinny</title>
|
||||
<meta name="name" content="Cinny" />
|
||||
<meta name="author" content="Ajay Bura" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Lotus Chat — the Lotus Guild Matrix client. Secure, fast, and built for our community."
|
||||
content="A Matrix client where you can enjoy the conversation using simple, elegant and secure interface protected by e2ee with the power of open source."
|
||||
/>
|
||||
<meta name="keywords" content="lotus chat, lotus guild, matrix, matrix client" />
|
||||
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content="Lotus Chat" />
|
||||
<meta property="og:url" content="https://chat.lotusguild.org" />
|
||||
<meta
|
||||
property="og:image"
|
||||
content="https://chat.lotusguild.org/public/res/android/android-chrome-192x192.png"
|
||||
name="keywords"
|
||||
content="cinny, cinnyapp, cinnychat, matrix, matrix client, matrix.org, element"
|
||||
/>
|
||||
|
||||
<meta property="og:title" content="Cinny" />
|
||||
<meta property="og:url" content="https://cinny.in" />
|
||||
<meta property="og:image" content="https://cinny.in/assets/favicon-48x48.png" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content="Lotus Chat — the Lotus Guild Matrix client. Secure, fast, and built for our community."
|
||||
content="A Matrix client where you can enjoy the conversation using simple, elegant and secure interface protected by e2ee with the power of open source."
|
||||
/>
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="color-scheme" content="dark light" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=VT323&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="/fonts/custom-fonts.css" />
|
||||
<link id="favicon" rel="shortcut icon" href="./public/favicon.ico" />
|
||||
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<meta name="mobile-web-app-capable" content="yes" />
|
||||
<meta name="application-name" content="Lotus Chat" />
|
||||
<meta name="apple-mobile-web-app-title" content="Lotus Chat" />
|
||||
<meta name="application-name" content="Cinny" />
|
||||
<meta name="apple-mobile-web-app-title" content="Cinny" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
|
||||
@@ -96,7 +90,12 @@
|
||||
window.global ||= window;
|
||||
</script>
|
||||
<div id="root"></div>
|
||||
<div id="portalContainer"></div>
|
||||
<script type="module" src="./src/index.tsx"></script>
|
||||
<audio id="notificationSound">
|
||||
<source src="./public/sound/notification.ogg" type="audio/ogg" />
|
||||
</audio>
|
||||
<audio id="inviteSound">
|
||||
<source src="./public/sound/invite.ogg" type="audio/ogg" />
|
||||
</audio>
|
||||
<script type="module" src="./src/index.jsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
Before Width: | Height: | Size: 851 KiB |
|
Before Width: | Height: | Size: 944 KiB |
@@ -1,36 +0,0 @@
|
||||
[[redirects]]
|
||||
from = "/config.json"
|
||||
to = "/config.json"
|
||||
status = 200
|
||||
|
||||
[[redirects]]
|
||||
from = "/manifest.json"
|
||||
to = "/manifest.json"
|
||||
status = 200
|
||||
|
||||
[[redirects]]
|
||||
from = "/sw.js"
|
||||
to = "/sw.js"
|
||||
status = 200
|
||||
|
||||
|
||||
[[redirects]]
|
||||
from = "/pdf.worker.min.js"
|
||||
to = "/pdf.worker.min.js"
|
||||
status = 200
|
||||
|
||||
[[redirects]]
|
||||
from = "/public/*"
|
||||
to = "/public/:splat"
|
||||
status = 200
|
||||
|
||||
[[redirects]]
|
||||
from = "/assets/*"
|
||||
to = "/assets/:splat"
|
||||
status = 200
|
||||
|
||||
[[redirects]]
|
||||
from = "/*"
|
||||
to = "/index.html"
|
||||
status = 200
|
||||
force = true
|
||||
@@ -1,146 +1,106 @@
|
||||
{
|
||||
"name": "lotus-chat",
|
||||
"version": "4.12.2-lotus",
|
||||
"description": "Lotus Chat — Matrix client for Lotus Guild",
|
||||
"name": "cinny",
|
||||
"version": "3.1.0",
|
||||
"description": "Yet another matrix client",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"lint": "npm run check:eslint && npm run check:prettier",
|
||||
"lint": "yarn check:eslint && yarn check:prettier",
|
||||
"check:eslint": "eslint src/*",
|
||||
"check:prettier": "prettier --check .",
|
||||
"fix:prettier": "prettier --write .",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"prepare": "husky",
|
||||
"commit": "git-cz",
|
||||
"postinstall": "node scripts/patch-folds.mjs",
|
||||
"sync:decorations": "node scripts/syncDecorations.mjs"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{ts,tsx,js,jsx}": "eslint",
|
||||
"*": "prettier --ignore-unknown --write"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "./node_modules/cz-conventional-changelog"
|
||||
}
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Ajay Bura",
|
||||
"license": "AGPL-3.0-only",
|
||||
"dependencies": {
|
||||
"@atlaskit/pragmatic-drag-and-drop": "1.8.1",
|
||||
"@atlaskit/pragmatic-drag-and-drop-auto-scroll": "2.1.5",
|
||||
"@atlaskit/pragmatic-drag-and-drop-hitbox": "1.1.0",
|
||||
"@eslint/eslintrc": "3.3.5",
|
||||
"@eslint/js": "10.0.1",
|
||||
"@fontsource-variable/inter": "5.2.8",
|
||||
"@giphy/js-fetch-api": "5.8.0",
|
||||
"@giphy/js-types": "5.1.0",
|
||||
"@giphy/js-util": "5.2.0",
|
||||
"@giphy/react-components": "10.1.2",
|
||||
"@sentry/react": "10.53.1",
|
||||
"@tanstack/react-query": "5.100.13",
|
||||
"@tanstack/react-query-devtools": "5.100.13",
|
||||
"@tanstack/react-virtual": "3.13.25",
|
||||
"@types/dompurify": "3.2.0",
|
||||
"@fontsource/inter": "4.5.14",
|
||||
"@khanacademy/simple-markdown": "0.8.6",
|
||||
"@matrix-org/olm": "3.2.14",
|
||||
"@tanstack/react-virtual": "3.0.0-beta.54",
|
||||
"@tippyjs/react": "4.2.6",
|
||||
"@vanilla-extract/css": "1.9.3",
|
||||
"@vanilla-extract/recipes": "0.3.0",
|
||||
"@vanilla-extract/vite-plugin": "3.7.1",
|
||||
"await-to-js": "3.0.0",
|
||||
"badwords-list": "2.0.1-4",
|
||||
"blurhash": "2.0.5",
|
||||
"blurhash": "2.0.4",
|
||||
"browser-encrypt-attachment": "0.3.0",
|
||||
"chroma-js": "3.2.0",
|
||||
"classnames": "2.5.1",
|
||||
"classnames": "2.3.2",
|
||||
"dateformat": "5.0.3",
|
||||
"dayjs": "1.11.20",
|
||||
"domhandler": "6.0.1",
|
||||
"dompurify": "3.4.5",
|
||||
"emojibase": "17.0.0",
|
||||
"emojibase-data": "17.0.0",
|
||||
"dayjs": "1.11.10",
|
||||
"domhandler": "5.0.3",
|
||||
"emojibase": "6.1.0",
|
||||
"emojibase-data": "7.0.1",
|
||||
"file-saver": "2.0.5",
|
||||
"focus-trap-react": "12.0.2",
|
||||
"folds": "2.6.2",
|
||||
"globals": "17.6.0",
|
||||
"html-dom-parser": "7.1.0",
|
||||
"html-react-parser": "6.1.2",
|
||||
"i18next": "26.2.0",
|
||||
"i18next-browser-languagedetector": "8.2.1",
|
||||
"i18next-http-backend": "4.0.0",
|
||||
"immer": "11.1.8",
|
||||
"flux": "4.0.3",
|
||||
"focus-trap-react": "10.0.2",
|
||||
"folds": "1.5.0",
|
||||
"formik": "2.2.9",
|
||||
"html-dom-parser": "4.0.0",
|
||||
"html-react-parser": "4.2.0",
|
||||
"immer": "9.0.16",
|
||||
"is-hotkey": "0.2.0",
|
||||
"jotai": "2.20.0",
|
||||
"linkify-react": "4.3.3",
|
||||
"linkifyjs": "4.3.3",
|
||||
"lodash": "4.18.1",
|
||||
"matrix-js-sdk": "41.6.0-rc.0",
|
||||
"matrix-widget-api": "1.17.0",
|
||||
"jotai": "1.12.0",
|
||||
"katex": "0.16.4",
|
||||
"linkify-html": "4.0.2",
|
||||
"linkify-react": "4.1.1",
|
||||
"linkifyjs": "4.0.2",
|
||||
"matrix-js-sdk": "24.1.0",
|
||||
"millify": "6.1.0",
|
||||
"pdfjs-dist": "5.7.284",
|
||||
"prismjs": "1.30.0",
|
||||
"react": "19.2.6",
|
||||
"react-aria": "3.48.0",
|
||||
"react-blurhash": "0.3.0",
|
||||
"react-colorful": "5.7.0",
|
||||
"react-dom": "19.2.6",
|
||||
"react-error-boundary": "6.1.1",
|
||||
"react-google-recaptcha": "3.1.0",
|
||||
"react-i18next": "17.0.8",
|
||||
"react-range": "1.10.0",
|
||||
"react-router-dom": "7.15.1",
|
||||
"sanitize-html": "2.17.4",
|
||||
"slate": "0.124.1",
|
||||
"slate-dom": "0.124.1",
|
||||
"slate-history": "0.113.1",
|
||||
"slate-react": "0.124.2",
|
||||
"styled-components": "6.4.2",
|
||||
"ua-parser-js": "2.0.10"
|
||||
"pdfjs-dist": "3.10.111",
|
||||
"prismjs": "1.29.0",
|
||||
"prop-types": "15.8.1",
|
||||
"react": "17.0.2",
|
||||
"react-aria": "3.29.1",
|
||||
"react-autosize-textarea": "7.1.0",
|
||||
"react-blurhash": "0.2.0",
|
||||
"react-dnd": "15.1.2",
|
||||
"react-dnd-html5-backend": "15.1.3",
|
||||
"react-dom": "17.0.2",
|
||||
"react-error-boundary": "4.0.10",
|
||||
"react-google-recaptcha": "2.1.0",
|
||||
"react-modal": "3.16.1",
|
||||
"react-range": "1.8.14",
|
||||
"sanitize-html": "2.8.0",
|
||||
"slate": "0.94.1",
|
||||
"slate-history": "0.93.0",
|
||||
"slate-react": "0.98.4",
|
||||
"tippy.js": "6.3.7",
|
||||
"twemoji": "14.0.2",
|
||||
"ua-parser-js": "1.0.35"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@element-hq/element-call-embedded": "0.19.4",
|
||||
"@rollup/plugin-inject": "5.0.5",
|
||||
"@rollup/plugin-wasm": "6.2.2",
|
||||
"@sentry/vite-plugin": "5.3.0",
|
||||
"@types/chroma-js": "3.1.2",
|
||||
"@types/file-saver": "2.0.7",
|
||||
"@types/is-hotkey": "0.1.10",
|
||||
"@types/node": "25.9.1",
|
||||
"@types/prismjs": "1.26.6",
|
||||
"@types/react": "19.2.15",
|
||||
"@types/react-dom": "19.2.3",
|
||||
"@types/react-google-recaptcha": "2.1.9",
|
||||
"@types/sanitize-html": "2.16.1",
|
||||
"@types/ua-parser-js": "0.7.39",
|
||||
"@typescript-eslint/eslint-plugin": "8.59.4",
|
||||
"@typescript-eslint/parser": "8.59.4",
|
||||
"@vanilla-extract/css": "1.20.1",
|
||||
"@vanilla-extract/recipes": "0.5.7",
|
||||
"@vanilla-extract/vite-plugin": "5.2.2",
|
||||
"@vitejs/plugin-react": "6.0.2",
|
||||
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
|
||||
"@rollup/plugin-inject": "5.0.3",
|
||||
"@rollup/plugin-wasm": "6.1.1",
|
||||
"@types/file-saver": "2.0.5",
|
||||
"@types/node": "18.11.18",
|
||||
"@types/prismjs": "1.26.0",
|
||||
"@types/react": "18.0.26",
|
||||
"@types/react-dom": "18.0.9",
|
||||
"@types/sanitize-html": "2.9.0",
|
||||
"@types/ua-parser-js": "0.7.36",
|
||||
"@typescript-eslint/eslint-plugin": "5.46.1",
|
||||
"@typescript-eslint/parser": "5.46.1",
|
||||
"@vitejs/plugin-react": "3.0.0",
|
||||
"buffer": "6.0.3",
|
||||
"cz-conventional-changelog": "3.3.0",
|
||||
"eslint": "9.39.4",
|
||||
"eslint": "8.29.0",
|
||||
"eslint-config-airbnb": "19.0.4",
|
||||
"eslint-config-prettier": "10.1.8",
|
||||
"eslint-plugin-import": "2.32.0",
|
||||
"eslint-plugin-jsx-a11y": "6.10.2",
|
||||
"eslint-plugin-react": "7.37.5",
|
||||
"eslint-plugin-react-hooks": "7.1.1",
|
||||
"husky": "9.1.7",
|
||||
"lint-staged": "17.0.5",
|
||||
"prettier": "3.8.3",
|
||||
"typescript": "6.0.3",
|
||||
"vite": "8.0.14",
|
||||
"vite-plugin-pwa": "1.3.0",
|
||||
"vite-plugin-static-copy": "4.1.0"
|
||||
},
|
||||
"overrides": {
|
||||
"@giphy/js-util": {
|
||||
"dompurify": ">=3.3.4"
|
||||
},
|
||||
"js-cookie": ">=3.0.6"
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
"eslint-plugin-import": "2.26.0",
|
||||
"eslint-plugin-jsx-a11y": "6.6.1",
|
||||
"eslint-plugin-react": "7.31.11",
|
||||
"eslint-plugin-react-hooks": "4.6.0",
|
||||
"mini-svg-data-uri": "1.4.4",
|
||||
"prettier": "2.8.1",
|
||||
"sass": "1.56.2",
|
||||
"typescript": "4.9.4",
|
||||
"vite": "4.3.9",
|
||||
"vite-plugin-static-copy": "0.13.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"defaultHomeserver": 0,
|
||||
"homeserverList": ["matrix.lotusguild.org", "matrix.org", "mozilla.org"],
|
||||
"allowCustomHomeservers": true,
|
||||
"featuredCommunities": {
|
||||
"openAsDefault": false,
|
||||
"spaces": [],
|
||||
"rooms": [],
|
||||
"servers": []
|
||||
},
|
||||
"hashRouter": {
|
||||
"enabled": false,
|
||||
"basename": "/"
|
||||
},
|
||||
"gifApiKey": ""
|
||||
}
|
||||
|
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 32 KiB |
@@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang=en>
|
||||
<meta charset=utf-8>
|
||||
<meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
|
||||
<title>Error 404 (Not Found)!!1</title>
|
||||
<style>
|
||||
*{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}
|
||||
</style>
|
||||
<a href=//www.google.com/><span id=logo aria-label=Google></span></a>
|
||||
<p><b>404.</b> <ins>That’s an error.</ins>
|
||||
<p>The requested URL <code>/s/jetbrainsmono/v18/tDbY2o-flEEny0FZhsfKu5WU4xD-IQ.woff2</code> was not found on this server. <ins>That’s all we know.</ins>
|
||||
@@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang=en>
|
||||
<meta charset=utf-8>
|
||||
<meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
|
||||
<title>Error 404 (Not Found)!!1</title>
|
||||
<style>
|
||||
*{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}
|
||||
</style>
|
||||
<a href=//www.google.com/><span id=logo aria-label=Google></span></a>
|
||||
<p><b>404.</b> <ins>That’s an error.</ins>
|
||||
<p>The requested URL <code>/s/jetbrainsmono/v18/tDbY2o-flEEny0FZhsfKu5WU4xD-IQ.woff2</code> was not found on this server. <ins>That’s all we know.</ins>
|
||||
@@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang=en>
|
||||
<meta charset=utf-8>
|
||||
<meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
|
||||
<title>Error 404 (Not Found)!!1</title>
|
||||
<style>
|
||||
*{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}
|
||||
</style>
|
||||
<a href=//www.google.com/><span id=logo aria-label=Google></span></a>
|
||||
<p><b>404.</b> <ins>That’s an error.</ins>
|
||||
<p>The requested URL <code>/s/jetbrainsmono/v18/tDbY2o-flEEny0FZhsfKu5WU4xD-IQ.woff2</code> was not found on this server. <ins>That’s all we know.</ins>
|
||||
@@ -1,51 +0,0 @@
|
||||
/* Self-hosted fonts — avoids tracking prevention in desktop WebView2 */
|
||||
@font-face {
|
||||
font-family: 'JetBrains Mono';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url('/fonts/JetBrainsMono-italic-400.woff2') format('woff2');
|
||||
unicode-range:
|
||||
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
|
||||
U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'JetBrains Mono';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url('/fonts/JetBrainsMono-normal-400.woff2') format('woff2');
|
||||
unicode-range:
|
||||
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
|
||||
U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'JetBrains Mono';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url('/fonts/JetBrainsMono-normal-700.woff2') format('woff2');
|
||||
unicode-range:
|
||||
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
|
||||
U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Fira Code';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url('/fonts/FiraCode-400.woff2') format('woff2');
|
||||
unicode-range:
|
||||
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
|
||||
U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Fira Code';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: url('/fonts/FiraCode-600.woff2') format('woff2');
|
||||
unicode-range:
|
||||
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
|
||||
U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"Organisms": {
|
||||
"RoomCommon": {
|
||||
"changed_room_name": " hat den Raum Name geändert"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"Organisms": {
|
||||
"RoomCommon": {
|
||||
"changed_room_name": " changed room name"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,74 +1,59 @@
|
||||
{
|
||||
"name": "Lotus Chat",
|
||||
"short_name": "Lotus Chat",
|
||||
"description": "Lotus Chat \u2014 the Lotus Guild Matrix client",
|
||||
"name": "Cinny",
|
||||
"short_name": "Cinny",
|
||||
"description": "Yet another matrix client",
|
||||
"dir": "auto",
|
||||
"lang": "en-US",
|
||||
"display": "standalone",
|
||||
"orientation": "portrait",
|
||||
"start_url": "./",
|
||||
"background_color": "#0a0a0a",
|
||||
"theme_color": "#980000",
|
||||
"start_url": "/",
|
||||
"background_color": "#fff",
|
||||
"theme_color": "#fff",
|
||||
"icons": [
|
||||
{
|
||||
"src": "./res/android/android-chrome-36x36.png",
|
||||
"src": "/public/android/android-chrome-36x36.png",
|
||||
"sizes": "36x36",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "./res/android/android-chrome-48x48.png",
|
||||
"src": "/public/android/android-chrome-48x48.png",
|
||||
"sizes": "48x48",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "./res/android/android-chrome-72x72.png",
|
||||
"src": "/public/android/android-chrome-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "./res/android/android-chrome-96x96.png",
|
||||
"src": "/public/android/android-chrome-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "./res/android/android-chrome-144x144.png",
|
||||
"src": "/public/android/android-chrome-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "./res/android/android-chrome-192x192.png",
|
||||
"src": "/public/android/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "./res/android/android-chrome-256x256.png",
|
||||
"src": "/public/android/android-chrome-256x256.png",
|
||||
"sizes": "256x256",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "./res/android/android-chrome-384x384.png",
|
||||
"src": "/public/android/android-chrome-384x384.png",
|
||||
"sizes": "384x384",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "./res/android/android-chrome-512x512.png",
|
||||
"src": "/public/android/android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"categories": ["social", "communication", "productivity"],
|
||||
"shortcuts": [
|
||||
{
|
||||
"name": "New Message",
|
||||
"short_name": "DM",
|
||||
"description": "Open a new direct message",
|
||||
"url": "/",
|
||||
"icons": [
|
||||
{
|
||||
"src": "res/android/android-chrome-96x96.png",
|
||||
"sizes": "96x96"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 208 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 8.2 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 3.1 KiB |
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||
<g>
|
||||
<path fill="#231F20" d="M9,11H5c-1.1,0-2-0.9-2-2V5c0-1.1,0.9-2,2-2h4c1.1,0,2,0.9,2,2v4C11,10.1,10.1,11,9,11z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#231F20" d="M19,11h-4c-1.1,0-2-0.9-2-2V5c0-1.1,0.9-2,2-2h4c1.1,0,2,0.9,2,2v4C21,10.1,20.1,11,19,11z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#231F20" d="M9,21H5c-1.1,0-2-0.9-2-2v-4c0-1.1,0.9-2,2-2h4c1.1,0,2,0.9,2,2v4C11,20.1,10.1,21,9,21z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#231F20" d="M19,21h-4c-1.1,0-2-0.9-2-2v-4c0-1.1,0.9-2,2-2h4c1.1,0,2,0.9,2,2v4C21,20.1,20.1,21,19,21z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 940 B |
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||
<path d="M13.8,4.5l0.7,0.7l-3.4,3.4L7.7,9.7l-1-1l-1.4,1.4l3.5,3.5l-5.7,5.7l1.4,1.4l5.7-5.7l3.5,3.5l1.4-1.4l-1-1l1.1-3.4l3.4-3.4
|
||||
l0.7,0.7l1.4-1.4l-5.7-5.7L13.8,4.5z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 612 B |
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||
<g>
|
||||
<polygon points="12,2 15.1,8.6 22,9.6 17,14.8 18.2,22 12,18.6 5.8,22 7,14.8 2,9.6 8.9,8.6 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 549 B |
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||
<g>
|
||||
<path d="M13.8,4.7l0.7,0.7l-3.4,3.4L7.7,10l-1-1l-1.4,1.4l3.5,3.5l-5.7,5.7L4.6,21l5.7-5.7l3.5,3.5l1.4-1.4l-1-1l1.1-3.4l3.4-3.4
|
||||
l0.7,0.7L20.9,9l-5.7-5.7L13.8,4.7z M13.7,12l-1,2.9l-3.4-3.4l2.9-1l3.7-3.7l1.4,1.4L13.7,12z"/>
|
||||
<polygon points="10,3.3 7.8,3.3 7.8,1 6.3,1 6.3,3.3 4,3.3 4,4.8 6.3,4.8 6.3,7 7.8,7 7.8,4.8 10,4.8 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 781 B |
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||
<g>
|
||||
<path d="M14,11c2.2,0,4-1.8,4-4c0-2.2-1.8-4-4-4s-4,1.8-4,4C10,9.2,11.8,11,14,11z M14,5c1.1,0,2,0.9,2,2c0,1.1-0.9,2-2,2
|
||||
s-2-0.9-2-2C12,5.9,12.9,5,14,5z"/>
|
||||
<path d="M16,13h-4c-3.3,0-6,2.7-6,6v2h16v-2C22,15.7,19.3,13,16,13z M8,19c0-2.2,1.8-4,4-4h4c2.2,0,4,1.8,4,4H8z"/>
|
||||
<polygon points="8,9 5,9 5,6 3,6 3,9 0,9 0,11 3,11 3,14 5,14 5,11 8,11 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 801 B |
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||
<path d="M19.5,5.4c-0.5-0.5-1-1-1.5-1.4c-1.7-1.3-3.8-2-6-2S7.7,2.8,6,4C5.5,4.4,5,4.9,4.5,5.4C2.9,7.2,2,9.5,2,12
|
||||
c0,2.5,0.9,4.8,2.5,6.6c0.5,0.5,1,1,1.5,1.4c1.7,1.3,3.8,2,6,2s4.3-0.8,6-2c0.5-0.4,1-0.9,1.5-1.4c1.6-1.8,2.5-4.1,2.5-6.6
|
||||
C22,9.5,21.1,7.2,19.5,5.4z M4,12c0-2,0.8-3.9,2-5.3C7.2,8.1,8,10,8,12c0,2-0.8,3.9-2,5.3C4.8,15.9,4,14,4,12z M12,20
|
||||
c-1.7,0-3.2-0.5-4.5-1.4C9.1,16.8,10,14.5,10,12c0-2.5-0.9-4.8-2.5-6.6C8.8,4.5,10.3,4,12,4s3.2,0.5,4.5,1.4C14.9,7.2,14,9.5,14,12
|
||||
c0,2.5,0.9,4.8,2.5,6.6C15.2,19.5,13.7,20,12,20z M18,17.3c-1.2-1.4-2-3.3-2-5.3c0-2,0.8-3.9,2-5.3c1.2,1.4,2,3.3,2,5.3
|
||||
C20,14,19.2,15.9,18,17.3z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||
<g>
|
||||
<path d="M12,22c1.1,0,2-0.9,2-2h-4C10,21.1,10.9,22,12,22z"/>
|
||||
<path d="M20.1,18.1L20.1,18.1L16,14L9.2,7.2L7.8,5.8L5.9,3.9L4.5,5.3l2.1,2.1C6.2,8.2,6,9.1,6,10v6H4v2h13.2l1.5,1.5L20.1,18.1z
|
||||
M8,16v-6c0-0.4,0.1-0.7,0.1-1l7,7H8z"/>
|
||||
<path d="M12,6c2.2,0,4,1.8,4,4v1.2l2,2V10c0-3-2.2-5.4-5-5.9V3h-2v1.1c-0.6,0.1-1.1,0.3-1.6,0.5L11,6.1C11.3,6.1,11.6,6,12,6z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 810 B |
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||
<g>
|
||||
<circle cx="17" cy="8" r="3"/>
|
||||
<path d="M12,22c1.1,0,2-0.9,2-2h-4C10,21.1,10.9,22,12,22z"/>
|
||||
<path d="M18,12.9C17.7,13,17.3,13,17,13s-0.7,0-1-0.1V16H8v-6c0-2.2,1.8-4,4-4c0.1,0,0.3,0,0.4,0c0.3-0.7,0.7-1.3,1.3-1.8
|
||||
c-0.2-0.1-0.5-0.1-0.7-0.2V3h-2v1.1C8.2,4.6,6,7,6,10v6H4v2h16v-2h-2V12.9z"/>
|
||||
<path d="M6.3,4.3L4.9,2.9C3.1,4.7,2,7.2,2,10h2C4,7.8,4.9,5.8,6.3,4.3z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 819 B |
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||
<g>
|
||||
<path d="M12,22c1.1,0,2-0.9,2-2h-4C10,21.1,10.9,22,12,22z"/>
|
||||
<path d="M18,10c0-3-2.2-5.4-5-5.9V3h-2v1.1C8.2,4.6,6,7,6,10v6H4v2h16v-2h-2V10z M16,16H8v-6c0-2.2,1.8-4,4-4s4,1.8,4,4V16z"/>
|
||||
<path d="M6.3,4.3L4.9,2.9C3.1,4.7,2,7.2,2,10h2C4,7.8,4.9,5.8,6.3,4.3z"/>
|
||||
<path d="M19.1,2.9l-1.4,1.4C19.1,5.8,20,7.8,20,10h2C22,7.2,20.9,4.7,19.1,2.9z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 796 B |
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||
<g>
|
||||
<path d="M12,22c1.1,0,2-0.9,2-2h-4C10,21.1,10.9,22,12,22z"/>
|
||||
<path d="M18,16v-6c0-3-2.2-5.4-5-5.9V3h-2v1.1C8.2,4.6,6,7,6,10v6H4v2h16v-2H18z M16,16H8v-6c0-2.2,1.8-4,4-4s4,1.8,4,4V16z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 640 B |
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<rect x="9" y="8" width="2" height="8"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="13" y="8" width="2" height="8"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="M21,3h-5l-1.4-1.4C14.2,1.2,13.7,1,13.2,1h-2.3c-0.5,0-1,0.2-1.4,0.6L8,3H3v2h2v14c0,1.1,0.9,2,2,2h10c1.1,0,2-0.9,2-2V5h2
|
||||
V3z M17,19H7V5h10V19z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 735 B |
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||
<path d="M12,2c-0.3,0-0.6,0-0.9,0.1c-3.5,0.4-6.4,3.2-7,6.7c-0.5,3.1,0.8,6,3.1,7.7C7.7,16.8,8,17.4,8,18v4h8v-4
|
||||
c0-0.6,0.3-1.2,0.8-1.6c1.9-1.5,3.2-3.8,3.2-6.4C20,5.6,16.4,2,12,2z M15.6,14.8c-1,0.7-1.6,1.9-1.6,3.2v2h-1.3v-8.1
|
||||
c0.7-0.3,1.3-1,1.3-1.9c0-1.1-0.9-2-2-2s-2,0.9-2,2c0,0.8,0.5,1.6,1.3,1.9V20H10v-2c0-1.2-0.6-2.4-1.6-3.2C6.6,13.4,5.7,11.3,6.1,9
|
||||
c0.4-2.6,2.6-4.7,5.2-5c0.2,0,0.5,0,0.7,0c3.3,0,6,2.7,6,6C18,11.9,17.1,13.7,15.6,14.8z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 886 B |
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||
<g>
|
||||
<path fill="#221F1F" d="M9,5v4H5V5H9 M9,3H5C3.9,3,3,3.9,3,5v4c0,1.1,0.9,2,2,2h4c1.1,0,2-0.9,2-2V5C11,3.9,10.1,3,9,3L9,3z"/>
|
||||
<path fill="#221F1F" d="M19,5v4h-4V5H19 M19,3h-4c-1.1,0-2,0.9-2,2v4c0,1.1,0.9,2,2,2h4c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3L19,3
|
||||
z"/>
|
||||
<path fill="#221F1F" d="M9,15v4H5v-4H9 M9,13H5c-1.1,0-2,0.9-2,2v4c0,1.1,0.9,2,2,2h4c1.1,0,2-0.9,2-2v-4C11,13.9,10.1,13,9,13
|
||||
L9,13z"/>
|
||||
<path fill="#221F1F" d="M19,15v4h-4v-4H19 M19,13h-4c-1.1,0-2,0.9-2,2v4c0,1.1,0.9,2,2,2h4c1.1,0,2-0.9,2-2v-4
|
||||
C21,13.9,20.1,13,19,13L19,13z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 995 B |