Merge pull request #50 from MutinyWallet/receive-qol

Halfway good tag editor, other small receive improvements
This commit is contained in:
Paul Miller
2023-04-26 13:26:33 -05:00
committed by GitHub
12 changed files with 369 additions and 193 deletions

View File

@@ -9,7 +9,7 @@
},
"type": "module",
"devDependencies": {
"@types/node": "^18.16.0",
"@types/node": "^18.16.1",
"@typescript-eslint/eslint-plugin": "^5.59.1",
"@typescript-eslint/parser": "^5.59.1",
"autoprefixer": "^10.4.14",
@@ -21,9 +21,9 @@
"eslint-plugin-solid": "0.11.0",
"postcss": "^8.4.23",
"solid-start-node": "^0.2.26",
"tailwindcss": "^3.3.1",
"tailwindcss": "^3.3.2",
"typescript": "^4.9.5",
"vite": "^4.3.1",
"vite": "^4.3.3",
"vite-plugin-pwa": "^0.14.7",
"vite-plugin-wasm": "^3.2.2",
"workbox-window": "^6.5.4"
@@ -33,11 +33,12 @@
"@kobalte/tailwindcss": "^0.5.0",
"@modular-forms/solid": "^0.12.0",
"@motionone/solid": "^10.16.0",
"@mutinywallet/mutiny-wasm": "^0.2.6",
"@mutinywallet/mutiny-wasm": "^0.2.7",
"@mutinywallet/waila-wasm": "^0.1.5",
"@nostr-dev-kit/ndk": "^0.0.13",
"@solidjs/meta": "^0.28.4",
"@solidjs/router": "^0.8.2",
"@thisbeyond/solid-select": "^0.14.0",
"class-variance-authority": "^0.4.0",
"nostr-tools": "^1.10.1",
"qr-scanner": "^1.4.2",

180
pnpm-lock.yaml generated
View File

@@ -6,7 +6,7 @@ dependencies:
version: 0.8.2(solid-js@1.7.3)
'@kobalte/tailwindcss':
specifier: ^0.5.0
version: 0.5.0(tailwindcss@3.3.1)
version: 0.5.0(tailwindcss@3.3.2)
'@modular-forms/solid':
specifier: ^0.12.0
version: 0.12.0(solid-js@1.7.3)
@@ -14,8 +14,8 @@ dependencies:
specifier: ^10.16.0
version: 10.16.0(solid-js@1.7.3)
'@mutinywallet/mutiny-wasm':
specifier: ^0.2.6
version: 0.2.6
specifier: ^0.2.7
version: 0.2.7
'@mutinywallet/waila-wasm':
specifier: ^0.1.5
version: 0.1.5
@@ -28,6 +28,9 @@ dependencies:
'@solidjs/router':
specifier: ^0.8.2
version: 0.8.2(solid-js@1.7.3)
'@thisbeyond/solid-select':
specifier: ^0.14.0
version: 0.14.0(solid-js@1.7.3)
class-variance-authority:
specifier: ^0.4.0
version: 0.4.0(typescript@4.9.5)
@@ -45,15 +48,15 @@ dependencies:
version: 0.0.8(qr.js@0.0.0)(solid-js@1.7.3)
solid-start:
specifier: ^0.2.26
version: 0.2.26(@solidjs/meta@0.28.4)(@solidjs/router@0.8.2)(solid-js@1.7.3)(solid-start-node@0.2.26)(vite@4.3.1)
version: 0.2.26(@solidjs/meta@0.28.4)(@solidjs/router@0.8.2)(solid-js@1.7.3)(solid-start-node@0.2.26)(vite@4.3.3)
undici:
specifier: ^5.22.0
version: 5.22.0
devDependencies:
'@types/node':
specifier: ^18.16.0
version: 18.16.0
specifier: ^18.16.1
version: 18.16.1
'@typescript-eslint/eslint-plugin':
specifier: ^5.59.1
version: 5.59.1(@typescript-eslint/parser@5.59.1)(eslint@8.39.0)(typescript@4.9.5)
@@ -86,28 +89,32 @@ devDependencies:
version: 8.4.23
solid-start-node:
specifier: ^0.2.26
version: 0.2.26(solid-start@0.2.26)(undici@5.22.0)(vite@4.3.1)
version: 0.2.26(solid-start@0.2.26)(undici@5.22.0)(vite@4.3.3)
tailwindcss:
specifier: ^3.3.1
version: 3.3.1(postcss@8.4.23)
specifier: ^3.3.2
version: 3.3.2
typescript:
specifier: ^4.9.5
version: 4.9.5
vite:
specifier: ^4.3.1
version: 4.3.1(@types/node@18.16.0)
specifier: ^4.3.3
version: 4.3.3(@types/node@18.16.1)
vite-plugin-pwa:
specifier: ^0.14.7
version: 0.14.7(vite@4.3.1)(workbox-build@6.5.4)(workbox-window@6.5.4)
version: 0.14.7(vite@4.3.3)(workbox-build@6.5.4)(workbox-window@6.5.4)
vite-plugin-wasm:
specifier: ^3.2.2
version: 3.2.2(vite@4.3.1)
version: 3.2.2(vite@4.3.3)
workbox-window:
specifier: ^6.5.4
version: 6.5.4
packages:
/@alloc/quick-lru@5.2.0:
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
engines: {node: '>=10'}
/@ampproject/remapping@2.2.1:
resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==}
engines: {node: '>=6.0.0'}
@@ -1449,8 +1456,8 @@ packages:
resolution: {integrity: sha512-EvYTiXet5XqweYGClEmpu3BoxmsQ4hkj3QaYA6qEnigCWffTP3vNRwBReTdrwDwo7OoJ3wM8Uoe9Uk4n+d4hfg==}
dev: false
/@floating-ui/dom@1.2.6:
resolution: {integrity: sha512-02vxFDuvuVPs22iJICacezYJyf7zwwOCWkPNkWNBr1U0Qt1cKFYzWvxts0AmqcOQGwt/3KJWcWIgtbUU38keyw==}
/@floating-ui/dom@1.2.7:
resolution: {integrity: sha512-DyqylONj1ZaBnzj+uBnVfzdjjCkFCL2aA9ESHLyUOGSqb03RpbLMImP1ekIQXYs4KLk9jAjJfZAU8hXfWSahEg==}
dependencies:
'@floating-ui/core': 1.2.6
dev: false
@@ -1537,7 +1544,7 @@ packages:
peerDependencies:
solid-js: ^1.6.15
dependencies:
'@floating-ui/dom': 1.2.6
'@floating-ui/dom': 1.2.7
'@internationalized/date': 3.2.0
'@internationalized/number': 3.2.0
'@internationalized/string': 3.1.0
@@ -1545,12 +1552,12 @@ packages:
solid-js: 1.7.3
dev: false
/@kobalte/tailwindcss@0.5.0(tailwindcss@3.3.1):
/@kobalte/tailwindcss@0.5.0(tailwindcss@3.3.2):
resolution: {integrity: sha512-qP2C6mS4FcINHdUBFhNHe2QPvdSvbpDW30b0BgtPVu9F1H1nud2j3DJBezXMDE0N72mrxtvmLRyel9eIUCPVVQ==}
peerDependencies:
tailwindcss: ^3.2.7
dependencies:
tailwindcss: 3.3.1(postcss@8.4.23)
tailwindcss: 3.3.2
dev: false
/@kobalte/utils@0.6.1(solid-js@1.7.3):
@@ -1635,8 +1642,8 @@ packages:
tslib: 2.5.0
dev: false
/@mutinywallet/mutiny-wasm@0.2.6:
resolution: {integrity: sha512-d87ss1LVaQVDKvzCRvdEM0JAMtvx2XqFMsq1ZDuISmTx+Ehoz8TCCpjrVBfMTPcEUd1ZL8eQzXM/Ui9uNeNn3w==}
/@mutinywallet/mutiny-wasm@0.2.7:
resolution: {integrity: sha512-AssJjkqDdYLD9kzJWfMJe1lZL+uGDBJbmd5ehUokdLKGbIrSpUzBO8hWDjWxI8dteci4laApZ/WfVRjVW7PQ9Q==}
dev: false
/@mutinywallet/waila-wasm@0.1.5:
@@ -1971,6 +1978,14 @@ packages:
tslib: 2.5.0
dev: false
/@thisbeyond/solid-select@0.14.0(solid-js@1.7.3):
resolution: {integrity: sha512-ecq4U3Vnc/nJbU84ARuPg2scNuYt994ljF5AmBlzuZW87x43mWiGJ5hEWufIJJMpDT6CcnCIx/xbrdDkaDEHQw==}
peerDependencies:
solid-js: ^1.5
dependencies:
solid-js: 1.7.3
dev: false
/@types/babel__core@7.20.0:
resolution: {integrity: sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==}
dependencies:
@@ -1978,7 +1993,7 @@ packages:
'@babel/types': 7.21.4
'@types/babel__generator': 7.6.4
'@types/babel__template': 7.4.1
'@types/babel__traverse': 7.18.3
'@types/babel__traverse': 7.18.4
/@types/babel__generator@7.6.4:
resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==}
@@ -1991,8 +2006,8 @@ packages:
'@babel/parser': 7.21.4
'@babel/types': 7.21.4
/@types/babel__traverse@7.18.3:
resolution: {integrity: sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==}
/@types/babel__traverse@7.18.4:
resolution: {integrity: sha512-TLG7CsGZZmX9aDF78UuJxnNTfQyRUFU0OYIVyIblr0/wd/HvsIo8wmuB90CszeD2MtLLAE9Tt4cWvk+KVkyGIw==}
dependencies:
'@babel/types': 7.21.4
@@ -2012,8 +2027,8 @@ packages:
/@types/json5@0.0.29:
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
/@types/node@18.16.0:
resolution: {integrity: sha512-BsAaKhB+7X+H4GnSjGhJG9Qi8Tw+inU9nJDwmD5CgOmBLEI6ArdhikpLX7DjbjDRDTbqZzU2LSQNZg8WGPiSZQ==}
/@types/node@18.16.1:
resolution: {integrity: sha512-DZxSZWXxFfOlx7k7Rv4LAyiMroaxa3Ly/7OOzZO8cBNho0YzAi4qlbrx8W27JGqG57IgR/6J7r+nOJWw6kcvZA==}
/@types/offscreencanvas@2019.7.0:
resolution: {integrity: sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==}
@@ -2022,7 +2037,7 @@ packages:
/@types/resolve@1.17.1:
resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==}
dependencies:
'@types/node': 18.16.0
'@types/node': 18.16.1
dev: true
/@types/resolve@1.20.2:
@@ -2382,7 +2397,7 @@ packages:
hasBin: true
dependencies:
caniuse-lite: 1.0.30001481
electron-to-chromium: 1.4.370
electron-to-chromium: 1.4.372
node-releases: 2.0.10
update-browserslist-db: 1.0.11(browserslist@4.21.5)
@@ -2675,8 +2690,8 @@ packages:
jake: 10.8.5
dev: true
/electron-to-chromium@1.4.370:
resolution: {integrity: sha512-c+wzD4sCYQeNeasbnArwsU3ig6+lR6bwQmxfMjB6bx+XoopVSPFp+7ZLxqa90MTC+Tq9QQ5l7zsMNG9GgMBorg==}
/electron-to-chromium@1.4.372:
resolution: {integrity: sha512-MrlFq/j+TYHOjeWsWGYfzevc25HNeJdsF6qaLFrqBTRWZQtWkb1myq/Q2veLWezVaa5OcSZ99CFwTT4aF4Mung==}
/emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
@@ -3822,7 +3837,7 @@ packages:
resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==}
engines: {node: '>= 10.13.0'}
dependencies:
'@types/node': 18.16.0
'@types/node': 18.16.1
merge-stream: 2.0.0
supports-color: 7.2.0
dev: true
@@ -3831,8 +3846,8 @@ packages:
resolution: {integrity: sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==}
hasBin: true
/joi@17.9.1:
resolution: {integrity: sha512-FariIi9j6QODKATGBrEX7HZcja8Bsh3rfdGYy/Sb65sGlZWK/QWesU1ghk7aJWDj95knjXlQfSmzFSPPkLVsfw==}
/joi@17.9.2:
resolution: {integrity: sha512-Itk/r+V4Dx0V3c7RLFdRh12IOjySm2/WGPMubBT92cQvRfYZhPM2W0hZlctjj72iES8jsRCwp7S/cRmWBnJ4nw==}
dependencies:
'@hapi/hoek': 9.3.0
'@hapi/topo': 5.1.0
@@ -4242,9 +4257,9 @@ packages:
'@polka/url': 1.0.0-next.21
trouter: 3.2.1
/postcss-import@14.1.0(postcss@8.4.23):
resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==}
engines: {node: '>=10.0.0'}
/postcss-import@15.1.0(postcss@8.4.23):
resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
engines: {node: '>=14.0.0'}
peerDependencies:
postcss: ^8.0.0
dependencies:
@@ -4262,9 +4277,9 @@ packages:
camelcase-css: 2.0.1
postcss: 8.4.23
/postcss-load-config@3.1.4(postcss@8.4.23):
resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==}
engines: {node: '>= 10'}
/postcss-load-config@4.0.1(postcss@8.4.23):
resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==}
engines: {node: '>= 14'}
peerDependencies:
postcss: '>=8.0.9'
ts-node: '>=9.0.0'
@@ -4276,10 +4291,10 @@ packages:
dependencies:
lilconfig: 2.1.0
postcss: 8.4.23
yaml: 1.10.2
yaml: 2.2.2
/postcss-nested@6.0.0(postcss@8.4.23):
resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==}
/postcss-nested@6.0.1(postcss@8.4.23):
resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==}
engines: {node: '>=12.0'}
peerDependencies:
postcss: ^8.2.14
@@ -4349,10 +4364,6 @@ packages:
/queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
/quick-lru@5.1.1:
resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
engines: {node: '>=10'}
/randombytes@2.1.0:
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
dependencies:
@@ -4575,8 +4586,8 @@ packages:
get-intrinsic: 1.2.0
object-inspect: 1.12.3
/sirv@2.0.2:
resolution: {integrity: sha512-4Qog6aE29nIjAOKe/wowFTxOdmbEZKb+3tsLljaBRzJwtqto0BChD2zzH0LhgCSXiI+V7X+Y45v14wBZQ1TK3w==}
/sirv@2.0.3:
resolution: {integrity: sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==}
engines: {node: '>= 10'}
dependencies:
'@polka/url': 1.0.0-next.21
@@ -4614,7 +4625,7 @@ packages:
'@babel/types': 7.21.4
solid-js: 1.7.3
/solid-start-node@0.2.26(solid-start@0.2.26)(undici@5.22.0)(vite@4.3.1):
/solid-start-node@0.2.26(solid-start@0.2.26)(undici@5.22.0)(vite@4.3.3):
resolution: {integrity: sha512-8vciTGoQV+lIlCUSVHJPazlaoKDRfBowDkPeBr/EZdmtbcMOKoJYf/APPQWFspylF+nhzunMf0+zJP90VtMEYg==}
peerDependencies:
solid-start: '*'
@@ -4627,15 +4638,15 @@ packages:
compression: 1.7.4
polka: 1.0.0-next.22
rollup: 3.21.0
sirv: 2.0.2
solid-start: 0.2.26(@solidjs/meta@0.28.4)(@solidjs/router@0.8.2)(solid-js@1.7.3)(solid-start-node@0.2.26)(vite@4.3.1)
sirv: 2.0.3
solid-start: 0.2.26(@solidjs/meta@0.28.4)(@solidjs/router@0.8.2)(solid-js@1.7.3)(solid-start-node@0.2.26)(vite@4.3.3)
terser: 5.17.1
undici: 5.22.0
vite: 4.3.1(@types/node@18.16.0)
vite: 4.3.3(@types/node@18.16.1)
transitivePeerDependencies:
- supports-color
/solid-start@0.2.26(@solidjs/meta@0.28.4)(@solidjs/router@0.8.2)(solid-js@1.7.3)(solid-start-node@0.2.26)(vite@4.3.1):
/solid-start@0.2.26(@solidjs/meta@0.28.4)(@solidjs/router@0.8.2)(solid-js@1.7.3)(solid-start-node@0.2.26)(vite@4.3.3):
resolution: {integrity: sha512-kne2HZlnSMzsirdnvNs1CsDqBl0L0uvKKt1t4de1CH7JIngyqoMcER97jTE0Ejr84KknANaKAdvJAzZcL7Ueng==}
hasBin: true
peerDependencies:
@@ -4696,14 +4707,14 @@ packages:
rollup-route-manifest: 1.0.0(rollup@3.21.0)
sade: 1.8.1
set-cookie-parser: 2.6.0
sirv: 2.0.2
sirv: 2.0.3
solid-js: 1.7.3
solid-start-node: 0.2.26(solid-start@0.2.26)(undici@5.22.0)(vite@4.3.1)
solid-start-node: 0.2.26(solid-start@0.2.26)(undici@5.22.0)(vite@4.3.3)
terser: 5.17.1
undici: 5.22.0
vite: 4.3.1(@types/node@18.16.0)
vite-plugin-inspect: 0.7.24(rollup@3.21.0)(vite@4.3.1)
vite-plugin-solid: 2.7.0(solid-js@1.7.3)(vite@4.3.1)
vite: 4.3.3(@types/node@18.16.1)
vite-plugin-inspect: 0.7.24(rollup@3.21.0)(vite@4.3.3)
vite-plugin-solid: 2.7.0(solid-js@1.7.3)(vite@4.3.3)
wait-on: 6.0.1(debug@4.3.4)
transitivePeerDependencies:
- supports-color
@@ -4852,16 +4863,14 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
/tailwindcss@3.3.1(postcss@8.4.23):
resolution: {integrity: sha512-Vkiouc41d4CEq0ujXl6oiGFQ7bA3WEhUZdTgXAhtKxSy49OmKs8rEfQmupsfF0IGW8fv2iQkp1EVUuapCFrZ9g==}
engines: {node: '>=12.13.0'}
/tailwindcss@3.3.2:
resolution: {integrity: sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w==}
engines: {node: '>=14.0.0'}
hasBin: true
peerDependencies:
postcss: ^8.0.9
dependencies:
'@alloc/quick-lru': 5.2.0
arg: 5.0.2
chokidar: 3.5.3
color-name: 1.1.4
didyoumean: 1.2.2
dlv: 1.1.3
fast-glob: 3.2.12
@@ -4874,13 +4883,12 @@ packages:
object-hash: 3.0.0
picocolors: 1.0.0
postcss: 8.4.23
postcss-import: 14.1.0(postcss@8.4.23)
postcss-import: 15.1.0(postcss@8.4.23)
postcss-js: 4.0.1(postcss@8.4.23)
postcss-load-config: 3.1.4(postcss@8.4.23)
postcss-nested: 6.0.0(postcss@8.4.23)
postcss-load-config: 4.0.1(postcss@8.4.23)
postcss-nested: 6.0.1(postcss@8.4.23)
postcss-selector-parser: 6.0.11
postcss-value-parser: 4.2.0
quick-lru: 5.1.1
resolve: 1.22.2
sucrase: 3.32.0
transitivePeerDependencies:
@@ -5117,7 +5125,7 @@ packages:
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
engines: {node: '>= 0.8'}
/vite-plugin-inspect@0.7.24(rollup@3.21.0)(vite@4.3.1):
/vite-plugin-inspect@0.7.24(rollup@3.21.0)(vite@4.3.3):
resolution: {integrity: sha512-XyrhTxYF+5X8CH0PFmYJhs8WGJMOa2UxwUftTaT0FiMm24VfUp+UsAh7xDZI3doPOiB5GxKEizDGxdU98Ay+Vg==}
engines: {node: '>=14'}
peerDependencies:
@@ -5128,13 +5136,13 @@ packages:
debug: 4.3.4
fs-extra: 11.1.1
picocolors: 1.0.0
sirv: 2.0.2
vite: 4.3.1(@types/node@18.16.0)
sirv: 2.0.3
vite: 4.3.3(@types/node@18.16.1)
transitivePeerDependencies:
- rollup
- supports-color
/vite-plugin-pwa@0.14.7(vite@4.3.1)(workbox-build@6.5.4)(workbox-window@6.5.4):
/vite-plugin-pwa@0.14.7(vite@4.3.3)(workbox-build@6.5.4)(workbox-window@6.5.4):
resolution: {integrity: sha512-dNJaf0fYOWncmjxv9HiSa2xrSjipjff7IkYE5oIUJ2x5HKu3cXgA8LRgzOwTc5MhwyFYRSU0xyN0Phbx3NsQYw==}
peerDependencies:
vite: ^3.1.0 || ^4.0.0
@@ -5146,14 +5154,14 @@ packages:
fast-glob: 3.2.12
pretty-bytes: 6.1.0
rollup: 3.21.0
vite: 4.3.1(@types/node@18.16.0)
vite: 4.3.3(@types/node@18.16.1)
workbox-build: 6.5.4
workbox-window: 6.5.4
transitivePeerDependencies:
- supports-color
dev: true
/vite-plugin-solid@2.7.0(solid-js@1.7.3)(vite@4.3.1):
/vite-plugin-solid@2.7.0(solid-js@1.7.3)(vite@4.3.3):
resolution: {integrity: sha512-avp/Jl5zOp/Itfo67xtDB2O61U7idviaIp4mLsjhCa13PjKNasz+IID0jYTyqUp9SFx6/PmBr6v4KgDppqompg==}
peerDependencies:
solid-js: ^1.7.2
@@ -5166,21 +5174,21 @@ packages:
merge-anything: 5.1.5
solid-js: 1.7.3
solid-refresh: 0.5.2(solid-js@1.7.3)
vite: 4.3.1(@types/node@18.16.0)
vitefu: 0.2.4(vite@4.3.1)
vite: 4.3.3(@types/node@18.16.1)
vitefu: 0.2.4(vite@4.3.3)
transitivePeerDependencies:
- supports-color
/vite-plugin-wasm@3.2.2(vite@4.3.1):
/vite-plugin-wasm@3.2.2(vite@4.3.3):
resolution: {integrity: sha512-cdbBUNR850AEoMd5nvLmnyeq63CSfoP1ctD/L2vLk/5+wsgAPlAVAzUK5nGKWO/jtehNlrSSHLteN+gFQw7VOA==}
peerDependencies:
vite: ^2 || ^3 || ^4
dependencies:
vite: 4.3.1(@types/node@18.16.0)
vite: 4.3.3(@types/node@18.16.1)
dev: true
/vite@4.3.1(@types/node@18.16.0):
resolution: {integrity: sha512-EPmfPLAI79Z/RofuMvkIS0Yr091T2ReUoXQqc5ppBX/sjFRhHKiPPF/R46cTdoci/XgeQpB23diiJxq5w30vdg==}
/vite@4.3.3(@types/node@18.16.1):
resolution: {integrity: sha512-MwFlLBO4udZXd+VBcezo3u8mC77YQk+ik+fbc0GZWGgzfbPP+8Kf0fldhARqvSYmtIWoAJ5BXPClUbMTlqFxrA==}
engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true
peerDependencies:
@@ -5204,14 +5212,14 @@ packages:
terser:
optional: true
dependencies:
'@types/node': 18.16.0
'@types/node': 18.16.1
esbuild: 0.17.18
postcss: 8.4.23
rollup: 3.21.0
optionalDependencies:
fsevents: 2.3.2
/vitefu@0.2.4(vite@4.3.1):
/vitefu@0.2.4(vite@4.3.3):
resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==}
peerDependencies:
vite: ^3.0.0 || ^4.0.0
@@ -5219,7 +5227,7 @@ packages:
vite:
optional: true
dependencies:
vite: 4.3.1(@types/node@18.16.0)
vite: 4.3.3(@types/node@18.16.1)
/wait-on@6.0.1(debug@4.3.4):
resolution: {integrity: sha512-zht+KASY3usTY5u2LgaNqn/Cd8MukxLGjdcZxT2ns5QzDmTFc4XoWBgC+C/na+sMRZTuVygQoMYwdcVjHnYIVw==}
@@ -5227,7 +5235,7 @@ packages:
hasBin: true
dependencies:
axios: 0.25.0(debug@4.3.4)
joi: 17.9.1
joi: 17.9.2
lodash: 4.17.21
minimist: 1.2.8
rxjs: 7.8.0
@@ -5477,9 +5485,9 @@ packages:
/yallist@4.0.0:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
/yaml@1.10.2:
resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
engines: {node: '>= 6'}
/yaml@2.2.2:
resolution: {integrity: sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA==}
engines: {node: '>= 14'}
/yargs-parser@21.1.1:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}

