bluesky client without react native baggage written in sveltekit

added liked states to post and added story

+323 -28
+1
.storybook/preview.ts
··· 1 1 import type { Preview } from '@storybook/sveltekit' 2 + import '../src/routes/layout.css' 2 3 3 4 const preview: Preview = { 4 5 parameters: {
+2
package.json
··· 22 22 "@chromatic-com/storybook": "^5.0.1", 23 23 "@eslint/compat": "^2.0.2", 24 24 "@eslint/js": "^9.39.2", 25 + "@iconify/json": "^2.2.444", 26 + "@iconify/tailwind4": "^1.2.1", 25 27 "@playwright/test": "^1.58.1", 26 28 "@storybook/addon-a11y": "^10.2.10", 27 29 "@storybook/addon-docs": "^10.2.10",
+242
pnpm-lock.yaml
··· 39 39 '@eslint/js': 40 40 specifier: ^9.39.2 41 41 version: 9.39.3 42 + '@iconify/json': 43 + specifier: ^2.2.444 44 + version: 2.2.444 45 + '@iconify/tailwind4': 46 + specifier: ^1.2.1 47 + version: 1.2.1(tailwindcss@4.2.0) 42 48 '@playwright/test': 43 49 specifier: ^1.58.1 44 50 version: 1.58.2 ··· 141 147 '@adobe/css-tools@4.4.4': 142 148 resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==} 143 149 150 + '@antfu/install-pkg@1.1.0': 151 + resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} 152 + 144 153 '@atcute/atproto@3.1.10': 145 154 resolution: {integrity: sha512-+GKZpOc0PJcdWMQEkTfg/rSNDAAHxmAUGBl60g2az15etqJn5WaUPNGFE2sB7hKpwi5Ue2h/L0OacINcE/JDDQ==} 146 155 ··· 229 238 engines: {node: '>=20.0.0', yarn: '>=1.22.18'} 230 239 peerDependencies: 231 240 storybook: ^0.0.0-0 || ^10.1.0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0 241 + 242 + '@cyberalien/svg-utils@1.2.0': 243 + resolution: {integrity: sha512-Y2Nf5DPa8LbYXlafRY6j31T15QLG88tkOdI08HCfhFwZqROIbmg0nqhRojoDIiwd0LuAa24pJd7biZAjHaK+mQ==} 232 244 233 245 '@esbuild/aix-ppc64@0.27.3': 234 246 resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} ··· 452 464 '@humanwhocodes/retry@0.4.3': 453 465 resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} 454 466 engines: {node: '>=18.18'} 467 + 468 + '@iconify/json@2.2.444': 469 + resolution: {integrity: sha512-z0UwFaVtaN/h/iWZ1kzEjqFU3sp0rRy93tzOtpepZU89DY39WsNeYZv2mxtft/2La6Bz2b4z1C/HkU5Cqv3gbw==} 470 + 471 + '@iconify/tailwind4@1.2.1': 472 + resolution: {integrity: sha512-Hd7k8y7uzT3hk8ltw0jGku0r0wA8sc3d2iMvVTYv/9tMxBb+frZtWZGD9hDMU3EYuE+lMn58wi2lS8R2ZbwFcQ==} 473 + peerDependencies: 474 + tailwindcss: '>= 4.0.0' 475 + 476 + '@iconify/tools@5.0.3': 477 + resolution: {integrity: sha512-W5nbH5fNv20TvU49Al19Foos/ViAnmppbCNV9ieGl6/dRMDRzxeFol6peXX/NAgaOytQwZZxTTJRq/Kxd4eWsA==} 478 + 479 + '@iconify/types@2.0.0': 480 + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} 481 + 482 + '@iconify/utils@3.1.0': 483 + resolution: {integrity: sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==} 455 484 456 485 '@jridgewell/gen-mapping@0.3.13': 457 486 resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} ··· 1098 1127 resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} 1099 1128 engines: {node: 18 || 20 || >=22} 1100 1129 1130 + boolbase@1.0.0: 1131 + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} 1132 + 1101 1133 brace-expansion@1.1.12: 1102 1134 resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} 1103 1135 ··· 1156 1188 color-name@1.1.4: 1157 1189 resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 1158 1190 1191 + commander@11.1.0: 1192 + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} 1193 + engines: {node: '>=16'} 1194 + 1159 1195 concat-map@0.0.1: 1160 1196 resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 1197 + 1198 + confbox@0.1.8: 1199 + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} 1161 1200 1162 1201 cookie@0.6.0: 1163 1202 resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} ··· 1167 1206 resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} 1168 1207 engines: {node: '>= 8'} 1169 1208 1209 + css-select@5.2.2: 1210 + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} 1211 + 1212 + css-tree@2.2.1: 1213 + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} 1214 + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} 1215 + 1216 + css-tree@3.1.0: 1217 + resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} 1218 + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} 1219 + 1220 + css-what@6.2.2: 1221 + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} 1222 + engines: {node: '>= 6'} 1223 + 1170 1224 css.escape@1.5.1: 1171 1225 resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} 1172 1226 ··· 1174 1228 resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} 1175 1229 engines: {node: '>=4'} 1176 1230 hasBin: true 1231 + 1232 + csso@5.0.5: 1233 + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} 1234 + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} 1177 1235 1178 1236 csstype@3.2.3: 1179 1237 resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} ··· 1238 1296 dom-accessibility-api@0.6.3: 1239 1297 resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} 1240 1298 1299 + dom-serializer@2.0.0: 1300 + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} 1301 + 1302 + domelementtype@2.3.0: 1303 + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} 1304 + 1305 + domhandler@5.0.3: 1306 + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} 1307 + engines: {node: '>= 4'} 1308 + 1309 + domutils@3.2.2: 1310 + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} 1311 + 1241 1312 enhanced-resolve@5.19.0: 1242 1313 resolution: {integrity: sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==} 1243 1314 engines: {node: '>=10.13.0'} 1315 + 1316 + entities@4.5.0: 1317 + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} 1318 + engines: {node: '>=0.12'} 1244 1319 1245 1320 es-module-lexer@1.7.0: 1246 1321 resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} ··· 1366 1441 peerDependenciesMeta: 1367 1442 picomatch: 1368 1443 optional: true 1444 + 1445 + fflate@0.8.2: 1446 + resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} 1369 1447 1370 1448 file-entry-cache@8.0.0: 1371 1449 resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} ··· 1627 1705 resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} 1628 1706 engines: {node: '>=10'} 1629 1707 1708 + mdn-data@2.0.28: 1709 + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} 1710 + 1711 + mdn-data@2.12.2: 1712 + resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} 1713 + 1630 1714 min-indent@1.0.1: 1631 1715 resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} 1632 1716 engines: {node: '>=4'} ··· 1637 1721 minimatch@9.0.6: 1638 1722 resolution: {integrity: sha512-kQAVowdR33euIqeA0+VZTDqU+qo1IeVY+hrKYtZMio3Pg0P0vuh/kwRylLUddJhB6pf3q/botcOvRtx4IN1wqQ==} 1639 1723 engines: {node: '>=16 || 14 >=14.17'} 1724 + 1725 + mlly@1.8.0: 1726 + resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} 1727 + 1728 + modern-tar@0.7.5: 1729 + resolution: {integrity: sha512-YTefgdpKKFgoTDbEUqXqgUJct2OG6/4hs4XWLsxcHkDLj/x/V8WmKIRppPnXP5feQ7d1vuYWSp3qKkxfwaFaxA==} 1730 + engines: {node: '>=18.0.0'} 1640 1731 1641 1732 mri@1.2.0: 1642 1733 resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} ··· 1662 1753 natural-compare@1.4.0: 1663 1754 resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} 1664 1755 1756 + nth-check@2.1.1: 1757 + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} 1758 + 1665 1759 obug@2.1.1: 1666 1760 resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} 1667 1761 ··· 1680 1774 p-locate@5.0.0: 1681 1775 resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} 1682 1776 engines: {node: '>=10'} 1777 + 1778 + package-manager-detector@1.6.0: 1779 + resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} 1683 1780 1684 1781 parent-module@1.0.1: 1685 1782 resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} ··· 1710 1807 pixelmatch@7.1.0: 1711 1808 resolution: {integrity: sha512-1wrVzJ2STrpmONHKBy228LM1b84msXDUoAzVEl0R8Mz4Ce6EPr+IVtxm8+yvrqLYMHswREkjYFaMxnyGnaY3Ng==} 1712 1809 hasBin: true 1810 + 1811 + pkg-types@1.3.1: 1812 + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} 1713 1813 1714 1814 playwright-core@1.58.2: 1715 1815 resolution: {integrity: sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==} ··· 1876 1976 resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} 1877 1977 engines: {node: '>=6'} 1878 1978 1979 + sax@1.4.4: 1980 + resolution: {integrity: sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==} 1981 + engines: {node: '>=11.0.0'} 1982 + 1879 1983 scheduler@0.27.0: 1880 1984 resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} 1881 1985 ··· 1977 2081 resolution: {integrity: sha512-yGONuIrcl/BMmqbm6/52Q/NYzfkta7uVlos5NSzGTfNJTTFtPPzra6rAQoQIwAqupeM3s9uuTf5PvioeiCdg9g==} 1978 2082 engines: {node: '>=18'} 1979 2083 2084 + svgo@4.0.0: 2085 + resolution: {integrity: sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==} 2086 + engines: {node: '>=16'} 2087 + hasBin: true 2088 + 1980 2089 tailwindcss@4.2.0: 1981 2090 resolution: {integrity: sha512-yYzTZ4++b7fNYxFfpnberEEKu43w44aqDMNM9MHMmcKuCH7lL8jJ4yJ7LGHv7rSwiqM0nkiobF9I6cLlpS2P7Q==} 1982 2091 ··· 2046 2155 resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} 2047 2156 engines: {node: '>=14.17'} 2048 2157 hasBin: true 2158 + 2159 + ufo@1.6.3: 2160 + resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} 2049 2161 2050 2162 undici-types@6.21.0: 2051 2163 resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} ··· 2220 2332 2221 2333 '@adobe/css-tools@4.4.4': {} 2222 2334 2335 + '@antfu/install-pkg@1.1.0': 2336 + dependencies: 2337 + package-manager-detector: 1.6.0 2338 + tinyexec: 1.0.2 2339 + 2223 2340 '@atcute/atproto@3.1.10': 2224 2341 dependencies: 2225 2342 '@atcute/lexicons': 1.2.9 ··· 2337 2454 transitivePeerDependencies: 2338 2455 - '@chromatic-com/cypress' 2339 2456 - '@chromatic-com/playwright' 2457 + 2458 + '@cyberalien/svg-utils@1.2.0': 2459 + dependencies: 2460 + '@iconify/types': 2.0.0 2340 2461 2341 2462 '@esbuild/aix-ppc64@0.27.3': 2342 2463 optional: true ··· 2483 2604 2484 2605 '@humanwhocodes/retry@0.4.3': {} 2485 2606 2607 + '@iconify/json@2.2.444': 2608 + dependencies: 2609 + '@iconify/types': 2.0.0 2610 + pathe: 2.0.3 2611 + 2612 + '@iconify/tailwind4@1.2.1(tailwindcss@4.2.0)': 2613 + dependencies: 2614 + '@iconify/tools': 5.0.3 2615 + '@iconify/types': 2.0.0 2616 + '@iconify/utils': 3.1.0 2617 + tailwindcss: 4.2.0 2618 + 2619 + '@iconify/tools@5.0.3': 2620 + dependencies: 2621 + '@cyberalien/svg-utils': 1.2.0 2622 + '@iconify/types': 2.0.0 2623 + '@iconify/utils': 3.1.0 2624 + fflate: 0.8.2 2625 + modern-tar: 0.7.5 2626 + pathe: 2.0.3 2627 + svgo: 4.0.0 2628 + 2629 + '@iconify/types@2.0.0': {} 2630 + 2631 + '@iconify/utils@3.1.0': 2632 + dependencies: 2633 + '@antfu/install-pkg': 1.1.0 2634 + '@iconify/types': 2.0.0 2635 + mlly: 1.8.0 2636 + 2486 2637 '@jridgewell/gen-mapping@0.3.13': 2487 2638 dependencies: 2488 2639 '@jridgewell/sourcemap-codec': 1.5.5 ··· 3138 3289 3139 3290 balanced-match@4.0.4: {} 3140 3291 3292 + boolbase@1.0.0: {} 3293 + 3141 3294 brace-expansion@1.1.12: 3142 3295 dependencies: 3143 3296 balanced-match: 1.0.2 ··· 3184 3337 3185 3338 color-name@1.1.4: {} 3186 3339 3340 + commander@11.1.0: {} 3341 + 3187 3342 concat-map@0.0.1: {} 3343 + 3344 + confbox@0.1.8: {} 3188 3345 3189 3346 cookie@0.6.0: {} 3190 3347 ··· 3194 3351 shebang-command: 2.0.0 3195 3352 which: 2.0.2 3196 3353 3354 + css-select@5.2.2: 3355 + dependencies: 3356 + boolbase: 1.0.0 3357 + css-what: 6.2.2 3358 + domhandler: 5.0.3 3359 + domutils: 3.2.2 3360 + nth-check: 2.1.1 3361 + 3362 + css-tree@2.2.1: 3363 + dependencies: 3364 + mdn-data: 2.0.28 3365 + source-map-js: 1.2.1 3366 + 3367 + css-tree@3.1.0: 3368 + dependencies: 3369 + mdn-data: 2.12.2 3370 + source-map-js: 1.2.1 3371 + 3372 + css-what@6.2.2: {} 3373 + 3197 3374 css.escape@1.5.1: {} 3198 3375 3199 3376 cssesc@3.0.0: {} 3377 + 3378 + csso@5.0.5: 3379 + dependencies: 3380 + css-tree: 2.2.1 3200 3381 3201 3382 csstype@3.2.3: {} 3202 3383 ··· 3233 3414 3234 3415 dom-accessibility-api@0.6.3: {} 3235 3416 3417 + dom-serializer@2.0.0: 3418 + dependencies: 3419 + domelementtype: 2.3.0 3420 + domhandler: 5.0.3 3421 + entities: 4.5.0 3422 + 3423 + domelementtype@2.3.0: {} 3424 + 3425 + domhandler@5.0.3: 3426 + dependencies: 3427 + domelementtype: 2.3.0 3428 + 3429 + domutils@3.2.2: 3430 + dependencies: 3431 + dom-serializer: 2.0.0 3432 + domelementtype: 2.3.0 3433 + domhandler: 5.0.3 3434 + 3236 3435 enhanced-resolve@5.19.0: 3237 3436 dependencies: 3238 3437 graceful-fs: 4.2.11 3239 3438 tapable: 2.3.0 3439 + 3440 + entities@4.5.0: {} 3240 3441 3241 3442 es-module-lexer@1.7.0: {} 3242 3443 ··· 3406 3607 fdir@6.5.0(picomatch@4.0.3): 3407 3608 optionalDependencies: 3408 3609 picomatch: 4.0.3 3610 + 3611 + fflate@0.8.2: {} 3409 3612 3410 3613 file-entry-cache@8.0.0: 3411 3614 dependencies: ··· 3607 3810 dependencies: 3608 3811 semver: 7.7.4 3609 3812 3813 + mdn-data@2.0.28: {} 3814 + 3815 + mdn-data@2.12.2: {} 3816 + 3610 3817 min-indent@1.0.1: {} 3611 3818 3612 3819 minimatch@3.1.3: ··· 3617 3824 dependencies: 3618 3825 brace-expansion: 5.0.3 3619 3826 3827 + mlly@1.8.0: 3828 + dependencies: 3829 + acorn: 8.16.0 3830 + pathe: 2.0.3 3831 + pkg-types: 1.3.1 3832 + ufo: 1.6.3 3833 + 3834 + modern-tar@0.7.5: {} 3835 + 3620 3836 mri@1.2.0: {} 3621 3837 3622 3838 mrmime@2.0.1: {} ··· 3628 3844 nanoid@5.1.6: {} 3629 3845 3630 3846 natural-compare@1.4.0: {} 3847 + 3848 + nth-check@2.1.1: 3849 + dependencies: 3850 + boolbase: 1.0.0 3631 3851 3632 3852 obug@2.1.1: {} 3633 3853 ··· 3655 3875 dependencies: 3656 3876 p-limit: 3.1.0 3657 3877 3878 + package-manager-detector@1.6.0: {} 3879 + 3658 3880 parent-module@1.0.1: 3659 3881 dependencies: 3660 3882 callsites: 3.1.0 ··· 3675 3897 dependencies: 3676 3898 pngjs: 7.0.0 3677 3899 3900 + pkg-types@1.3.1: 3901 + dependencies: 3902 + confbox: 0.1.8 3903 + mlly: 1.8.0 3904 + pathe: 2.0.3 3905 + 3678 3906 playwright-core@1.58.2: {} 3679 3907 3680 3908 playwright@1.58.2: ··· 3797 4025 dependencies: 3798 4026 mri: 1.2.0 3799 4027 4028 + sax@1.4.4: {} 4029 + 3800 4030 scheduler@0.27.0: {} 3801 4031 3802 4032 scule@1.3.0: {} ··· 3919 4149 magic-string: 0.30.21 3920 4150 zimmerframe: 1.1.4 3921 4151 4152 + svgo@4.0.0: 4153 + dependencies: 4154 + commander: 11.1.0 4155 + css-select: 5.2.2 4156 + css-tree: 3.1.0 4157 + css-what: 6.2.2 4158 + csso: 5.0.5 4159 + picocolors: 1.1.1 4160 + sax: 1.4.4 4161 + 3922 4162 tailwindcss@4.2.0: {} 3923 4163 3924 4164 tapable@2.3.0: {} ··· 3968 4208 - supports-color 3969 4209 3970 4210 typescript@5.9.3: {} 4211 + 4212 + ufo@1.6.3: {} 3971 4213 3972 4214 undici-types@6.21.0: {} 3973 4215
+1 -1
src/lib/components/Avatar.svelte
··· 3 3 4 4 let { user }: { user: AppBskyActorDefs.ProfileViewDetailed } = $props() 5 5 </script> 6 - <img class="ml-2.5 mr-2 w-10.5 h-10.5 rounded-lg" src={user.avatar} alt={`${user.displayName || user.handle}'s avatar'`}> 6 + <img class="w-10.5 h-10.5 block rounded-lg" src={user.avatar} alt={`${user.displayName || user.handle}'s avatar'`}>
+43
src/lib/components/Post.stories.svelte
··· 1 + <script module> 2 + import { defineMeta } from '@storybook/addon-svelte-csf'; 3 + import Post from './Post.svelte'; 4 + 5 + const basePost = { 6 + uri: 'at://did:plc:example/app.bsky.feed.post/123', 7 + cid: 'bafyreiexample', 8 + author: { 9 + did: 'did:plc:example', 10 + handle: 'user.bsky.social', 11 + displayName: 'Example User', 12 + avatar: 'https://picsum.photos/seed/avatar/48/48', 13 + }, 14 + record: { 15 + $type: 'app.bsky.feed.post', 16 + text: 'Hello world! This is an example Bluesky post.', 17 + createdAt: '2024-01-01T00:00:00Z', 18 + }, 19 + replyCount: 3, 20 + repostCount: 12, 21 + likeCount: 42, 22 + indexedAt: '2024-01-01T00:00:00Z', 23 + viewer: {}, 24 + }; 25 + 26 + const { Story } = defineMeta({ 27 + title: 'Components/Post', 28 + component: Post, 29 + tags: ['autodocs'], 30 + }); 31 + </script> 32 + 33 + <Story name="Default" args={{ post: basePost }} /> 34 + 35 + <Story name="Liked" args={{ post: { ...basePost, viewer: { like: 'at://liked' } } }} /> 36 + 37 + <Story name="WithImage" args={{ post: { 38 + ...basePost, 39 + embed: { 40 + $type: 'app.bsky.embed.images#view', 41 + images: [{ thumb: 'https://picsum.photos/seed/post/600/400', alt: 'Example image', fullsize: '', aspectRatio: { width: 600, height: 400 } }] 42 + } 43 + }}} />
+15 -6
src/lib/components/Post.svelte
··· 3 3 import Avatar from "./Avatar.svelte"; 4 4 import type { PostView } from "@atcute/bluesky/types/app/feed/defs"; 5 5 6 - let { post }: { post: PostView } = $props(); 6 + let { post }: { post: PostView } = $props(); 7 + console.log(post) 8 + // let liked = post.viewer?.like; 9 + let liked = Object.hasOwn(post.viewer, "like"); 7 10 </script> 8 11 9 12 <article class="flex pr-4 pl-2.5 pt-2 pb-2 border-post-border border"> 10 - <Avatar user={post.author} /> 13 + <div class="ml-2 mr-2.5 shrink-0"> 14 + <Avatar user={post.author} /> 15 + </div> 11 16 <div> 12 17 <div class="mb-1"> 13 18 <a href="#" > ··· 24 29 {/if} 25 30 {/if} 26 31 <div class="flex mt-0.5 w-full"> 27 - <div class="max-w-[320px] w-full flex justify-between"> 28 - <div class="grow">💬 {post.replyCount}</div> 29 - <div class="grow">🔁 {post.repostCount}</div> 30 - <div class="grow">❤️ {post.likeCount}</div> 32 + <div class="w-[320px] max-w-[320px] flex justify-between"> 33 + <div class="grow"><button class="flex items-center gap-1 py-1.25 pr-1.25"><span class="icon-[boxicons--message-reply] w-4.5 h-4.5 text-4.5"></span> {post.replyCount}</button></div> 34 + <div class="grow flex items-center gap-1"><span class="icon-[mdi--repost] w-4.5 h-4.5 text-4.5"></span> {post.repostCount}</div> 35 + {#if liked} 36 + <div class="grow flex items-center gap-1"><span class="icon-[icon-park-solid--like] w-4.5 h-4.5 text-4.5 fill-red"></span> {post.likeCount}</div> 37 + {:else} 38 + <div class="grow flex items-center gap-1"><span class="icon-[icon-park-outline--like] w-4.5 h-4.5 text-4.5"></span> {post.likeCount}</div> 39 + {/if} 31 40 </div> 32 41 </div> 33 42 </div>
+9 -1
src/routes/+layout.js
··· 1 - export const ssr = false; 1 + import { resumeSession, getProfile } from '$lib/atproto'; 2 + 3 + export async function load() { 4 + const loggedIn = await resumeSession(); 5 + const profile = loggedIn ? await getProfile() : null; 6 + return { loggedIn, profile }; 7 + } 8 + 9 + export const ssr = false;
+3 -17
src/routes/+layout.svelte
··· 1 1 <script lang="ts"> 2 2 import './layout.css'; 3 3 import favicon from '$lib/assets/favicon.svg'; 4 - import { onMount } from 'svelte'; 5 - import { resumeSession, getProfile } from '$lib/atproto'; 6 4 import { setUserContext } from '$lib/context'; 7 5 import type { AppBskyActorDefs } from '@atcute/bluesky'; 8 6 9 - let { children } = $props(); 10 - 11 - let loggedIn = $state(false); 12 - let profile = $state<AppBskyActorDefs.ProfileViewDetailed | null>(null); 7 + let { children, data } = $props(); 13 8 14 9 setUserContext({ 15 - get loggedIn() { return loggedIn; }, 16 - set loggedIn(v: boolean) { loggedIn = v; }, 17 - get profile() { return profile; }, 18 - set profile(v) { profile = v; } 19 - }); 20 - 21 - onMount(async () => { 22 - loggedIn = await resumeSession(); 23 - if (loggedIn) { 24 - profile = await getProfile(); 25 - } 10 + loggedIn: data.loggedIn, 11 + profile: data.profile 26 12 }); 27 13 </script> 28 14
+5 -3
src/routes/+page.svelte
··· 22 22 23 23 <div class="mx-auto flex max-h-screen max-w-290"> 24 24 <div class="sidebar p-4"> 25 - {#if user.loggedIn} 26 - <p>Logged in</p> 25 + {#if user.loggedIn && user.profile} 27 26 <div class="flex items-center gap-2"> 28 27 <Avatar user={user.profile} /> 29 28 {user.profile?.handle} 30 29 </div> 30 + <button class="flex align-items bg-post-button gap-3 rounded-full py-3 px-6 text-white hover:cursor-pointer"> 31 + New Post 32 + </button> 31 33 {:else} 32 34 <form onsubmit={(e) => { e.preventDefault(); handleLogin(); }}> 33 35 <input ··· 57 59 <style> 58 60 .sidebar { 59 61 height: 100vh; 60 - flex-grow: 1; 62 + flex: 1 0 0; 61 63 } 62 64 </style>
+2
src/routes/layout.css
··· 1 1 @import 'tailwindcss'; 2 + @plugin '@iconify/tailwind4'; 2 3 3 4 @theme { 4 5 --color-post-border: rgb(222, 225, 234); 5 6 --color-secondary-text: rgb(71, 79, 104); 7 + --color-post-button: rgb(0, 106, 255); 6 8 } 7 9 8 10 html,