diff --git a/package.json b/package.json index c4c29051..8ca3ceb5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "intuition-chrome-extension", "displayName": "Intuition Chrome Extension", - "version": "0.1.44", + "version": "0.1.45", "description": "", "author": "THP-Lab.org", "scripts": { @@ -61,7 +61,7 @@ "autoprefixer": "10.4.16", "concurrently": "^8.2.2", "cross-env": "^7.0.3", - "plasmo": "0.90.3", + "plasmo": "0.90.5", "postcss": "8.4.31", "prettier": "3.2.4", "svgo": "^3.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e8001e72..9dbb9761 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -151,8 +151,8 @@ importers: specifier: ^7.0.3 version: 7.0.3 plasmo: - specifier: 0.90.3 - version: 0.90.3(@swc/core@1.11.11(@swc/helpers@0.5.15))(@swc/helpers@0.5.15)(@types/node@20.11.5)(lodash@4.17.21)(postcss@8.4.31)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: 0.90.5 + version: 0.90.5(@swc/core@1.11.11(@swc/helpers@0.5.15))(@swc/helpers@0.5.15)(@types/node@20.11.5)(lodash@4.17.21)(postcss@8.4.31)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) postcss: specifier: 8.4.31 version: 8.4.31 @@ -1998,36 +1998,18 @@ packages: resolution: {integrity: sha512-cesanjtj/oLehW8Waq9JFPmAImhoiHX03ihc3JTWkrvJYSbD7wYKCDgPAM3JiRAqvh1LZ6P699uITrYWNoRLUg==} engines: {node: '>= 12.0.0'} - '@parcel/watcher-android-arm64@2.2.0': - resolution: {integrity: sha512-nU2wh00CTQT9rr1TIKTjdQ9lAGYpmz6XuKw0nAwAN+S2A5YiD55BK1u+E5WMCT8YOIDe/n6gaj4o/Bi9294SSQ==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [android] - '@parcel/watcher-android-arm64@2.5.1': resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [android] - '@parcel/watcher-darwin-arm64@2.2.0': - resolution: {integrity: sha512-cJl0UZDcodciy3TDMomoK/Huxpjlkkim3SyMgWzjovHGOZKNce9guLz2dzuFwfObBFCjfznbFMIvAZ5syXotYw==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [darwin] - '@parcel/watcher-darwin-arm64@2.5.1': resolution: {integrity: sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [darwin] - '@parcel/watcher-darwin-x64@2.2.0': - resolution: {integrity: sha512-QI77zxaGrCV1StKcoRYfsUfmUmvPMPfQrubkBBy5XujV2fwaLgZivQOTQMBgp5K2+E19u1ufpspKXAPqSzpbyg==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [darwin] - '@parcel/watcher-darwin-x64@2.5.1': resolution: {integrity: sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==} engines: {node: '>= 10.0.0'} @@ -2040,12 +2022,6 @@ packages: cpu: [x64] os: [freebsd] - '@parcel/watcher-linux-arm-glibc@2.2.0': - resolution: {integrity: sha512-I2GPBcAXazPzabCmfsa3HRRW+MGlqxYd8g8RIueJU+a4o5nyNZDz0CR1cu0INT0QSQXEZV7w6UE8Hz9CF8u3Pg==} - engines: {node: '>= 10.0.0'} - cpu: [arm] - os: [linux] - '@parcel/watcher-linux-arm-glibc@2.5.1': resolution: {integrity: sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==} engines: {node: '>= 10.0.0'} @@ -2058,60 +2034,30 @@ packages: cpu: [arm] os: [linux] - '@parcel/watcher-linux-arm64-glibc@2.2.0': - resolution: {integrity: sha512-St5mlfp+2lS9AmgixUqfwJa/DwVmTCJxC1HcOubUTz6YFOKIlkHCeUa1Bxi4E/tR/HSez8+heXHL8HQkJ4Bd8g==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [linux] - '@parcel/watcher-linux-arm64-glibc@2.5.1': resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] - '@parcel/watcher-linux-arm64-musl@2.2.0': - resolution: {integrity: sha512-jS+qfhhoOBVWwMLP65MaG8xdInMK30pPW8wqTCg2AAuVJh5xepMbzkhHJ4zURqHiyY3EiIRuYu4ONJKCxt8iqA==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [linux] - '@parcel/watcher-linux-arm64-musl@2.5.1': resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] - '@parcel/watcher-linux-x64-glibc@2.2.0': - resolution: {integrity: sha512-xJvJ7R2wJdi47WZBFS691RDOWvP1j/IAs3EXaWVhDI8FFITbWrWaln7KoNcR0Y3T+ZwimFY/cfb0PNht1q895g==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [linux] - '@parcel/watcher-linux-x64-glibc@2.5.1': resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] - '@parcel/watcher-linux-x64-musl@2.2.0': - resolution: {integrity: sha512-D+NMpgr23a+RI5mu8ZPKWy7AqjBOkURFDgP5iIXXEf/K3hm0jJ3ogzi0Ed2237B/CdYREimCgXyeiAlE/FtwyA==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [linux] - '@parcel/watcher-linux-x64-musl@2.5.1': resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] - '@parcel/watcher-win32-arm64@2.2.0': - resolution: {integrity: sha512-z225cPn3aygJsyVUOWwfyW+fY0Tvk7N3XCOl66qUPFxpbuXeZuiuuJemmtm8vxyqa3Ur7peU/qJxrpC64aeI7Q==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [win32] - '@parcel/watcher-win32-arm64@2.5.1': resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==} engines: {node: '>= 10.0.0'} @@ -2124,22 +2070,12 @@ packages: cpu: [ia32] os: [win32] - '@parcel/watcher-win32-x64@2.2.0': - resolution: {integrity: sha512-JqGW0RJ61BkKx+yYzIURt9s53P7xMVbv0uxYPzAXLBINGaFmkIKSuUPyBVfy8TMbvp93lvF4SPBNDzVRJfvgOw==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [win32] - '@parcel/watcher-win32-x64@2.5.1': resolution: {integrity: sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [win32] - '@parcel/watcher@2.2.0': - resolution: {integrity: sha512-71S4TF+IMyAn24PK4KSkdKtqJDR3zRzb0HE3yXpacItqTM7XfF2f5q9NEGLEVl0dAaBAGfNwDCjH120y25F6Tg==} - engines: {node: '>= 10.0.0'} - '@parcel/watcher@2.5.1': resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} engines: {node: '>= 10.0.0'} @@ -2318,8 +2254,8 @@ packages: '@plasmohq/parcel-config@0.42.0': resolution: {integrity: sha512-GHtipmFGA84UsBVLO4v9qrc14XD3iKQA1PfHKiUW/xvGL2+gFzV8+WOvOnTslsh+VpOfJdVQQ5nWqVIH9yRiXg==} - '@plasmohq/parcel-core@0.1.10': - resolution: {integrity: sha512-XbJrqlgPNo+uQaukWayfRDZnAvdkYrmcydCOz0wfmuksTjDisyGkL3ZbWeX86QPN65CXFyou11/9h3+U9IsHfA==} + '@plasmohq/parcel-core@0.1.11': + resolution: {integrity: sha512-Jy/6xHSewP8CGUgBLONI2H02LKGhltySp31E0NbRP7qJ+AX58AMd7SKE8xsVB1pTgJ/bRLl9HXw8/929UDLrew==} engines: {parcel: '>= 2.7.0'} '@plasmohq/parcel-namer-manifest@0.3.12': @@ -3663,9 +3599,6 @@ packages: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} - abortcontroller-polyfill@1.7.5: - resolution: {integrity: sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==} - abortcontroller-polyfill@1.7.8: resolution: {integrity: sha512-9f1iZ2uWh92VcrU9Y8x+LdM4DLj75VE0MJB8zuF1iUnroEptStw+DQ8EQPMUdfe5k+PkB1uUfDQfWbhstH8LrQ==} @@ -3889,8 +3822,8 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - chalk@5.3.0: - resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + chalk@5.4.1: + resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} change-case-all@1.0.14: @@ -3902,8 +3835,8 @@ packages: change-case@4.1.2: resolution: {integrity: sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==} - change-case@5.1.2: - resolution: {integrity: sha512-CAtbGEDulyjzs05RXy3uKcwqeztz/dMEuAc1Xu9NQBsbrhuGMneL0u9Dj5SoutLKBFYun8txxYIwhjtLNfUmCA==} + change-case@5.4.4: + resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==} chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} @@ -4246,10 +4179,6 @@ packages: dotenv-expand@5.1.0: resolution: {integrity: sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==} - dotenv@16.3.1: - resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} - engines: {node: '>=12'} - dotenv@16.4.7: resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} engines: {node: '>=12'} @@ -4362,6 +4291,10 @@ packages: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} @@ -4381,9 +4314,6 @@ packages: resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} engines: {node: ^12.20 || >= 14.13} - fflate@0.8.1: - resolution: {integrity: sha512-/exOvEuc+/iaUm105QIiOt4LpBdMTWsXxqR0HDF35vx3fmaKzw7354gTilCh5rkzEt8WYyG//ku3h3nRmd7CHQ==} - fflate@0.8.2: resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} @@ -4448,8 +4378,8 @@ packages: resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} engines: {node: '>=6'} - get-port@7.0.0: - resolution: {integrity: sha512-mDHFgApoQd+azgMdwylJrv2DX47ywGq1i5VFJE7fZ0dttNq3iQMfsU4IvEgBHojA3KqEudyu7Vq+oN8kNaNkWw==} + get-port@7.1.0: + resolution: {integrity: sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==} engines: {node: '>=16'} get-stream@6.0.1: @@ -4496,8 +4426,8 @@ packages: resolution: {integrity: sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==} engines: {node: '>=16'} - got@14.4.5: - resolution: {integrity: sha512-sq+uET8TnNKRNnjEOPJzMcxeI0irT8BBNmf+GtZcJpmhYsQM1DSKmCROUjPWKsXZ5HzwD5Cf5/RV+QD9BSTxJg==} + got@14.4.6: + resolution: {integrity: sha512-rnhwfM/PhMNJ1i17k3DuDqgj0cKx3IHxBKVv/WX1uDKqrhi2Gv3l7rhPThR/Cc6uU++dD97W9c8Y0qyw9x0jag==} engines: {node: '>=20'} graceful-fs@4.2.10: @@ -4681,8 +4611,8 @@ packages: ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - inquirer@12.4.1: - resolution: {integrity: sha512-/V7OyFkeUBFO2jAokUq5emSlcVMHVvzg8bwwZnzmCwErPgbeftsthmPUg71AIi5mR0YmiJOLQ+bTiHVWEjOw7A==} + inquirer@12.5.0: + resolution: {integrity: sha512-aiBBq5aKF1k87MTxXDylLfwpRwToShiHrSv4EmB07EYyLgmnjEz5B3rn0aGw1X3JA/64Ngf2T54oGwc+BCsPIQ==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -5267,8 +5197,8 @@ packages: node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - node-object-hash@3.0.0: - resolution: {integrity: sha512-jLF6tlyletktvSAawuPmH1SReP0YfZQ+tBrDiTCK+Ai7eXPMS9odi5xW/iKC7ZhrWJJ0Z5xYcW/x+1fVMn1Qvw==} + node-object-hash@3.1.1: + resolution: {integrity: sha512-A32kRGjXtwQ+uSa3GrXiCl8HVFY0Jy6IiKFO7UjagAKSaOOrruxB2Qf/w7TP5QtNfB3uOiHTu3cjhp8k/C0PCg==} engines: {node: '>=16', pnpm: '>=8'} node-releases@2.0.19: @@ -5493,8 +5423,8 @@ packages: pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - plasmo@0.90.3: - resolution: {integrity: sha512-m8OlsFZQRbce/CBfbhGr8UD5XrTJFvp8kGlSu/KYJpsJd19I8fLc4JW+Xxyo1ve3UJFgC88COCXKeecP1Z0EPQ==} + plasmo@0.90.5: + resolution: {integrity: sha512-VRFsRCHTKCDSRz7ZGmN4hCFqrHE8z7vDYqJK63v5gjRs+EUFdfEciQyGhPmG5NkT+yPvmMZO+R/j1HU/pg2BKA==} hasBin: true pony-cause@2.1.11: @@ -8299,14 +8229,14 @@ snapshots: transitivePeerDependencies: - '@parcel/core' - '@parcel/config-default@2.9.3(@parcel/core@2.9.3)(@swc/helpers@0.5.15)(postcss@8.4.31)(typescript@5.2.2)': + '@parcel/config-default@2.9.3(@parcel/core@2.9.3)(@swc/helpers@0.5.15)(postcss@8.4.31)(typescript@5.8.2)': dependencies: '@parcel/bundler-default': 2.9.3(@parcel/core@2.9.3) '@parcel/compressor-raw': 2.9.3(@parcel/core@2.9.3) '@parcel/core': 2.9.3 '@parcel/namer-default': 2.9.3(@parcel/core@2.9.3) '@parcel/optimizer-css': 2.9.3(@parcel/core@2.9.3) - '@parcel/optimizer-htmlnano': 2.9.3(@parcel/core@2.9.3)(postcss@8.4.31)(typescript@5.2.2) + '@parcel/optimizer-htmlnano': 2.9.3(@parcel/core@2.9.3)(postcss@8.4.31)(typescript@5.8.2) '@parcel/optimizer-image': 2.9.3(@parcel/core@2.9.3) '@parcel/optimizer-svgo': 2.9.3(@parcel/core@2.9.3) '@parcel/optimizer-swc': 2.9.3(@parcel/core@2.9.3)(@swc/helpers@0.5.15) @@ -8369,7 +8299,7 @@ snapshots: json5: 2.2.3 msgpackr: 1.11.2 nullthrows: 1.1.1 - semver: 7.5.4 + semver: 7.7.1 '@parcel/diagnostic@2.8.3': dependencies: @@ -8455,7 +8385,7 @@ snapshots: '@parcel/fs': 2.9.3(@parcel/core@2.9.3) '@parcel/utils': 2.9.3 nullthrows: 1.1.1 - semver: 7.5.4 + semver: 7.7.1 transitivePeerDependencies: - '@parcel/core' @@ -8480,10 +8410,10 @@ snapshots: transitivePeerDependencies: - '@parcel/core' - '@parcel/optimizer-htmlnano@2.9.3(@parcel/core@2.9.3)(postcss@8.4.31)(typescript@5.2.2)': + '@parcel/optimizer-htmlnano@2.9.3(@parcel/core@2.9.3)(postcss@8.4.31)(typescript@5.8.2)': dependencies: '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) - htmlnano: 2.1.1(postcss@8.4.31)(svgo@2.8.0)(typescript@5.2.2) + htmlnano: 2.1.1(postcss@8.4.31)(svgo@2.8.0)(typescript@5.8.2) nullthrows: 1.1.1 posthtml: 0.16.6 svgo: 2.8.0 @@ -8548,7 +8478,7 @@ snapshots: '@parcel/types': 2.9.3(@parcel/core@2.9.3) '@parcel/utils': 2.9.3 '@parcel/workers': 2.9.3(@parcel/core@2.9.3) - semver: 7.5.4 + semver: 7.7.1 '@parcel/packager-css@2.9.3(@parcel/core@2.9.3)': dependencies: @@ -8689,7 +8619,7 @@ snapshots: browserslist: 4.24.4 json5: 2.2.3 nullthrows: 1.1.1 - semver: 7.5.4 + semver: 7.7.1 transitivePeerDependencies: - '@parcel/core' @@ -8722,7 +8652,7 @@ snapshots: posthtml: 0.16.6 posthtml-parser: 0.10.2 posthtml-render: 3.0.0 - semver: 7.5.4 + semver: 7.7.1 srcset: 4.0.0 transitivePeerDependencies: - '@parcel/core' @@ -8753,7 +8683,7 @@ snapshots: browserslist: 4.24.4 nullthrows: 1.1.1 regenerator-runtime: 0.13.11 - semver: 7.5.4 + semver: 7.7.1 '@parcel/transformer-json@2.9.3(@parcel/core@2.9.3)': dependencies: @@ -8779,7 +8709,7 @@ snapshots: clone: 2.1.2 nullthrows: 1.1.1 postcss-value-parser: 4.2.0 - semver: 7.5.4 + semver: 7.7.1 transitivePeerDependencies: - '@parcel/core' @@ -8791,7 +8721,7 @@ snapshots: posthtml: 0.16.6 posthtml-parser: 0.10.2 posthtml-render: 3.0.0 - semver: 7.5.4 + semver: 7.7.1 transitivePeerDependencies: - '@parcel/core' @@ -8836,7 +8766,7 @@ snapshots: posthtml: 0.16.6 posthtml-parser: 0.10.2 posthtml-render: 3.0.0 - semver: 7.5.4 + semver: 7.7.1 transitivePeerDependencies: - '@parcel/core' @@ -8891,93 +8821,45 @@ snapshots: chalk: 4.1.2 nullthrows: 1.1.1 - '@parcel/watcher-android-arm64@2.2.0': - optional: true - '@parcel/watcher-android-arm64@2.5.1': optional: true - '@parcel/watcher-darwin-arm64@2.2.0': - optional: true - '@parcel/watcher-darwin-arm64@2.5.1': optional: true - '@parcel/watcher-darwin-x64@2.2.0': - optional: true - '@parcel/watcher-darwin-x64@2.5.1': optional: true '@parcel/watcher-freebsd-x64@2.5.1': optional: true - '@parcel/watcher-linux-arm-glibc@2.2.0': - optional: true - '@parcel/watcher-linux-arm-glibc@2.5.1': optional: true '@parcel/watcher-linux-arm-musl@2.5.1': optional: true - '@parcel/watcher-linux-arm64-glibc@2.2.0': - optional: true - '@parcel/watcher-linux-arm64-glibc@2.5.1': optional: true - '@parcel/watcher-linux-arm64-musl@2.2.0': - optional: true - '@parcel/watcher-linux-arm64-musl@2.5.1': optional: true - '@parcel/watcher-linux-x64-glibc@2.2.0': - optional: true - '@parcel/watcher-linux-x64-glibc@2.5.1': optional: true - '@parcel/watcher-linux-x64-musl@2.2.0': - optional: true - '@parcel/watcher-linux-x64-musl@2.5.1': optional: true - '@parcel/watcher-win32-arm64@2.2.0': - optional: true - '@parcel/watcher-win32-arm64@2.5.1': optional: true '@parcel/watcher-win32-ia32@2.5.1': optional: true - '@parcel/watcher-win32-x64@2.2.0': - optional: true - '@parcel/watcher-win32-x64@2.5.1': optional: true - '@parcel/watcher@2.2.0': - dependencies: - detect-libc: 1.0.3 - is-glob: 4.0.3 - micromatch: 4.0.8 - node-addon-api: 7.1.1 - optionalDependencies: - '@parcel/watcher-android-arm64': 2.2.0 - '@parcel/watcher-darwin-arm64': 2.2.0 - '@parcel/watcher-darwin-x64': 2.2.0 - '@parcel/watcher-linux-arm-glibc': 2.2.0 - '@parcel/watcher-linux-arm64-glibc': 2.2.0 - '@parcel/watcher-linux-arm64-musl': 2.2.0 - '@parcel/watcher-linux-x64-glibc': 2.2.0 - '@parcel/watcher-linux-x64-musl': 2.2.0 - '@parcel/watcher-win32-arm64': 2.2.0 - '@parcel/watcher-win32-x64': 2.2.0 - '@parcel/watcher@2.5.1': dependencies: detect-libc: 1.0.3 @@ -9048,10 +8930,10 @@ snapshots: transitivePeerDependencies: - '@parcel/core' - '@plasmohq/parcel-config@0.42.0(@swc/core@1.11.11(@swc/helpers@0.5.15))(@swc/helpers@0.5.15)(lodash@4.17.21)(postcss@8.4.31)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.2.2)': + '@plasmohq/parcel-config@0.42.0(@swc/core@1.11.11(@swc/helpers@0.5.15))(@swc/helpers@0.5.15)(lodash@4.17.21)(postcss@8.4.31)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.2)': dependencies: '@parcel/compressor-raw': 2.9.3(@parcel/core@2.9.3) - '@parcel/config-default': 2.9.3(@parcel/core@2.9.3)(@swc/helpers@0.5.15)(postcss@8.4.31)(typescript@5.2.2) + '@parcel/config-default': 2.9.3(@parcel/core@2.9.3)(@swc/helpers@0.5.15)(postcss@8.4.31)(typescript@5.8.2) '@parcel/core': 2.9.3 '@parcel/optimizer-data-url': 2.9.3(@parcel/core@2.9.3) '@parcel/reporter-bundle-buddy': 2.9.3(@parcel/core@2.9.3) @@ -9145,7 +9027,7 @@ snapshots: - walrus - whiskers - '@plasmohq/parcel-core@0.1.10': + '@plasmohq/parcel-core@0.1.11': dependencies: '@parcel/cache': 2.9.3(@parcel/core@2.9.3) '@parcel/core': 2.9.3 @@ -9160,9 +9042,9 @@ snapshots: '@parcel/source-map': 2.1.1 '@parcel/types': 2.9.3(@parcel/core@2.9.3) '@parcel/utils': 2.9.3 - '@parcel/watcher': 2.2.0 + '@parcel/watcher': 2.5.1 '@parcel/workers': 2.9.3(@parcel/core@2.9.3) - abortcontroller-polyfill: 1.7.5 + abortcontroller-polyfill: 1.7.8 nullthrows: 1.1.1 '@plasmohq/parcel-namer-manifest@0.3.12': @@ -10580,8 +10462,6 @@ snapshots: dependencies: event-target-shim: 5.0.1 - abortcontroller-polyfill@1.7.5: {} - abortcontroller-polyfill@1.7.8: {} acorn-walk@8.3.4: @@ -10840,7 +10720,7 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 - chalk@5.3.0: {} + chalk@5.4.1: {} change-case-all@1.0.14: dependencies: @@ -10883,7 +10763,7 @@ snapshots: snake-case: 3.0.4 tslib: 2.8.1 - change-case@5.1.2: {} + change-case@5.4.4: {} chardet@0.7.0: {} @@ -11046,14 +10926,14 @@ snapshots: optionalDependencies: typescript: 5.8.2 - cosmiconfig@9.0.0(typescript@5.2.2): + cosmiconfig@9.0.0(typescript@5.8.2): dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 js-yaml: 4.1.0 parse-json: 5.2.0 optionalDependencies: - typescript: 5.2.2 + typescript: 5.8.2 crc-32@1.2.2: {} @@ -11229,8 +11109,6 @@ snapshots: dotenv-expand@5.1.0: {} - dotenv@16.3.1: {} - dotenv@16.4.7: {} dotenv@7.0.0: {} @@ -11406,6 +11284,14 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + fast-safe-stringify@2.1.1: {} fastq@1.19.1: @@ -11435,8 +11321,6 @@ snapshots: node-domexception: 1.0.0 web-streams-polyfill: 3.3.3 - fflate@0.8.1: {} - fflate@0.8.2: {} figures@3.2.0: @@ -11488,7 +11372,7 @@ snapshots: get-nonce@1.0.1: {} - get-port@7.0.0: {} + get-port@7.1.0: {} get-stream@6.0.1: {} @@ -11554,7 +11438,7 @@ snapshots: p-cancelable: 3.0.0 responselike: 3.0.0 - got@14.4.5: + got@14.4.6: dependencies: '@sindresorhus/is': 7.0.1 '@szmarczak/http-timer': 5.0.1 @@ -11641,9 +11525,9 @@ snapshots: dependencies: react-is: 16.13.1 - htmlnano@2.1.1(postcss@8.4.31)(svgo@2.8.0)(typescript@5.2.2): + htmlnano@2.1.1(postcss@8.4.31)(svgo@2.8.0)(typescript@5.8.2): dependencies: - cosmiconfig: 9.0.0(typescript@5.2.2) + cosmiconfig: 9.0.0(typescript@5.8.2) posthtml: 0.16.6 timsort: 0.3.0 optionalDependencies: @@ -11724,7 +11608,7 @@ snapshots: ini@1.3.8: {} - inquirer@12.4.1(@types/node@20.11.5): + inquirer@12.5.0(@types/node@20.11.5): dependencies: '@inquirer/core': 10.1.9(@types/node@20.11.5) '@inquirer/prompts': 7.4.0(@types/node@20.11.5) @@ -12268,7 +12152,7 @@ snapshots: node-int64@0.4.0: {} - node-object-hash@3.0.0: {} + node-object-hash@3.1.1: {} node-releases@2.0.19: {} @@ -12488,38 +12372,38 @@ snapshots: mlly: 1.7.4 pathe: 2.0.3 - plasmo@0.90.3(@swc/core@1.11.11(@swc/helpers@0.5.15))(@swc/helpers@0.5.15)(@types/node@20.11.5)(lodash@4.17.21)(postcss@8.4.31)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + plasmo@0.90.5(@swc/core@1.11.11(@swc/helpers@0.5.15))(@swc/helpers@0.5.15)(@types/node@20.11.5)(lodash@4.17.21)(postcss@8.4.31)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: '@expo/spawn-async': 1.7.2 '@parcel/core': 2.9.3 '@parcel/fs': 2.9.3(@parcel/core@2.9.3) '@parcel/package-manager': 2.9.3(@parcel/core@2.9.3) - '@parcel/watcher': 2.2.0 + '@parcel/watcher': 2.5.1 '@plasmohq/init': 0.7.0 - '@plasmohq/parcel-config': 0.42.0(@swc/core@1.11.11(@swc/helpers@0.5.15))(@swc/helpers@0.5.15)(lodash@4.17.21)(postcss@8.4.31)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.2.2) - '@plasmohq/parcel-core': 0.1.10 + '@plasmohq/parcel-config': 0.42.0(@swc/core@1.11.11(@swc/helpers@0.5.15))(@swc/helpers@0.5.15)(lodash@4.17.21)(postcss@8.4.31)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.8.2) + '@plasmohq/parcel-core': 0.1.11 buffer: 6.0.3 - chalk: 5.3.0 - change-case: 5.1.2 - dotenv: 16.3.1 + chalk: 5.4.1 + change-case: 5.4.4 + dotenv: 16.4.7 dotenv-expand: 12.0.1 events: 3.3.0 - fast-glob: 3.3.2 - fflate: 0.8.1 - get-port: 7.0.0 - got: 14.4.5 + fast-glob: 3.3.3 + fflate: 0.8.2 + get-port: 7.1.0 + got: 14.4.6 ignore: 7.0.3 - inquirer: 12.4.1(@types/node@20.11.5) + inquirer: 12.5.0(@types/node@20.11.5) is-path-inside: 4.0.0 json5: 2.2.3 mnemonic-id: 3.2.7 - node-object-hash: 3.0.0 + node-object-hash: 3.1.1 package-json: 10.0.1 process: 0.11.10 - semver: 7.5.4 + semver: 7.7.1 sharp: 0.33.5 tempy: 3.1.0 - typescript: 5.2.2 + typescript: 5.8.2 transitivePeerDependencies: - '@swc/core' - '@swc/helpers' diff --git a/src/components/FloatingStatusBadge.tsx b/src/components/FloatingStatusBadge.tsx new file mode 100644 index 00000000..e03fe24c --- /dev/null +++ b/src/components/FloatingStatusBadge.tsx @@ -0,0 +1,70 @@ +import { useEffect, useState } from "react" +import type { Status } from "~src/hooks/useClaimDetection" + +const FloatingStatusBadge = ({ status }: { status: Status }) => { + const [visible, setVisible] = useState(true) + + useEffect(() => { + if (status === "loading") { + setVisible(true) + return + } + + setVisible(true) + const timeout = setTimeout(() => setVisible(false), 6000) + return () => clearTimeout(timeout) + }, [status]) + + if (!visible) return null + + const isLoading = status === "loading" + const color = + status === "found" + ? "#22c55e" + : status === "not_found" + ? "#ef4444" + : "#3b82f6" + + return ( + + {isLoading && ( + + )} + + + ) +} + +export default FloatingStatusBadge diff --git a/src/components/WalletConnectionButton.tsx b/src/components/WalletConnectionButton.tsx index 9f953489..47b1df8f 100644 --- a/src/components/WalletConnectionButton.tsx +++ b/src/components/WalletConnectionButton.tsx @@ -7,10 +7,12 @@ import { PowerOff } from 'lucide-react'; const WalletConnectionButton = () => { const [account, setAccount] = useStorage("metamask-account") + const handleConnect = async () => { try { const accountAddress = await connectWallet() setAccount(accountAddress) + chrome.storage.local.set({ "metamask-account": accountAddress }) } catch (error) { console.error("Failed to connect to wallet: ", error) } diff --git a/src/contents/plasmo-inline.tsx b/src/contents/plasmo-inline.tsx index 63b466c2..62f685d8 100644 --- a/src/contents/plasmo-inline.tsx +++ b/src/contents/plasmo-inline.tsx @@ -1,6 +1,16 @@ import type { PlasmoCSConfig, PlasmoGetInlineAnchor } from "plasmo" import { useEffect, useRef, useState } from "react" +import { + ApolloProvider, + gql, + useSubscription +} from "@apollo/client" +import { QueryClient, QueryClientProvider } from "@tanstack/react-query" +import { apolloSubscriptionClient } from "~src/graphql/src/apollo-subscription-client" +import { useGetFollowingsFromAddressQuery } from "~src/graphql/src" +import { useClaimDetection } from "~src/hooks/useClaimDetection" import IntuitionSearchIcon from "~src/components/icons/IntuitionSearchBar" +import FloatingStatusBadge from "~src/components/FloatingStatusBadge" export const config: PlasmoCSConfig = { matches: ["https://*/*"] @@ -9,12 +19,57 @@ export const config: PlasmoCSConfig = { export const getInlineAnchor: PlasmoGetInlineAnchor = () => document.querySelector("body") -export const getShadowHostId = () => "plasmo-inline-example-unique-id" +export const getShadowHostId = () => "plasmo-floating-button" -function PlasmoInline() { - const [positionY, setPositionY] = useState(50) +const EVENTS_SUBSCRIPTION = gql` + subscription Events($limit: Int!) { + events( + where: { deposit: { is_atom_wallet: { _eq: false } } } + order_by: [{ block_number: desc }] + limit: $limit + ) { + type + deposit { + sender { + id + } + } + } + } +` + +const FloatingButton = ({ address }: { address: string }) => { + const [positionY, setPositionY] = useState(50) + const [hasNotification, setHasNotification] = useState(false) const draggingRef = useRef(false) + const { data: followData } = useGetFollowingsFromAddressQuery({ + address: address?.toLowerCase() || "" + }) + + const { data: eventData } = useSubscription(EVENTS_SUBSCRIPTION, { + variables: { limit: 1 } + }) + + const { status } = useClaimDetection(window.location.href, address) + + const followingIds = + followData?.following?.map((f) => f.id).filter(Boolean) ?? [] + + useEffect(() => { + const latestEvent = eventData?.events?.[0] + const actorId = latestEvent?.deposit?.sender?.id + const eventType = latestEvent?.type + + if ( + actorId && + followingIds.includes(actorId) && + ["ClaimCreated", "AtomCreated", "TripleCreated"].includes(eventType) + ) { + setHasNotification(true) + } + }, [eventData, followingIds]) + const handleMouseDown = (e: React.MouseEvent) => { const startY = e.clientY const startPositionY = positionY @@ -22,10 +77,7 @@ function PlasmoInline() { const handleMouseMove = (moveEvent: MouseEvent) => { const deltaY = moveEvent.clientY - startY - if (Math.abs(deltaY) > 5) { - draggingRef.current = true - } - + if (Math.abs(deltaY) > 5) draggingRef.current = true if (draggingRef.current) { const newY = startPositionY + (deltaY / window.innerHeight) * 100 setPositionY(Math.min(90, Math.max(0, newY))) @@ -35,9 +87,9 @@ function PlasmoInline() { const handleMouseUp = () => { window.removeEventListener("mousemove", handleMouseMove) window.removeEventListener("mouseup", handleMouseUp) - if (!draggingRef.current) { - handleSidePanel() + setHasNotification(false) + chrome.runtime.sendMessage({ type: "open_sidepanel" }) } } @@ -45,44 +97,98 @@ function PlasmoInline() { window.addEventListener("mouseup", handleMouseUp) } - const handleSidePanel = () => { - chrome.runtime.sendMessage({ type: "open_sidepanel" }) - } - return ( -
-
{ - e.currentTarget.style.opacity = "1" - }} - onMouseLeave={(e) => { - e.currentTarget.style.opacity = "0.2" - }} - > +
(e.currentTarget.style.opacity = "1")} + onMouseLeave={(e) => (e.currentTarget.style.opacity = "0.4")} + > +
{}} size={35} position={{ x: 0, y: 0 }} className="hover:opacity-80 transition-opacity" /> + + {hasNotification && ( + + + + + )}
) } -export default PlasmoInline +const queryClient = new QueryClient() + +const Wrapper = () => { + const [address, setAddress] = useState("") + + useEffect(() => { + chrome.storage.local.get("metamask-account", (res) => { + const addr = res["metamask-account"] + if (addr) { + console.log("✅ Metamask account loaded:", addr) + setAddress(addr) + } + }) + }, []) + + console.log("🧪 Rendering Wrapper with address:", address) + + return ( + + + + + + ) +} + +export default Wrapper diff --git a/src/graphql/src/apollo-subscription-client.ts b/src/graphql/src/apollo-subscription-client.ts new file mode 100644 index 00000000..4e30d9e5 --- /dev/null +++ b/src/graphql/src/apollo-subscription-client.ts @@ -0,0 +1,62 @@ +import { ApolloClient, InMemoryCache, split } from "@apollo/client" +import { GraphQLWsLink } from "@apollo/client/link/subscriptions" +import { createClient } from "graphql-ws" +import { getMainDefinition } from "@apollo/client/utilities" +import { HttpLink } from "@apollo/client" + + +const ENV = "dev" // "local" | "dev" | "prod" + +const ENDPOINTS = { + local: { + http: "http://localhost:8080/v1/graphql", + ws: "ws://localhost:8080/v1/graphql" + }, + dev: { + http: "https://prod.base-sepolia.intuition-api.com/v1/graphql", + ws: "wss://prod.base-sepolia.intuition-api.com/v1/graphql" + }, + prod: { + http: "https://prod.base.intuition-api.com/v1/graphql", + ws: "wss://prod.base.intuition-api.com/v1/graphql" + } +} + +const { http, ws } = ENDPOINTS[ENV] + +const httpLink = new HttpLink({ + uri: http, + headers: { + "Content-Type": "application/json" + + } +}) + +const wsLink = new GraphQLWsLink( + createClient({ + url: ws, + connectionParams: { + headers: { + + } + } + }) +) + + +const splitLink = split( + ({ query }) => { + const definition = getMainDefinition(query) + return ( + definition.kind === "OperationDefinition" && + definition.operation === "subscription" + ) + }, + wsLink, + httpLink +) + +export const apolloSubscriptionClient = new ApolloClient({ + link: splitLink, + cache: new InMemoryCache() +}) diff --git a/src/graphql/src/generated/index.ts b/src/graphql/src/generated/index.ts index 75357c18..18cde6c7 100644 --- a/src/graphql/src/generated/index.ts +++ b/src/graphql/src/generated/index.ts @@ -11480,6 +11480,18 @@ export type GetFollowersFromAddressQuery = { }> } +export type GetFollowingIdsQueryVariables = Exact<{ + address: Scalars["String"]["input"] +}> + +export type GetFollowingIdsQuery = { + __typename?: "query_root" + triples: Array<{ + __typename?: "triples" + object: { __typename?: "atoms"; id: any } + }> +} + export type GetFollowingsFromAddressQueryVariables = Exact<{ address: Scalars["String"]["input"] }> @@ -13925,6 +13937,15 @@ export type EventsSubscription = { }> } +export type FollowerActivitySubscriptionVariables = Exact<{ + limit: Scalars["Int"]["input"] +}> + +export type FollowerActivitySubscription = { + __typename?: "subscription_root" + events: Array<{ __typename?: "events"; type: any; block_timestamp: any }> +} + export const AccountClaimsAggregateFragmentDoc = ` fragment AccountClaimsAggregate on accounts { claims_aggregate(order_by: {shares: desc}) { @@ -15823,6 +15844,93 @@ useGetFollowersFromAddressQuery.fetcher = ( options ) +export const GetFollowingIdsDocument = ` + query getFollowingIds($address: String!) { + triples( + where: {predicate: {label: {_eq: "follow"}}, subject: {accounts: {id: {_eq: $address}}}} + ) { + object { + id + } + } +} + ` + +export const useGetFollowingIdsQuery = < + TData = GetFollowingIdsQuery, + TError = unknown +>( + variables: GetFollowingIdsQueryVariables, + options?: Omit< + UseQueryOptions, + "queryKey" + > & { + queryKey?: UseQueryOptions["queryKey"] + } +) => { + return useQuery({ + queryKey: ["getFollowingIds", variables], + queryFn: fetcher( + GetFollowingIdsDocument, + variables + ), + ...options + }) +} + +useGetFollowingIdsQuery.document = GetFollowingIdsDocument + +useGetFollowingIdsQuery.getKey = (variables: GetFollowingIdsQueryVariables) => [ + "getFollowingIds", + variables +] + +export const useInfiniteGetFollowingIdsQuery = < + TData = InfiniteData, + TError = unknown +>( + variables: GetFollowingIdsQueryVariables, + options: Omit< + UseInfiniteQueryOptions, + "queryKey" + > & { + queryKey?: UseInfiniteQueryOptions< + GetFollowingIdsQuery, + TError, + TData + >["queryKey"] + } +) => { + return useInfiniteQuery( + (() => { + const { queryKey: optionsQueryKey, ...restOptions } = options + return { + queryKey: optionsQueryKey ?? ["getFollowingIds.infinite", variables], + queryFn: (metaData) => + fetcher( + GetFollowingIdsDocument, + { ...variables, ...(metaData.pageParam ?? {}) } + )(), + ...restOptions + } + })() + ) +} + +useInfiniteGetFollowingIdsQuery.getKey = ( + variables: GetFollowingIdsQueryVariables +) => ["getFollowingIds.infinite", variables] + +useGetFollowingIdsQuery.fetcher = ( + variables: GetFollowingIdsQueryVariables, + options?: RequestInit["headers"] +) => + fetcher( + GetFollowingIdsDocument, + variables, + options + ) + export const GetFollowingsFromAddressDocument = ` query getFollowingsFromAddress($address: String!) { following(args: {address: $address}) { @@ -18627,6 +18735,18 @@ ${VaultDetailsWithFilteredPositionsFragmentDoc} ${VaultBasicDetailsFragmentDoc} ${VaultFilteredPositionsFragmentDoc} ${PositionFieldsFragmentDoc}` +export const FollowerActivityDocument = ` + subscription FollowerActivity($limit: Int!) { + events( + where: {type: {_in: ["ClaimCreated", "AtomCreated"]}} + order_by: [{block_number: desc}] + limit: $limit + ) { + type + block_timestamp + } +} + ` export const AccountClaimsAggregate = { kind: "Document", definitions: [ @@ -27609,6 +27729,129 @@ export const GetFollowersFromAddress = { } ] } as unknown as DocumentNode +export const GetFollowingIds = { + kind: "Document", + definitions: [ + { + kind: "OperationDefinition", + operation: "query", + name: { kind: "Name", value: "getFollowingIds" }, + variableDefinitions: [ + { + kind: "VariableDefinition", + variable: { + kind: "Variable", + name: { kind: "Name", value: "address" } + }, + type: { + kind: "NonNullType", + type: { kind: "NamedType", name: { kind: "Name", value: "String" } } + } + } + ], + selectionSet: { + kind: "SelectionSet", + selections: [ + { + kind: "Field", + name: { kind: "Name", value: "triples" }, + arguments: [ + { + kind: "Argument", + name: { kind: "Name", value: "where" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "predicate" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "label" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "_eq" }, + value: { + kind: "StringValue", + value: "follow", + block: false + } + } + ] + } + } + ] + } + }, + { + kind: "ObjectField", + name: { kind: "Name", value: "subject" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "accounts" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "id" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "_eq" }, + value: { + kind: "Variable", + name: { + kind: "Name", + value: "address" + } + } + } + ] + } + } + ] + } + } + ] + } + } + ] + } + } + ], + selectionSet: { + kind: "SelectionSet", + selections: [ + { + kind: "Field", + name: { kind: "Name", value: "object" }, + selectionSet: { + kind: "SelectionSet", + selections: [ + { kind: "Field", name: { kind: "Name", value: "id" } } + ] + } + } + ] + } + } + ] + } + } + ] +} as unknown as DocumentNode export const GetFollowingsFromAddress = { kind: "Document", definitions: [ @@ -36603,3 +36846,111 @@ export const Events = { } ] } as unknown as DocumentNode +export const FollowerActivity = { + kind: "Document", + definitions: [ + { + kind: "OperationDefinition", + operation: "subscription", + name: { kind: "Name", value: "FollowerActivity" }, + variableDefinitions: [ + { + kind: "VariableDefinition", + variable: { + kind: "Variable", + name: { kind: "Name", value: "limit" } + }, + type: { + kind: "NonNullType", + type: { kind: "NamedType", name: { kind: "Name", value: "Int" } } + } + } + ], + selectionSet: { + kind: "SelectionSet", + selections: [ + { + kind: "Field", + name: { kind: "Name", value: "events" }, + arguments: [ + { + kind: "Argument", + name: { kind: "Name", value: "where" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "type" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "_in" }, + value: { + kind: "ListValue", + values: [ + { + kind: "StringValue", + value: "ClaimCreated", + block: false + }, + { + kind: "StringValue", + value: "AtomCreated", + block: false + } + ] + } + } + ] + } + } + ] + } + }, + { + kind: "Argument", + name: { kind: "Name", value: "order_by" }, + value: { + kind: "ListValue", + values: [ + { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "block_number" }, + value: { kind: "EnumValue", value: "desc" } + } + ] + } + ] + } + }, + { + kind: "Argument", + name: { kind: "Name", value: "limit" }, + value: { + kind: "Variable", + name: { kind: "Name", value: "limit" } + } + } + ], + selectionSet: { + kind: "SelectionSet", + selections: [ + { kind: "Field", name: { kind: "Name", value: "type" } }, + { + kind: "Field", + name: { kind: "Name", value: "block_timestamp" } + } + ] + } + } + ] + } + } + ] +} as unknown as DocumentNode diff --git a/src/graphql/src/generated/subscriptions.ts b/src/graphql/src/generated/subscriptions.ts index 7893be46..0a42a069 100644 --- a/src/graphql/src/generated/subscriptions.ts +++ b/src/graphql/src/generated/subscriptions.ts @@ -11500,6 +11500,18 @@ export type GetFollowersFromAddressQuery = { }> } +export type GetFollowingIdsQueryVariables = Exact<{ + address: Scalars["String"]["input"] +}> + +export type GetFollowingIdsQuery = { + __typename?: "query_root" + triples: Array<{ + __typename?: "triples" + object: { __typename?: "atoms"; id: any } + }> +} + export type GetFollowingsFromAddressQueryVariables = Exact<{ address: Scalars["String"]["input"] }> @@ -13945,6 +13957,15 @@ export type EventsSubscription = { }> } +export type FollowerActivitySubscriptionVariables = Exact<{ + limit: Scalars["Int"]["input"] +}> + +export type FollowerActivitySubscription = { + __typename?: "subscription_root" + events: Array<{ __typename?: "events"; type: any; block_timestamp: any }> +} + export const AccountClaimsAggregateFragmentDoc = { kind: "Document", definitions: [ @@ -23457,6 +23478,204 @@ export type GetFollowersFromAddressQueryResult = Apollo.QueryResult< GetFollowersFromAddressQuery, GetFollowersFromAddressQueryVariables > +export const GetFollowingIdsDocument = { + kind: "Document", + definitions: [ + { + kind: "OperationDefinition", + operation: "query", + name: { kind: "Name", value: "getFollowingIds" }, + variableDefinitions: [ + { + kind: "VariableDefinition", + variable: { + kind: "Variable", + name: { kind: "Name", value: "address" } + }, + type: { + kind: "NonNullType", + type: { kind: "NamedType", name: { kind: "Name", value: "String" } } + } + } + ], + selectionSet: { + kind: "SelectionSet", + selections: [ + { + kind: "Field", + name: { kind: "Name", value: "triples" }, + arguments: [ + { + kind: "Argument", + name: { kind: "Name", value: "where" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "predicate" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "label" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "_eq" }, + value: { + kind: "StringValue", + value: "follow", + block: false + } + } + ] + } + } + ] + } + }, + { + kind: "ObjectField", + name: { kind: "Name", value: "subject" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "accounts" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "id" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "_eq" }, + value: { + kind: "Variable", + name: { + kind: "Name", + value: "address" + } + } + } + ] + } + } + ] + } + } + ] + } + } + ] + } + } + ], + selectionSet: { + kind: "SelectionSet", + selections: [ + { + kind: "Field", + name: { kind: "Name", value: "object" }, + selectionSet: { + kind: "SelectionSet", + selections: [ + { kind: "Field", name: { kind: "Name", value: "id" } } + ] + } + } + ] + } + } + ] + } + } + ] +} as unknown as DocumentNode + +/** + * __useGetFollowingIdsQuery__ + * + * To run a query within a React component, call `useGetFollowingIdsQuery` and pass it any options that fit your needs. + * When your component renders, `useGetFollowingIdsQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useGetFollowingIdsQuery({ + * variables: { + * address: // value for 'address' + * }, + * }); + */ +export function useGetFollowingIdsQuery( + baseOptions: Apollo.QueryHookOptions< + GetFollowingIdsQuery, + GetFollowingIdsQueryVariables + > & + ( + | { variables: GetFollowingIdsQueryVariables; skip?: boolean } + | { skip: boolean } + ) +) { + const options = { ...defaultOptions, ...baseOptions } + return Apollo.useQuery( + GetFollowingIdsDocument, + options + ) +} +export function useGetFollowingIdsLazyQuery( + baseOptions?: Apollo.LazyQueryHookOptions< + GetFollowingIdsQuery, + GetFollowingIdsQueryVariables + > +) { + const options = { ...defaultOptions, ...baseOptions } + return Apollo.useLazyQuery< + GetFollowingIdsQuery, + GetFollowingIdsQueryVariables + >(GetFollowingIdsDocument, options) +} +export function useGetFollowingIdsSuspenseQuery( + baseOptions?: + | Apollo.SkipToken + | Apollo.SuspenseQueryHookOptions< + GetFollowingIdsQuery, + GetFollowingIdsQueryVariables + > +) { + const options = + baseOptions === Apollo.skipToken + ? baseOptions + : { ...defaultOptions, ...baseOptions } + return Apollo.useSuspenseQuery< + GetFollowingIdsQuery, + GetFollowingIdsQueryVariables + >(GetFollowingIdsDocument, options) +} +export type GetFollowingIdsQueryHookResult = ReturnType< + typeof useGetFollowingIdsQuery +> +export type GetFollowingIdsLazyQueryHookResult = ReturnType< + typeof useGetFollowingIdsLazyQuery +> +export type GetFollowingIdsSuspenseQueryHookResult = ReturnType< + typeof useGetFollowingIdsSuspenseQuery +> +export type GetFollowingIdsQueryResult = Apollo.QueryResult< + GetFollowingIdsQuery, + GetFollowingIdsQueryVariables +> export const GetFollowingsFromAddressDocument = { kind: "Document", definitions: [ @@ -33994,3 +34213,149 @@ export type EventsSubscriptionHookResult = ReturnType< > export type EventsSubscriptionResult = Apollo.SubscriptionResult +export const FollowerActivityDocument = { + kind: "Document", + definitions: [ + { + kind: "OperationDefinition", + operation: "subscription", + name: { kind: "Name", value: "FollowerActivity" }, + variableDefinitions: [ + { + kind: "VariableDefinition", + variable: { + kind: "Variable", + name: { kind: "Name", value: "limit" } + }, + type: { + kind: "NonNullType", + type: { kind: "NamedType", name: { kind: "Name", value: "Int" } } + } + } + ], + selectionSet: { + kind: "SelectionSet", + selections: [ + { + kind: "Field", + name: { kind: "Name", value: "events" }, + arguments: [ + { + kind: "Argument", + name: { kind: "Name", value: "where" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "type" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "_in" }, + value: { + kind: "ListValue", + values: [ + { + kind: "StringValue", + value: "ClaimCreated", + block: false + }, + { + kind: "StringValue", + value: "AtomCreated", + block: false + } + ] + } + } + ] + } + } + ] + } + }, + { + kind: "Argument", + name: { kind: "Name", value: "order_by" }, + value: { + kind: "ListValue", + values: [ + { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "block_number" }, + value: { kind: "EnumValue", value: "desc" } + } + ] + } + ] + } + }, + { + kind: "Argument", + name: { kind: "Name", value: "limit" }, + value: { + kind: "Variable", + name: { kind: "Name", value: "limit" } + } + } + ], + selectionSet: { + kind: "SelectionSet", + selections: [ + { kind: "Field", name: { kind: "Name", value: "type" } }, + { + kind: "Field", + name: { kind: "Name", value: "block_timestamp" } + } + ] + } + } + ] + } + } + ] +} as unknown as DocumentNode + +/** + * __useFollowerActivitySubscription__ + * + * To run a query within a React component, call `useFollowerActivitySubscription` and pass it any options that fit your needs. + * When your component renders, `useFollowerActivitySubscription` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the subscription, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useFollowerActivitySubscription({ + * variables: { + * limit: // value for 'limit' + * }, + * }); + */ +export function useFollowerActivitySubscription( + baseOptions: Apollo.SubscriptionHookOptions< + FollowerActivitySubscription, + FollowerActivitySubscriptionVariables + > & + ( + | { variables: FollowerActivitySubscriptionVariables; skip?: boolean } + | { skip: boolean } + ) +) { + const options = { ...defaultOptions, ...baseOptions } + return Apollo.useSubscription< + FollowerActivitySubscription, + FollowerActivitySubscriptionVariables + >(FollowerActivityDocument, options) +} +export type FollowerActivitySubscriptionHookResult = ReturnType< + typeof useFollowerActivitySubscription +> +export type FollowerActivitySubscriptionResult = + Apollo.SubscriptionResult diff --git a/src/graphql/src/queries/following-ids.graphql b/src/graphql/src/queries/following-ids.graphql new file mode 100644 index 00000000..c81a585f --- /dev/null +++ b/src/graphql/src/queries/following-ids.graphql @@ -0,0 +1,12 @@ +query getFollowingIds($address: String!) { + triples( + where: { + predicate: { label: { _eq: "follow" } } + subject: { accounts: { id: { _eq: $address } } } + } + ) { + object { + id + } + } +} diff --git a/src/graphql/src/subscriptions/follower-activity.graphql b/src/graphql/src/subscriptions/follower-activity.graphql new file mode 100644 index 00000000..6318e607 --- /dev/null +++ b/src/graphql/src/subscriptions/follower-activity.graphql @@ -0,0 +1,11 @@ +subscription FollowerActivity($limit: Int!) { + events( + where: { type: { _in: ["ClaimCreated", "AtomCreated"] } } + order_by: [{ block_number: desc }] + limit: $limit + ) { + type + + block_timestamp + } +} diff --git a/src/hooks/useClaimDetection.ts b/src/hooks/useClaimDetection.ts new file mode 100644 index 00000000..f81e3079 --- /dev/null +++ b/src/hooks/useClaimDetection.ts @@ -0,0 +1,39 @@ +import { useEffect, useState } from "react" +import { useGetClaimsByUriQuery } from "~src/graphql/src" + +export type Status = "loading" | "found" | "not_found" + +export const useClaimDetection = ( + uri: string, + address?: string +): { status: Status } => { + const [status, setStatus] = useState("loading") + + const { data, isLoading } = useGetClaimsByUriQuery( + { uri, address }, + { enabled: Boolean(uri) && Boolean(address) } + ) + + useEffect(() => { + + + if (isLoading) { + setStatus("loading") + } else { + const atoms = data?.atoms ?? [] + + const foundClaim = atoms.some((atom) => { + const subjectCount = + atom?.as_subject_claims_aggregate?.aggregate?.count ?? 0 + const objectCount = + atom?.as_object_claims_aggregate?.aggregate?.count ?? 0 + return subjectCount > 0 || objectCount > 0 + }) + + + setStatus(foundClaim ? "found" : "not_found") + } + }, [isLoading, data, uri, address]) + + return { status } +} diff --git a/src/hooks/useEventNotification.ts b/src/hooks/useEventNotification.ts new file mode 100644 index 00000000..c7652ee3 --- /dev/null +++ b/src/hooks/useEventNotification.ts @@ -0,0 +1,25 @@ +import { useEffect, useState } from "react" +import { useSubscription } from "@apollo/client" +import { EventsDocument } from "~src/graphql/src/generated/subscriptions" + +export const useEventNotification = () => { + const [hasNotification, setHasNotification] = useState(false) + + const { data } = useSubscription(EventsDocument, { + variables: { + addresses: [], + limit: 1 + } + }) + + useEffect(() => { + const event = data?.events?.[0] + const type = event?.type?.toLowerCase?.() + if (type?.includes("claim") || type?.includes("atom")) { + + setHasNotification(true) + } + }, [data]) + + return { hasNotification, reset: () => setHasNotification(false) } +} diff --git a/src/pages/RecentActivity.tsx b/src/pages/RecentActivity.tsx index a402f51d..4657600b 100644 --- a/src/pages/RecentActivity.tsx +++ b/src/pages/RecentActivity.tsx @@ -38,7 +38,7 @@ const RecentActivity: React.FC = () => { } - if (error) return
Erreur : {error.message}
+ if (error) return
Error : {error.message}
if (loading || !data) { return (