View File

@@ -18,9 +18,12 @@ function SingleDigitButton(props: { character: string, onClick: (c: string) => v
);
}
export function AmountEditable(props: { initialAmountSats: string, setAmountSats: (s: bigint) => void, onSave?: () => void }) {
export function AmountEditable(props: { initialAmountSats: string, setAmountSats: (s: bigint) => void }) {
const [isOpen, setIsOpen] = createSignal(false);
const [displayAmount, setDisplayAmount] = createSignal(props.initialAmountSats || "0");
let inputRef!: HTMLInputElement;
function handleCharacterInput(character: string) {
@@ -101,9 +104,12 @@ export function AmountEditable(props: { initialAmountSats: string, setAmountSats
const amountInUsd = () => satsToUsd(state.price, Number(displayAmount()) || 0, true)
// What we're all here for in the first place: returning a value
function handleSubmit() {
function handleSubmit(e: SubmitEvent | MouseEvent) {
e.preventDefault()
// validate it's a number
console.log("handling submit...");
console.log(displayAmount());
const number = Number(displayAmount());
if (isNaN(number) || number < 0) {
setDisplayAmount("0");
@@ -112,36 +118,36 @@ export function AmountEditable(props: { initialAmountSats: string, setAmountSats
} else {
const bign = BigInt(displayAmount());
props.setAmountSats(bign);
// This is so the parent can focus the next input if it wants to
if (props.onSave) {
props.onSave();
}
}
setIsOpen(false);
}
const DIALOG_POSITIONER = "fixed inset-0 safe-top safe-bottom z-50"
const DIALOG_CONTENT = "h-screen-safe p-4 bg-gray/50 backdrop-blur-md bg-black/80"
return (
<Dialog.Root>
<Dialog.Trigger>
<div class="p-4 rounded-xl border-2 border-m-blue">
<Amount amountSats={Number(displayAmount())} showFiat />
</div>
</Dialog.Trigger>
<Dialog.Root isOpen={isOpen()}>
<button onClick={() => setIsOpen(true)} class="p-4 rounded-xl border-2 border-m-blue">
<Amount amountSats={Number(displayAmount())} showFiat />
</button>
<Dialog.Portal>
{/* <Dialog.Overlay class={OVERLAY} /> */}
<div class={DIALOG_POSITIONER}>
<Dialog.Content class={DIALOG_CONTENT}>
{/* TODO: figure out how to submit on enter */}
<input ref={el => inputRef = el}
autofocus
inputmode='none'
type="text"
class="opacity-0 absolute -z-10"
value={displayAmount()}
onInput={(e) => handleHiddenInput(e)}
/>
<form onSubmit={handleSubmit}>
<input ref={el => inputRef = el}
autofocus
inputmode='none'
type="text"
class="opacity-0 absolute -z-10"
value={displayAmount()}
onInput={(e) => handleHiddenInput(e)}
/>
</form>
<div class="flex flex-col gap-4 max-w-[400px] mx-auto">
<div class="p-4 bg-black rounded-xl flex flex-col gap-4 items-center justify-center">
<h1 class={`font-light text-center transition-transform ease-out duration-300 text-6xl ${scale()}`}>
@@ -159,13 +165,9 @@ export function AmountEditable(props: { initialAmountSats: string, setAmountSats
</For>
</div>
{/* TODO: this feels wrong */}
<Dialog.CloseButton>
<Button intent="inactive" class="w-full flex-none"
onClick={handleSubmit}
>
Set Amount
</Button>
</Dialog.CloseButton>
<Button intent="inactive" class="w-full flex-none" onClick={handleSubmit}>
Set Amount
</Button>
</div>
</Dialog.Content>
</div>

View File

@@ -0,0 +1,64 @@
import { Select, createOptions } from "@thisbeyond/solid-select";
import "~/styles/solid-select.css"
import { SmallHeader } from "./layout";
// take two arrays, subtract the second from the first, then return the first
function subtract<T>(a: T[], b: T[]) {
const set = new Set(b);
return a.filter(x => !set.has(x));
};
// simple math.random based id generator
const createUniqueId = () => Math.random().toString(36).substr(2, 9);
export type TagItem = {
id: string;
name: string;
kind: "text" | "contact";
}
const createValue = (name: string) => {
return { id: createUniqueId(), name, kind: "text" };
};
export function TagEditor(props: { title: string, values: TagItem[], setValues: (values: TagItem[]) => void, selectedValues: TagItem[], setSelectedValues: (values: TagItem[]) => void }) {
const onChange = (selected: TagItem[]) => {
props.setSelectedValues(selected);
console.log(selected)
const lastValue = selected[selected.length - 1];
if (lastValue && !props.values.includes(lastValue)) {
props.setValues([...props.values, lastValue]);
}
};
const selectProps = createOptions(props.values, {
key: "name",
disable: (value) => props.selectedValues.includes(value),
filterable: true, // Default
createable: createValue,
});
return (
<div class="flex flex-col gap-2 flex-grow flex-shrink flex-1" >
<SmallHeader>{props.title}</SmallHeader>
<Select
multiple
onChange={onChange}
placeholder="Where's it coming from?"
{...selectProps}
/>
{/* TODO: blocked on https://github.com/thisbeyond/solid-select/issues/39 */}
{/* <div class="flex gap-2 flex-wrap">
<For each={subtract(props.values, props.selectedValues).slice(0, 3)}>
{(contact) => (
<div onClick={() => onChange([...props.selectedValues, contact])} class="bg-m-blue/50 px-1 py-[0.5] rounded cursor-pointer hover:outline-white hover:outline-1">{contact.name}</div>
)}
</For>
<button class="bg-black border border-white px-1 py-[0.5] rounded cursor-pointer hover:outline-white hover:outline-1">+ Add Contact</button>
</div> */}
</div >
)
}

View File

View File

@@ -2,5 +2,5 @@ import { A } from "solid-start";
import { Back } from "~/assets/svg/Back";
export function BackButton(props: { href?: string, title?: string }) {
return (<A href={props.href ? props.href : "/"} class="text-m-red text-xl font-semibold no-underline md:hidden flex items-center"><Back />{props.title ? props.title : "Home"}</A>)
return (<A href={props.href ? props.href : "/"} class="text-m-red active:text-m-red/80 text-xl font-semibold no-underline md:hidden flex items-center"><Back />{props.title ? props.title : "Home"}</A>)
}

View File

@@ -1,7 +1,7 @@
import { Dialog } from "@kobalte/core";
import { JSX } from "solid-js";
import { Button, SmallHeader } from "~/components/layout";
import { Button, LargeHeader, SmallHeader } from "~/components/layout";
import close from "~/assets/icons/close.svg";
const DIALOG_POSITIONER = "fixed inset-0 safe-top safe-bottom z-50"
@@ -24,9 +24,9 @@ export function FullscreenModal(props: FullscreenModalProps) {
<Dialog.Content class={DIALOG_CONTENT}>
<div class="flex justify-between items-center mb-2">
<Dialog.Title>
<SmallHeader>
<LargeHeader>
{props.title}
</SmallHeader>
</LargeHeader>
</Dialog.Title>
<Dialog.CloseButton class="p-2 hover:bg-white/10 rounded-lg active:bg-m-blue">
<img src={close} alt="Close" />

View File

@@ -1,24 +1,26 @@
import { RadioGroup } from "@kobalte/core";
import { For } from "solid-js";
import { For, Show } from "solid-js";
type Choices = { value: string, label: string, caption: string }[]
// TODO: how could would it be if we could just pass the estimated fees in here?
export function StyledRadioGroup(props: { value: string, choices: Choices, onValueChange: (value: string) => void }) {
export function StyledRadioGroup(props: { value: string, choices: Choices, onValueChange: (value: string) => void, small?: boolean, }) {
return (
<RadioGroup.Root value={props.value} onValueChange={(e) => props.onValueChange(e)} class="grid w-full gap-4 grid-cols-2">
<RadioGroup.Root value={props.value} onValueChange={(e) => props.onValueChange(e)} class={`grid w-full gap-${props.small ? "2" : "4"} grid-cols-${props.choices.length.toString()}`}>
<For each={props.choices}>
{choice =>
<RadioGroup.Item value={choice.value} class="ui-checked:bg-neutral-950 bg-white/10 rounded outline outline-black/50 ui-checked:outline-m-blue ui-checked:outline-2">
<div class="py-3 px-4">
<div class={props.small ? "py-2 px-2" : "py-3 px-4"}>
<RadioGroup.ItemInput />
<RadioGroup.ItemControl >
<RadioGroup.ItemIndicator />
</RadioGroup.ItemControl>
<RadioGroup.ItemLabel class="ui-checked:text-white text-neutral-400">
<div class="block">
<div class="text-lg font-semibold">{choice.label}</div>
<div class="text-sm font-light">{choice.caption}</div>
<div class={`text-${props.small ? "base" : "lg"} font-semibold`}>{choice.label}</div>
<Show when={!props.small}>
<div class="text-sm font-light">{choice.caption}</div>
</Show>
</div>
</RadioGroup.ItemLabel>
</div>

View File

@@ -40,11 +40,10 @@ const FancyCard: ParentComponent<{ title?: string, tag?: JSX.Element }> = (props
const SafeArea: ParentComponent = (props) => {
return (
<div class="safe-top safe-left safe-right safe-bottom flex flex-col h-screen-safe">
<div class="flex-1 disable-scrollbars overflow-y-scroll md:pl-[8rem] md:pr-[6rem]">
{props.children}
<div class="h-32" />
</div>
<div class="safe-top safe-left safe-right safe-bottom">
{/* <div class="flex-1 disable-scrollbars overflow-y-scroll md:pl-[8rem] md:pr-[6rem]"> */}
{props.children}
{/* </div> */}
</div >
)
}

View File

@@ -1,12 +1,10 @@
import { TextField } from "@kobalte/core";
import { MutinyBip21RawMaterials, MutinyInvoice } from "@mutinywallet/mutiny-wasm";
import { createEffect, createMemo, createResource, createSignal, Match, onCleanup, Switch } from "solid-js";
import { createEffect, createResource, createSignal, For, Match, onCleanup, Switch } from "solid-js";
import { QRCodeSVG } from "solid-qr-code";
import { AmountEditable } from "~/components/AmountEditable";
import { Button, Card, DefaultMain, LargeHeader, NodeManagerGuard, SafeArea, SmallHeader } from "~/components/layout";
import { Button, Card, LargeHeader, NodeManagerGuard, SafeArea, SmallHeader } from "~/components/layout";
import NavBar from "~/components/NavBar";
import { useMegaStore } from "~/state/megaStore";
import { satsToUsd } from "~/utils/conversions";
import { objectToSearchParams } from "~/utils/objectToSearchParams";
import { useCopy } from "~/utils/useCopy";
import mempoolTxUrl from "~/utils/mempoolTxUrl";
@@ -15,6 +13,9 @@ import party from '~/assets/party.gif';
import { Amount } from "~/components/Amount";
import { FullscreenModal } from "~/components/layout/FullscreenModal";
import { BackButton } from "~/components/layout/BackButton";
import { TagEditor, TagItem } from "~/components/TagEditor";
import { StyledRadioGroup } from "~/components/layout/Radio";
import { showToast } from "~/components/Toaster";
type OnChainTx = {
transaction: {
@@ -40,6 +41,19 @@ type OnChainTx = {
}
}
const createUniqueId = () => Math.random().toString(36).substr(2, 9);
const fakeContacts: TagItem[] = [
{ id: createUniqueId(), name: "Unknown", kind: "text" },
{ id: createUniqueId(), name: "Alice", kind: "contact" },
{ id: createUniqueId(), name: "Bob", kind: "contact" },
{ id: createUniqueId(), name: "Carol", kind: "contact" },
]
const RECEIVE_FLAVORS = [{ value: "unified", label: "Unified", caption: "Sender decides" }, { value: "lightning", label: "Lightning", caption: "Fast and cool" }, { value: "onchain", label: "On-chain", caption: "Just like Satoshi did it" }]
type ReceiveFlavor = "unified" | "lightning" | "onchain"
function ShareButton(props: { receiveString: string }) {
async function share(receiveString: string) {
// If the browser doesn't support share we can just copy the address
@@ -69,26 +83,29 @@ export default function Receive() {
const [state, _] = useMegaStore()
const [amount, setAmount] = createSignal("")
const [label, setLabel] = createSignal("")
const [receiveState, setReceiveState] = createSignal<ReceiveState>("edit")
const [bip21Raw, setBip21Raw] = createSignal<MutinyBip21RawMaterials>();
const [unified, setUnified] = createSignal("")
// Tagging stuff
const [selectedValues, setSelectedValues] = createSignal<TagItem[]>([]);
const [values, setValues] = createSignal([...fakeContacts]);
// The data we get after a payment
const [paymentTx, setPaymentTx] = createSignal<OnChainTx>();
const [paymentInvoice, setPaymentInvoice] = createSignal<MutinyInvoice>();
// The flavor of the receive
const [flavor, setFlavor] = createSignal<ReceiveFlavor>("unified");
function clearAll() {
setAmount("")
setLabel("")
setReceiveState("edit")
setBip21Raw(undefined)
setUnified("")
setPaymentTx(undefined)
setPaymentInvoice(undefined)
setSelectedValues([])
}
let amountInput!: HTMLInputElement;
@@ -106,43 +123,48 @@ export default function Receive() {
labelInput.focus();
}
const [copy, copied] = useCopy({ copiedTimeout: 1000 });
async function getUnifiedQr(amount: string, label: string) {
function handleCopy() {
if (flavor() === "unified") {
copy(unified() ?? "")
} else if (flavor() === "lightning") {
copy(bip21Raw()?.invoice ?? "")
} else if (flavor() === "onchain") {
copy(bip21Raw()?.address ?? "")
}
}
async function getUnifiedQr(amount: string) {
const bigAmount = BigInt(amount);
const raw = await state.node_manager?.create_bip21(bigAmount, label);
try {
const raw = await state.node_manager?.create_bip21(bigAmount, "TODO DELETE ME");
// Save the raw info so we can watch the address and invoice
setBip21Raw(raw);
// Save the raw info so we can watch the address and invoice
setBip21Raw(raw);
const params = objectToSearchParams({
amount: raw?.btc_amount,
label: raw?.description,
lightning: raw?.invoice
})
const params = objectToSearchParams({
amount: raw?.btc_amount,
label: raw?.description,
lightning: raw?.invoice
})
return `bitcoin:${raw?.address}?${params}`
return `bitcoin:${raw?.address}?${params}`
} catch (e) {
showToast(new Error("Couldn't create invoice. Are you asking for enough?"))
console.error(e)
}
}
async function onSubmit(e: Event) {
e.preventDefault();
const unifiedQr = await getUnifiedQr(amount(), label())
const unifiedQr = await getUnifiedQr(amount())
setUnified(unifiedQr)
setUnified(unifiedQr || "")
setReceiveState("show")
}
const amountInUsd = createMemo(() => satsToUsd(state.price, parseInt(amount()) || 0, true))
function handleAmountSave() {
console.error("focusing label input...")
console.error(labelInput)
labelInput.focus();
}
async function checkIfPaid(bip21?: MutinyBip21RawMaterials): Promise<PaidState | undefined> {
if (bip21) {
console.log("checking if paid...")
@@ -181,46 +203,59 @@ export default function Receive() {
return (
<NodeManagerGuard>
<SafeArea>
<DefaultMain>
<main class="max-w-[600px] flex flex-col gap-4 mx-auto p-4">
<BackButton />
<LargeHeader>Receive Bitcoin</LargeHeader>
<Switch>
<Match when={!unified() || receiveState() === "edit"}>
<AmountEditable initialAmountSats={amount() || "0"} setAmountSats={setAmount} onSave={handleAmountSave} />
<div>
<Button intent="glowy" layout="xs">Tag the sender</Button>
</div>
<form class="flex flex-col gap-4" onSubmit={onSubmit} >
<TextField.Root
value={label()}
onValueChange={setLabel}
class="flex flex-col gap-2"
>
<TextField.Label><SmallHeader>Label (private)</SmallHeader></TextField.Label>
<TextField.Input
ref={el => labelInput = el}
class="w-full p-2 rounded-lg text-black" />
</TextField.Root>
<Button disabled={!amount() || !label()} intent="green" type="submit">Create Invoice</Button>
</form >
<dl>
<dd>
<AmountEditable initialAmountSats={amount() || "0"} setAmountSats={setAmount} />
</dd>
<dd>
<TagEditor title="Tag the origin" values={values()} setValues={setValues} selectedValues={selectedValues()} setSelectedValues={setSelectedValues} />
</dd>
</dl>
<Button class="w-full" disabled={!amount() || !selectedValues().length} intent="green" onClick={onSubmit}>Create Invoice</Button>
</Match>
<Match when={unified() && receiveState() === "show"}>
<StyledRadioGroup small value={flavor()} onValueChange={setFlavor} choices={RECEIVE_FLAVORS} />
<div class="w-full bg-white rounded-xl">
<QRCodeSVG value={unified() ?? ""} class="w-full h-full p-8 max-h-[400px]" />
<Switch>
<Match when={flavor() === "unified"}>
<QRCodeSVG value={unified() ?? ""} class="w-full h-full p-8 max-h-[400px]" />
</Match>
<Match when={flavor() === "lightning"}>
<QRCodeSVG value={bip21Raw()?.invoice ?? ""} class="w-full h-full p-8 max-h-[400px]" />
</Match>
<Match when={flavor() === "onchain"}>
<QRCodeSVG value={bip21Raw()?.address ?? ""} class="w-full h-full p-8 max-h-[400px]" />
</Match>
</Switch>
</div>
<div class="flex gap-2 w-full">
<Button onClick={(_) => copy(unified() ?? "")}>{copied() ? "Copied" : "Copy"}</Button>
<Button onClick={handleCopy}>{copied() ? "Copied" : "Copy"}</Button>
<ShareButton receiveString={unified() ?? ""} />
</div>
<Card>
<SmallHeader>Amount</SmallHeader>
<div class="flex justify-between">
<p>{amount()} sats</p><button onClick={editAmount}>&#x270F;&#xFE0F;</button>
<Amount amountSats={parseInt(amount()) || 0} showFiat={true} />
<button onClick={editAmount}>&#x270F;&#xFE0F;</button>
</div>
<pre>({amountInUsd()})</pre>
<SmallHeader>Private Label</SmallHeader>
<SmallHeader>Tags</SmallHeader>
<div class="flex justify-between">
<p>{label()} </p><button onClick={editLabel}>&#x270F;&#xFE0F;</button>
<div class="flex flex-wrap">
<For each={selectedValues()}>
{(tag) => (
<div class=" bg-white/20 rounded px-1">
{tag.name}
</div>)}
</For>
</div>
{/* <pre>{JSON.stringify(selectedValues(), null, 2)}</pre> */}
<button onClick={editLabel}>&#x270F;&#xFE0F;</button>
</div>
</Card>
<Card title="Bip21">
@@ -228,7 +263,7 @@ export default function Receive() {
</Card>
</Match>
<Match when={receiveState() === "paid" && paidState() === "lightning_paid"}>
<FullscreenModal title="Payment Received!" open={!!paidState()} setOpen={(open: boolean) => { if (!open) clearAll() }}>
<FullscreenModal title="Payment Received" open={!!paidState()} setOpen={(open: boolean) => { if (!open) clearAll() }}>
<div class="flex flex-col items-center gap-8">
<img src={party} alt="party" class="w-1/2 mx-auto max-w-[50vh] aspect-square" />
<Amount amountSats={paymentInvoice()?.amount_sats} showFiat />
@@ -236,7 +271,7 @@ export default function Receive() {
</FullscreenModal>
</Match>
<Match when={receiveState() === "paid" && paidState() === "onchain_paid"}>
<FullscreenModal title="Payment Received!" open={!!paidState()} setOpen={(open: boolean) => { if (!open) clearAll() }}>
<FullscreenModal title="Payment Received" open={!!paidState()} setOpen={(open: boolean) => { if (!open) clearAll() }}>
<div class="flex flex-col items-center gap-8">
<img src={party} alt="party" class="w-1/2 mx-auto max-w-[50vh] aspect-square" />
<Amount amountSats={paymentTx()?.received} showFiat />
@@ -247,7 +282,7 @@ export default function Receive() {
</FullscreenModal>
</Match>
</Switch>
</DefaultMain>
</main>
<NavBar activeTab="receive" />
</SafeArea >
</NodeManagerGuard>

View File

@@ -171,7 +171,7 @@ export default function Send() {
<DefaultMain>
<BackButton />
<LargeHeader>Send Bitcoin</LargeHeader>
<FullscreenModal title="Sent!" open={!!sentDetails()} setOpen={(open: boolean) => { if (!open) setSentDetails(undefined) }} onConfirm={() => setSentDetails(undefined)}>
<FullscreenModal title="Sent" open={!!sentDetails()} setOpen={(open: boolean) => { if (!open) setSentDetails(undefined) }} onConfirm={() => setSentDetails(undefined)}>
<div class="flex flex-col items-center gap-8">
<img src={handshake} alt="party" class="w-1/2 mx-auto max-w-[50vh] zoom-image" />
<Amount amountSats={sentDetails()?.amount} showFiat />
@@ -247,8 +247,6 @@ export default function Send() {
</div>
</ButtonLink>
</HStack>
</VStack>
</Match>
</Switch>

View File

@@ -0,0 +1,67 @@
.solid-select-container[data-disabled="true"] {
@apply pointer-events-none;
}
.solid-select-container {
@apply relative;
}
.solid-select-control[data-disabled="true"] {
}
.solid-select-control {
@apply w-full p-2 rounded-lg bg-white/10 placeholder-neutral-400;
@apply grid leading-6;
grid-template-columns: repeat(1, minmax(0, 1fr));
}
.solid-select-control[data-multiple="true"][data-has-value="true"] {
@apply flex items-stretch gap-1 flex-wrap;
}
.solid-select-placeholder {
@apply text-neutral-400;
@apply col-start-1 row-start-1;
}
.solid-select-single-value {
@apply col-start-1 row-start-1;
}
.solid-select-multi-value {
@apply flex bg-white/20 rounded items-center px-1;
}
.solid-select-multi-value-remove {
/* TODO: there's gotta be a better way to vertically center this */
@apply pl-2 pr-1 leading-3 -mt-2 text-2xl;
}
.solid-select-input {
@apply bg-transparent caret-transparent flex-grow flex-shrink;
outline: 2px solid transparent;
@apply col-start-1 row-start-1;
}
.solid-select-input:read-only {
@apply cursor-default;
}
.solid-select-input[data-multiple="true"] {
@apply caret-current;
}
.solid-select-input[data-is-active="true"] {
@apply caret-current;
}
.solid-select-list {
@apply max-h-[50vh] min-w-full overflow-y-auto absolute whitespace-nowrap z-10 bg-neutral-950 p-2 rounded-lg;
}
.solid-select-option[data-focused="true"] {
}
.solid-select-option > mark {
@apply underline bg-white/10 text-white;
}
.solid-select-option {
@apply cursor-default select-none p-1 hover:bg-neutral-800 rounded;
}
.solid-select-option[data-disabled="true"] {
@apply pointer-events-none opacity-50;
}
.solid-select-list-placeholder {
@apply cursor-default select-none;
}