diff --git a/package.json b/package.json
index 0750a3e6..4fbc7a85 100644
--- a/package.json
+++ b/package.json
@@ -21,7 +21,6 @@
"@evilmartians/harmony": "^1.1.0",
"@getalby/sdk": "^2.5.0",
"@nostr-dev-kit/ndk": "^2.0.5",
- "@nostr-dev-kit/ndk-cache-dexie": "^2.0.5",
"@nostr-fetch/adapter-ndk": "^0.13.1",
"@radix-ui/react-alert-dialog": "^1.0.5",
"@radix-ui/react-avatar": "^1.0.4",
@@ -32,9 +31,7 @@
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-toolbar": "^1.0.4",
"@radix-ui/react-tooltip": "^1.0.7",
- "@tanstack/query-sync-storage-persister": "^5.8.1",
"@tanstack/react-query": "^5.8.1",
- "@tanstack/react-query-persist-client": "^5.8.1",
"@tauri-apps/api": "2.0.0-alpha.11",
"@tauri-apps/cli": "2.0.0-alpha.17",
"@tauri-apps/plugin-clipboard-manager": "2.0.0-alpha.3",
@@ -59,13 +56,10 @@
"@tiptap/react": "^2.1.12",
"@tiptap/starter-kit": "^2.1.12",
"@tiptap/suggestion": "^2.1.12",
- "cobe": "^0.6.3",
"dayjs": "^1.11.10",
- "destr": "^2.0.2",
"framer-motion": "^10.16.4",
"html-to-text": "^9.0.5",
"idb-keyval": "^6.2.1",
- "immer": "^10.0.3",
"light-bolt11-decoder": "^3.0.0",
"lru-cache": "^10.0.2",
"markdown-to-jsx": "^7.3.2",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 88e86861..fd55430b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -14,9 +14,6 @@ dependencies:
'@nostr-dev-kit/ndk':
specifier: ^2.0.5
version: 2.0.5(typescript@5.2.2)
- '@nostr-dev-kit/ndk-cache-dexie':
- specifier: ^2.0.5
- version: 2.0.5(typescript@5.2.2)
'@nostr-fetch/adapter-ndk':
specifier: ^0.13.1
version: 0.13.1(@nostr-dev-kit/ndk@2.0.5)(nostr-fetch@0.13.1)
@@ -47,15 +44,9 @@ dependencies:
'@radix-ui/react-tooltip':
specifier: ^1.0.7
version: 1.0.7(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
- '@tanstack/query-sync-storage-persister':
- specifier: ^5.8.1
- version: 5.8.1
'@tanstack/react-query':
specifier: ^5.8.1
version: 5.8.1(react-dom@18.2.0)(react@18.2.0)
- '@tanstack/react-query-persist-client':
- specifier: ^5.8.1
- version: 5.8.1(@tanstack/react-query@5.8.1)(react-dom@18.2.0)(react@18.2.0)
'@tauri-apps/api':
specifier: 2.0.0-alpha.11
version: 2.0.0-alpha.11
@@ -128,15 +119,9 @@ dependencies:
'@tiptap/suggestion':
specifier: ^2.1.12
version: 2.1.12(@tiptap/core@2.1.12)(@tiptap/pm@2.1.12)
- cobe:
- specifier: ^0.6.3
- version: 0.6.3
dayjs:
specifier: ^1.11.10
version: 1.11.10
- destr:
- specifier: ^2.0.2
- version: 2.0.2
framer-motion:
specifier: ^10.16.4
version: 10.16.4(react-dom@18.2.0)(react@18.2.0)
@@ -146,9 +131,6 @@ dependencies:
idb-keyval:
specifier: ^6.2.1
version: 6.2.1
- immer:
- specifier: ^10.0.3
- version: 10.0.3
light-bolt11-decoder:
specifier: ^3.0.0
version: 3.0.0
@@ -199,7 +181,7 @@ dependencies:
version: 1.1.1
reactflow:
specifier: ^11.10.1
- version: 11.10.1(@types/react@18.2.37)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0)
+ version: 11.10.1(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
sonner:
specifier: ^1.2.0
version: 1.2.0(react-dom@18.2.0)(react@18.2.0)
@@ -220,7 +202,7 @@ dependencies:
version: 0.16.2(react-dom@18.2.0)(react@18.2.0)
zustand:
specifier: ^4.4.6
- version: 4.4.6(@types/react@18.2.37)(immer@10.0.3)(react@18.2.0)
+ version: 4.4.6(@types/react@18.2.37)(react@18.2.0)
devDependencies:
'@tailwindcss/typography':
@@ -842,19 +824,6 @@ packages:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.15.0
- /@nostr-dev-kit/ndk-cache-dexie@2.0.5(typescript@5.2.2):
- resolution: {integrity: sha512-MLblEgykCPU8JmBSqQc4YLFlQWv856Ecky6jTZC5pKw+lirqUxkVvLGFHzX2r2tP0h6VzZZxmZWGHNKZofxWjA==}
- dependencies:
- '@nostr-dev-kit/ndk': 2.0.5(typescript@5.2.2)
- debug: 4.3.4
- dexie: 3.2.4
- nostr-tools: 1.17.0(typescript@5.2.2)
- typescript-lru-cache: 2.0.0
- transitivePeerDependencies:
- - supports-color
- - typescript
- dev: false
-
/@nostr-dev-kit/ndk@2.0.5(typescript@5.2.2):
resolution: {integrity: sha512-EvVr43y+4N9lMSZIIe5V8jFWYlKTVkMyyJfbgRaDGCGiBZAm9iy0wcO2Yi+W57awOAlvr3mjT5fAwG9RDb6HSA==}
dependencies:
@@ -1690,39 +1659,39 @@ packages:
'@babel/runtime': 7.23.2
dev: false
- /@reactflow/background@11.3.6(@types/react@18.2.37)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0):
+ /@reactflow/background@11.3.6(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-06FPlSUOOMALEEs+2PqPAbpqmL7WDjrkbG2UsDr2d6mbcDDhHiV4tu9FYoz44SQvXo7ma9VRotlsaR4OiRcYsg==}
peerDependencies:
react: '>=17'
react-dom: '>=17'
dependencies:
- '@reactflow/core': 11.10.1(@types/react@18.2.37)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0)
+ '@reactflow/core': 11.10.1(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
classcat: 5.0.4
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
- zustand: 4.4.6(@types/react@18.2.37)(immer@10.0.3)(react@18.2.0)
+ zustand: 4.4.6(@types/react@18.2.37)(react@18.2.0)
transitivePeerDependencies:
- '@types/react'
- immer
dev: false
- /@reactflow/controls@11.2.6(@types/react@18.2.37)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0):
+ /@reactflow/controls@11.2.6(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-4QHT92/ACVlZkvV+Hq44bAPV8WbMhkJl+/J0EbXcqQ1+an7cWJsF84eeelJw7R5J76RoaSSpKdsWsL2v7HAVlw==}
peerDependencies:
react: '>=17'
react-dom: '>=17'
dependencies:
- '@reactflow/core': 11.10.1(@types/react@18.2.37)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0)
+ '@reactflow/core': 11.10.1(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
classcat: 5.0.4
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
- zustand: 4.4.6(@types/react@18.2.37)(immer@10.0.3)(react@18.2.0)
+ zustand: 4.4.6(@types/react@18.2.37)(react@18.2.0)
transitivePeerDependencies:
- '@types/react'
- immer
dev: false
- /@reactflow/core@11.10.1(@types/react@18.2.37)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0):
+ /@reactflow/core@11.10.1(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-GIh3usY1W3eVobx//OO9+Cwm+5evQBBdPGxDaeXwm25UqPMWRI240nXQA5F/5gL5Mwpf0DUC7DR2EmrKNQy+Rw==}
peerDependencies:
react: '>=17'
@@ -1738,19 +1707,19 @@ packages:
d3-zoom: 3.0.0
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
- zustand: 4.4.6(@types/react@18.2.37)(immer@10.0.3)(react@18.2.0)
+ zustand: 4.4.6(@types/react@18.2.37)(react@18.2.0)
transitivePeerDependencies:
- '@types/react'
- immer
dev: false
- /@reactflow/minimap@11.7.6(@types/react@18.2.37)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0):
+ /@reactflow/minimap@11.7.6(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-kJEtyeQkTZYViLGebVWHVUJROMAGcvejvT+iX4DqKnFb5yK8E8LWlXQpRx2FrL9gDy80mJJaciy7IxnnQKE1bg==}
peerDependencies:
react: '>=17'
react-dom: '>=17'
dependencies:
- '@reactflow/core': 11.10.1(@types/react@18.2.37)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0)
+ '@reactflow/core': 11.10.1(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
'@types/d3-selection': 3.0.10
'@types/d3-zoom': 3.0.8
classcat: 5.0.4
@@ -1758,41 +1727,41 @@ packages:
d3-zoom: 3.0.0
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
- zustand: 4.4.6(@types/react@18.2.37)(immer@10.0.3)(react@18.2.0)
+ zustand: 4.4.6(@types/react@18.2.37)(react@18.2.0)
transitivePeerDependencies:
- '@types/react'
- immer
dev: false
- /@reactflow/node-resizer@2.2.6(@types/react@18.2.37)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0):
+ /@reactflow/node-resizer@2.2.6(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-1Xb6q97uP7hRBLpog9sRCNfnsHdDgFRGEiU+lQqGgPEAeYwl4nRjWa/sXwH6ajniKxBhGEvrdzOgEFn6CRMcpQ==}
peerDependencies:
react: '>=17'
react-dom: '>=17'
dependencies:
- '@reactflow/core': 11.10.1(@types/react@18.2.37)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0)
+ '@reactflow/core': 11.10.1(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
classcat: 5.0.4
d3-drag: 3.0.0
d3-selection: 3.0.0
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
- zustand: 4.4.6(@types/react@18.2.37)(immer@10.0.3)(react@18.2.0)
+ zustand: 4.4.6(@types/react@18.2.37)(react@18.2.0)
transitivePeerDependencies:
- '@types/react'
- immer
dev: false
- /@reactflow/node-toolbar@1.3.6(@types/react@18.2.37)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0):
+ /@reactflow/node-toolbar@1.3.6(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-JXDEuZ0wKjZ8z7qK2bIst0eZPzNyVEsiHL0e93EyuqT4fA9icoyE0fLq2ryNOOp7MXgId1h7LusnH6ta45F0yQ==}
peerDependencies:
react: '>=17'
react-dom: '>=17'
dependencies:
- '@reactflow/core': 11.10.1(@types/react@18.2.37)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0)
+ '@reactflow/core': 11.10.1(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
classcat: 5.0.4
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
- zustand: 4.4.6(@types/react@18.2.37)(immer@10.0.3)(react@18.2.0)
+ zustand: 4.4.6(@types/react@18.2.37)(react@18.2.0)
transitivePeerDependencies:
- '@types/react'
- immer
@@ -2000,32 +1969,6 @@ packages:
resolution: {integrity: sha512-Y0enatz2zQXBAsd7XmajlCs+WaitdR7dIFkqz9Xd7HL4KV04JOigWVreYseTmNH7YFSBSC/BJ9uuNp1MAf+GfA==}
dev: false
- /@tanstack/query-persist-client-core@5.8.1:
- resolution: {integrity: sha512-V7Nt1V3jTgoPt2l0/XgHAHyMrbGynx4Wzo8EGkDjxv8ih/jDQt8yMvyk99ZqvtU80ch1DCElqIM8n3CHcV/KrA==}
- dependencies:
- '@tanstack/query-core': 5.8.1
- dev: false
-
- /@tanstack/query-sync-storage-persister@5.8.1:
- resolution: {integrity: sha512-zzOgg9eFvXVUoJXEhVFYRjXlEd9KBjOoAE3uJUSFEDvL56T3jfPslOlc1W6yDM5H86k3NYZJYEDWO4v70kxCpQ==}
- dependencies:
- '@tanstack/query-core': 5.8.1
- '@tanstack/query-persist-client-core': 5.8.1
- dev: false
-
- /@tanstack/react-query-persist-client@5.8.1(@tanstack/react-query@5.8.1)(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-rH562Zgox1RBFu7UEaaBgNcJjETGeGwZa/T+pktul6aPdbCG0rTV6XBq0Uda227bTi4V1o/s3RLXKIBZs2j21A==}
- peerDependencies:
- '@tanstack/react-query': ^5.8.1
- react: ^18.0.0
- react-dom: ^18.0.0
- dependencies:
- '@tanstack/query-persist-client-core': 5.8.1
- '@tanstack/react-query': 5.8.1(react-dom@18.2.0)(react@18.2.0)
- react: 18.2.0
- react-dom: 18.2.0(react@18.2.0)
- dev: false
-
/@tanstack/react-query@5.8.1(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-YMagxS8iNPOLg0pK6WOjdSDlAvWKOf69udLOwQrBVmkC2SRLNLko7elo5Ro3ptlJkXvTVHidxC/h5KGi5bH1XQ==}
peerDependencies:
@@ -3271,12 +3214,6 @@ packages:
resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==}
engines: {node: '>=6'}
- /cobe@0.6.3:
- resolution: {integrity: sha512-WHr7X4o1ym94GZ96h7b1pNemZJacbOzd02dZtnVwuC4oWBaLg96PBmp2rIS1SAhUDhhC/QyS9WEqkpZIs/ZBTg==}
- dependencies:
- phenomenon: 1.6.0
- dev: false
-
/color-convert@1.9.3:
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
dependencies:
@@ -3490,19 +3427,10 @@ packages:
engines: {node: '>=6'}
dev: true
- /destr@2.0.2:
- resolution: {integrity: sha512-65AlobnZMiCET00KaFFjUefxDX0khFA/E4myqZ7a6Sq1yZtR8+FVIvilVX66vF2uobSumxooYZChiRPCKNqhmg==}
- dev: false
-
/detect-node-es@1.1.0:
resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
dev: false
- /dexie@3.2.4:
- resolution: {integrity: sha512-VKoTQRSv7+RnffpOJ3Dh6ozknBqzWw/F3iqMdsZg958R0AS8AnY9x9d1lbwENr0gzeGJHXKcGhAMRaqys6SxqA==}
- engines: {node: '>=6.0'}
- dev: false
-
/didyoumean@1.2.2:
resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
@@ -4256,10 +4184,6 @@ packages:
engines: {node: '>= 4'}
dev: true
- /immer@10.0.3:
- resolution: {integrity: sha512-pwupu3eWfouuaowscykeckFmVTpqbzW+rXFCX8rQLkZzM9ftBmU/++Ra+o+L27mz03zJTlyV4UUr+fdKNffo4A==}
- dev: false
-
/import-fresh@3.3.0:
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
engines: {node: '>=6'}
@@ -5021,10 +4945,6 @@ packages:
resolution: {integrity: sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==}
dev: false
- /phenomenon@1.6.0:
- resolution: {integrity: sha512-7h9/fjPD3qNlgggzm88cY58l9sudZ6Ey+UmZsizfhtawO6E3srZQXywaNm2lBwT72TbpHYRPy7ytIHeBUD/G0A==}
- dev: false
-
/picocolors@1.0.0:
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
@@ -5489,18 +5409,18 @@ packages:
loose-envify: 1.4.0
dev: false
- /reactflow@11.10.1(@types/react@18.2.37)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0):
+ /reactflow@11.10.1(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-Q616fElAc5/N37tMwjuRkkgm/VgmnLLTNNCj61z5mvJxae+/VXZQMfot1K6a5LLz9G3SVKqU97PMb9Ga1PRXew==}
peerDependencies:
react: '>=17'
react-dom: '>=17'
dependencies:
- '@reactflow/background': 11.3.6(@types/react@18.2.37)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0)
- '@reactflow/controls': 11.2.6(@types/react@18.2.37)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0)
- '@reactflow/core': 11.10.1(@types/react@18.2.37)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0)
- '@reactflow/minimap': 11.7.6(@types/react@18.2.37)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0)
- '@reactflow/node-resizer': 2.2.6(@types/react@18.2.37)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0)
- '@reactflow/node-toolbar': 1.3.6(@types/react@18.2.37)(immer@10.0.3)(react-dom@18.2.0)(react@18.2.0)
+ '@reactflow/background': 11.3.6(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
+ '@reactflow/controls': 11.2.6(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
+ '@reactflow/core': 11.10.1(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
+ '@reactflow/minimap': 11.7.6(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
+ '@reactflow/node-resizer': 2.2.6(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
+ '@reactflow/node-toolbar': 1.3.6(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
transitivePeerDependencies:
@@ -6339,7 +6259,7 @@ packages:
engines: {node: '>=10'}
dev: true
- /zustand@4.4.6(@types/react@18.2.37)(immer@10.0.3)(react@18.2.0):
+ /zustand@4.4.6(@types/react@18.2.37)(react@18.2.0):
resolution: {integrity: sha512-Rb16eW55gqL4W2XZpJh0fnrATxYEG3Apl2gfHTyDSE965x/zxslTikpNch0JgNjJA9zK6gEFW8Fl6d1rTZaqgg==}
engines: {node: '>=12.7.0'}
peerDependencies:
@@ -6355,7 +6275,6 @@ packages:
optional: true
dependencies:
'@types/react': 18.2.37
- immer: 10.0.3
react: 18.2.0
use-sync-external-store: 1.2.0(react@18.2.0)
dev: false
diff --git a/src/app.tsx b/src/app.tsx
index 409fa4da..57643ed3 100644
--- a/src/app.tsx
+++ b/src/app.tsx
@@ -1,4 +1,5 @@
import { message } from '@tauri-apps/plugin-dialog';
+import { fetch } from '@tauri-apps/plugin-http';
import { RouterProvider, createBrowserRouter, defer, redirect } from 'react-router-dom';
import { ReactFlowProvider } from 'reactflow';
diff --git a/src/app/auth/components/features/favoriteHashtag.tsx b/src/app/auth/components/features/favoriteHashtag.tsx
index 92dabd67..928d3c96 100644
--- a/src/app/auth/components/features/favoriteHashtag.tsx
+++ b/src/app/auth/components/features/favoriteHashtag.tsx
@@ -11,10 +11,10 @@ export function FavoriteHashtag() {
-
Favorite hashtag
+
Favorite topic
- By adding favorite hashtag, Lume will display all contents related to this
- hashtag as a column
+ By adding favorite topic, Lume will display all contents related to this topic
+ for you
{hashtag ? (
diff --git a/src/app/auth/onboarding/hashtag.tsx b/src/app/auth/onboarding/hashtag.tsx
index 789c3a90..b1df5f3d 100644
--- a/src/app/auth/onboarding/hashtag.tsx
+++ b/src/app/auth/onboarding/hashtag.tsx
@@ -4,33 +4,31 @@ import { useNavigate } from 'react-router-dom';
import { ArrowLeftIcon, CheckCircleIcon, LoaderIcon } from '@shared/icons';
-import { HASHTAGS } from '@stores/constants';
+import { TOPICS, WIDGET_KIND } from '@stores/constants';
import { useOnboarding } from '@stores/onboarding';
+import { useWidget } from '@utils/hooks/useWidget';
+
export function OnboardHashtagScreen() {
const [loading, setLoading] = useState(false);
- const [tags, setTags] = useState(new Set
());
+ const [topic, setTopic] = useState(null);
const navigate = useNavigate();
const setHashtag = useOnboarding((state) => state.toggleHashtag);
- const toggleTag = (tag: string) => {
- if (tags.has(tag)) {
- setTags((prev) => {
- prev.delete(tag);
- return new Set(prev);
- });
- } else {
- if (tags.size >= 3) return;
- setTags((prev) => new Set(prev.add(tag)));
- }
- };
+ const { addWidget } = useWidget();
const submit = async () => {
try {
setLoading(true);
-
setHashtag();
+
+ addWidget.mutate({
+ kind: WIDGET_KIND.topic,
+ title: topic.title,
+ content: JSON.stringify(topic.content),
+ });
+
navigate(-1);
} catch (e) {
setLoading(false);
@@ -53,19 +51,19 @@ export function OnboardHashtagScreen() {
- Choose {tags.size}/3 your favorite hashtag
+ Choose your favorite topic
-
- {HASHTAGS.map((item: { hashtag: string }) => (
+
+ {TOPICS.map((item) => (
toggleTag(item.hashtag)}
- className="inline-flex items-center justify-between px-4 py-2 hover:bg-neutral-300 dark:hover:bg-neutral-700"
+ onClick={() => setTopic(item)}
+ className="inline-flex h-14 items-center justify-between rounded-xl bg-neutral-100 px-4 hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800"
>
- {item.hashtag}
- {tags.has(item.hashtag) && (
+ {item.title}
+ {topic && topic.title === item.title && (
@@ -76,7 +74,7 @@ export function OnboardHashtagScreen() {
{loading ? (
@@ -85,7 +83,7 @@ export function OnboardHashtagScreen() {
Adding...
>
) : (
- Add {tags.size} tags & Continue
+ Add & Continue
)}
diff --git a/src/app/auth/onboarding/list.tsx b/src/app/auth/onboarding/list.tsx
index eee68853..76287728 100644
--- a/src/app/auth/onboarding/list.tsx
+++ b/src/app/auth/onboarding/list.tsx
@@ -31,7 +31,7 @@ export function OnboardingListScreen() {
-
+
You're almost ready to use Lume.
diff --git a/src/app/relays/components/relayEventList.tsx b/src/app/relays/components/relayEventList.tsx
index 12c764eb..4f360059 100644
--- a/src/app/relays/components/relayEventList.tsx
+++ b/src/app/relays/components/relayEventList.tsx
@@ -11,7 +11,7 @@ import { MemoizedRepost, MemoizedTextNote, UnknownNote } from '@shared/notes';
export function RelayEventList({ relayUrl }: { relayUrl: string }) {
const { fetcher } = useNDK();
const { status, data } = useQuery({
- queryKey: ['relay-event'],
+ queryKey: ['relay-events', relayUrl],
queryFn: async () => {
const url = 'wss://' + relayUrl;
const events = await fetcher.fetchLatestEvents(
@@ -42,7 +42,7 @@ export function RelayEventList({ relayUrl }: { relayUrl: string }) {
return (
-
+
{status === 'pending' ? (
@@ -51,13 +51,9 @@ export function RelayEventList({ relayUrl }: { relayUrl: string }) {
) : (
-
-
- {data.map((item) => renderItem(item))}
-
-
+ data.map((item) => renderItem(item))
)}
-
+
);
}
diff --git a/src/app/relays/components/relayList.tsx b/src/app/relays/components/relayList.tsx
index e92221e4..cc77ef51 100644
--- a/src/app/relays/components/relayList.tsx
+++ b/src/app/relays/components/relayList.tsx
@@ -56,7 +56,7 @@ export function RelayList() {
- All relays used by your follows
+ All relays
{[...data].map(([key, value]) => (
diff --git a/src/app/relays/components/userRelay.tsx b/src/app/relays/components/userRelay.tsx
index 9c8e97ea..eb901402 100644
--- a/src/app/relays/components/userRelay.tsx
+++ b/src/app/relays/components/userRelay.tsx
@@ -36,7 +36,7 @@ export function UserRelay() {
{data.map((item) => (
{relayUrls.includes(item) ? (
diff --git a/src/libs/ndk/instance.ts b/src/libs/ndk/instance.ts
index dfc0737e..d6ce4315 100644
--- a/src/libs/ndk/instance.ts
+++ b/src/libs/ndk/instance.ts
@@ -4,6 +4,7 @@ import { message } from '@tauri-apps/plugin-dialog';
import { fetch } from '@tauri-apps/plugin-http';
import { NostrFetcher } from 'nostr-fetch';
import { useEffect, useMemo, useState } from 'react';
+import { toast } from 'sonner';
import NDKCacheAdapterTauri from '@libs/ndk/cache';
import { useStorage } from '@libs/storage/provider';
@@ -36,11 +37,11 @@ export const NDKInstance = () => {
});
if (!res.ok) {
- console.info(`${relay} is not working, skipping...`);
+ toast.warning(`${relay} is not working, skipping...`);
onlineRelays.delete(relay);
}
} catch {
- console.warn(`${relay} is not working, skipping...`);
+ toast.warning(`${relay} is not working, skipping...`);
onlineRelays.delete(relay);
}
}
diff --git a/src/shared/notes/preview/image.tsx b/src/shared/notes/preview/image.tsx
index 640d67b7..1529910b 100644
--- a/src/shared/notes/preview/image.tsx
+++ b/src/shared/notes/preview/image.tsx
@@ -40,7 +40,7 @@ export function ImagePreview({ url }: { url: string }) {
decoding="async"
style={{ contentVisibility: 'auto' }}
onError={fallback}
- className="h-auto w-full rounded-lg border border-neutral-300/50 object-cover dark:border-neutral-700/50"
+ className="h-auto w-full rounded-lg border border-neutral-200/50 object-cover dark:border-neutral-800/50"
/>
-
+
+
diff --git a/src/shared/widgets/article.tsx b/src/shared/widgets/article.tsx
index 06163dd7..abacbbfd 100644
--- a/src/shared/widgets/article.tsx
+++ b/src/shared/widgets/article.tsx
@@ -21,7 +21,7 @@ export function ArticleWidget({ widget }: { widget: Widget }) {
const { ndk, relayUrls, fetcher } = useNDK();
const { status, data, hasNextPage, isFetchingNextPage, fetchNextPage } =
useInfiniteQuery({
- queryKey: ['widget-article'],
+ queryKey: ['article', widget.id],
initialPageParam: 0,
queryFn: async ({
signal,
diff --git a/src/shared/widgets/file.tsx b/src/shared/widgets/file.tsx
index a5e19e85..a64cf62d 100644
--- a/src/shared/widgets/file.tsx
+++ b/src/shared/widgets/file.tsx
@@ -21,7 +21,7 @@ export function FileWidget({ widget }: { widget: Widget }) {
const { ndk, relayUrls, fetcher } = useNDK();
const { status, data, hasNextPage, isFetchingNextPage, fetchNextPage } =
useInfiniteQuery({
- queryKey: ['widget-media'],
+ queryKey: ['media', widget.id],
initialPageParam: 0,
queryFn: async ({
signal,
diff --git a/src/shared/widgets/group.tsx b/src/shared/widgets/group.tsx
index 286390e1..bdc9cf0e 100644
--- a/src/shared/widgets/group.tsx
+++ b/src/shared/widgets/group.tsx
@@ -23,7 +23,7 @@ export function GroupWidget({ widget }: { widget: Widget }) {
const { relayUrls, ndk, fetcher } = useNDK();
const { status, data, hasNextPage, isFetchingNextPage, fetchNextPage } =
useInfiniteQuery({
- queryKey: [`widget-${widget.id}`],
+ queryKey: ['groupfeeds', widget.id],
initialPageParam: 0,
queryFn: async ({
signal,
diff --git a/src/shared/widgets/hashtag.tsx b/src/shared/widgets/hashtag.tsx
index d62760c2..cb9e8d9c 100644
--- a/src/shared/widgets/hashtag.tsx
+++ b/src/shared/widgets/hashtag.tsx
@@ -18,7 +18,7 @@ export function HashtagWidget({ widget }: { widget: Widget }) {
const { ndk, relayUrls, fetcher } = useNDK();
const { status, data, hasNextPage, isFetchingNextPage, fetchNextPage } =
useInfiniteQuery({
- queryKey: [`widget-${widget.content}`],
+ queryKey: ['hashtag', widget.id],
initialPageParam: 0,
queryFn: async ({
signal,
diff --git a/src/shared/widgets/nostrBand/trendingAccounts.tsx b/src/shared/widgets/nostrBand/trendingAccounts.tsx
index f8ea6f68..87cc8379 100644
--- a/src/shared/widgets/nostrBand/trendingAccounts.tsx
+++ b/src/shared/widgets/nostrBand/trendingAccounts.tsx
@@ -17,7 +17,7 @@ interface Response {
export function TrendingAccountsWidget({ widget }: { widget: Widget }) {
const { status, data } = useQuery({
- queryKey: ['trending-profiles-widget'],
+ queryKey: ['trending-users'],
queryFn: async () => {
const res = await fetch('https://api.nostr.band/v0/trending/profiles');
if (!res.ok) {
diff --git a/src/shared/widgets/nostrBand/trendingNotes.tsx b/src/shared/widgets/nostrBand/trendingNotes.tsx
index cee7970f..302d4220 100644
--- a/src/shared/widgets/nostrBand/trendingNotes.tsx
+++ b/src/shared/widgets/nostrBand/trendingNotes.tsx
@@ -15,7 +15,7 @@ interface Response {
export function TrendingNotesWidget({ widget }: { widget: Widget }) {
const { status, data } = useQuery({
- queryKey: ['widget-' + widget.id],
+ queryKey: ['trending-posts'],
queryFn: async () => {
const res = await fetch('https://api.nostr.band/v0/trending/notes');
if (!res.ok) {
diff --git a/src/shared/widgets/notification.tsx b/src/shared/widgets/notification.tsx
index e002f474..0139650c 100644
--- a/src/shared/widgets/notification.tsx
+++ b/src/shared/widgets/notification.tsx
@@ -148,9 +148,9 @@ export function NotificationWidget() {
) : allEvents.length < 1 ? (
-
-
🎉
-
+
+
🎉
+
Hmm! Nothing new yet.
diff --git a/src/shared/widgets/other/toggleWidgetList.tsx b/src/shared/widgets/other/toggleWidgetList.tsx
index dca0863f..81c4fe47 100644
--- a/src/shared/widgets/other/toggleWidgetList.tsx
+++ b/src/shared/widgets/other/toggleWidgetList.tsx
@@ -16,10 +16,9 @@ export function ToggleWidgetList() {
onClick={() =>
addWidget.mutate({ kind: WIDGET_KIND.list, title: '', content: '' })
}
- className="inline-flex h-9 items-center gap-2 rounded-full bg-neutral-100 px-3 text-neutral-900 hover:bg-neutral-200 dark:bg-neutral-900 dark:text-neutral-100 dark:hover:bg-neutral-800"
+ className="inline-flex h-14 w-14 items-center justify-center rounded-full bg-neutral-100 text-neutral-900 hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800"
>
-
-
Add widget
+
diff --git a/src/shared/widgets/tmp/feeds.tsx b/src/shared/widgets/tmp/feeds.tsx
deleted file mode 100644
index 9b5f0986..00000000
--- a/src/shared/widgets/tmp/feeds.tsx
+++ /dev/null
@@ -1,96 +0,0 @@
-import { useState } from 'react';
-
-import { useStorage } from '@libs/storage/provider';
-
-import { ArrowRightCircleIcon, CancelIcon, CheckCircleIcon } from '@shared/icons';
-import { User } from '@shared/user';
-import { WidgetWrapper } from '@shared/widgets';
-
-import { WIDGET_KIND } from '@stores/constants';
-
-import { useWidget } from '@utils/hooks/useWidget';
-import { Widget } from '@utils/types';
-
-export function XfeedsWidget({ params }: { params: Widget }) {
- const { db } = useStorage();
- const { addWidget, removeWidget } = useWidget();
-
- const [title, setTitle] = useState
('');
- const [groups, setGroups] = useState>([]);
-
- // toggle follow state
- const toggleGroup = (pubkey: string) => {
- const arr = groups.includes(pubkey)
- ? groups.filter((i) => i !== pubkey)
- : [...groups, pubkey];
- setGroups(arr);
- };
-
- const submit = async () => {
- addWidget.mutate({
- kind: WIDGET_KIND.group,
- title: title || 'Group',
- content: JSON.stringify(groups),
- });
- // remove temp widget
- removeWidget.mutate(params.id);
- };
-
- return (
-
-
-
-
- Adding group feeds
-
-
removeWidget.mutate(params.id)}
- className="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded text-neutral-900 backdrop-blur-xl hover:bg-neutral-100 dark:text-neutral-100 dark:hover:bg-neutral-900"
- >
-
-
-
-
-
-
setTitle(e.target.value)}
- placeholder="Group name"
- className="relative h-11 w-full rounded-lg bg-neutral-100 px-3 py-1 text-neutral-900 !outline-none placeholder:text-neutral-500 dark:bg-neutral-900 dark:text-neutral-100 dark:placeholder:text-neutral-300"
- />
-
-
- Add users {title ? 'to ' + title : ''}
-
- {db.account.circles.map((item: string) => (
-
toggleGroup(item)}
- className="inline-flex transform items-center justify-between px-4 py-2 hover:bg-neutral-100 dark:hover:bg-neutral-900"
- >
-
- {groups.includes(item) ? (
-
- ) : null}
-
- ))}
-
-
-
-
-
- Add {groups.length} user to group feed
-
-
-
-
-
- );
-}
diff --git a/src/shared/widgets/tmp/hashtag.tsx b/src/shared/widgets/tmp/hashtag.tsx
deleted file mode 100644
index 467b3dc9..00000000
--- a/src/shared/widgets/tmp/hashtag.tsx
+++ /dev/null
@@ -1,110 +0,0 @@
-import { Resolver, useForm } from 'react-hook-form';
-
-import { ArrowRightCircleIcon, CancelIcon } from '@shared/icons';
-import { WidgetWrapper } from '@shared/widgets';
-
-import { HASHTAGS, WIDGET_KIND } from '@stores/constants';
-
-import { useWidget } from '@utils/hooks/useWidget';
-import { Widget } from '@utils/types';
-
-type FormValues = {
- hashtag: string;
-};
-
-const resolver: Resolver = async (values) => {
- return {
- values: values.hashtag ? values : {},
- errors: !values.hashtag
- ? {
- hashtag: {
- type: 'required',
- message: 'This is required.',
- },
- }
- : {},
- };
-};
-
-export function XhashtagWidget({ params }: { params: Widget }) {
- const { addWidget, removeWidget } = useWidget();
- const {
- register,
- setValue,
- setError,
- handleSubmit,
- formState: { errors, isDirty, isValid },
- } = useForm({ resolver });
-
- const onSubmit = async (data: FormValues) => {
- try {
- addWidget.mutate({
- kind: WIDGET_KIND.hashtag,
- title: data.hashtag,
- content: data.hashtag.replace('#', ''),
- });
- // remove temp widget
- removeWidget.mutate(params.id);
- } catch (e) {
- setError('hashtag', {
- type: 'custom',
- message: e,
- });
- }
- };
-
- return (
-
-
-
-
- Adding hashtag feeds
-
-
removeWidget.mutate(params.id)}
- className="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded text-neutral-900 backdrop-blur-xl hover:bg-neutral-100 dark:text-neutral-100 dark:hover:bg-neutral-900"
- >
-
-
-
-
-
- );
-}
diff --git a/src/shared/widgets/topic.tsx b/src/shared/widgets/topic.tsx
index 18c030fd..d910fc2d 100644
--- a/src/shared/widgets/topic.tsx
+++ b/src/shared/widgets/topic.tsx
@@ -24,7 +24,7 @@ export function TopicWidget({ widget }: { widget: Widget }) {
const { relayUrls, ndk, fetcher } = useNDK();
const { status, data, hasNextPage, isFetchingNextPage, fetchNextPage } =
useInfiniteQuery({
- queryKey: ['widget-' + widget.id],
+ queryKey: ['topic', widget.id],
initialPageParam: 0,
queryFn: async ({
signal,
diff --git a/src/shared/widgets/user.tsx b/src/shared/widgets/user.tsx
index 6fdebc52..185107c6 100644
--- a/src/shared/widgets/user.tsx
+++ b/src/shared/widgets/user.tsx
@@ -21,7 +21,7 @@ import { Widget } from '@utils/types';
export function UserWidget({ widget }: { widget: Widget }) {
const { ndk } = useNDK();
const { status, data } = useQuery({
- queryKey: ['widget-' + widget.id],
+ queryKey: ['user-posts', widget.id],
queryFn: async () => {
const rootIds = new Set();
const dedupQueue = new Set();
diff --git a/src/stores/constants.ts b/src/stores/constants.ts
index e666a95f..2916b11d 100644
--- a/src/stores/constants.ts
+++ b/src/stores/constants.ts
@@ -102,6 +102,9 @@ export const TOPICS = [
'#thewitcher',
'#rogally',
'#rog',
+ '#indiegames',
+ '#indiedev',
+ '#gamedev',
],
},
{
@@ -136,6 +139,7 @@ export const TOPICS = [
'#amass',
'#bluray',
'#Blu_Ray',
+ '#taylor',
],
},
{
@@ -262,22 +266,23 @@ export const TOPICS = [
'#animestr',
'#anime',
'#manga',
- '#ntr',
'#otaku',
'#animeart',
'#animegirl',
'#cosplay',
- '#kawaii',
'#weeb',
'#onepiece',
'#demonslayer',
'#animeworld',
'#aot',
- '#hentai',
'#fanart',
- '#loli',
'#vocaloid',
'#vtuber',
+ '#fate',
+ '#hololive',
+ '#hololivemeet',
+ '#pixiv',
+ '#waifu',
],
},
{
@@ -292,6 +297,7 @@ export const TOPICS = [
'#sexy',
'#loli',
'#hentai',
+ '#ntr',
],
},
];
diff --git a/src/stores/resources.ts b/src/stores/resources.ts
deleted file mode 100644
index 2a9aec81..00000000
--- a/src/stores/resources.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import { create } from 'zustand';
-import { persist } from 'zustand/middleware';
-
-import { Resources } from '@utils/types';
-
-const DEFAULT_RESOURCES: Array = [
- {
- title: 'The Basics (provide by nostr.com)',
- data: [
- {
- id: 'naddr1qqxnzd3exsurgwfnxgcnjve5qgsym7p8qvs805ny3z3vausedzzwnwk27cfe67r69nrxpqe8w0urmegrqsqqqa283wgxe0',
- title: 'What is Nostr?',
- image: '',
- },
- {
- id: 'naddr1qqxnzd3exsurgwf48qcnvdfcqgsym7p8qvs805ny3z3vausedzzwnwk27cfe67r69nrxpqe8w0urmegrqsqqqa28cnv0yt',
- title: 'Understanding keys',
- image: '',
- },
- {
- id: 'naddr1qqxnzd3exsurgwfcxgcrzwfjqgsym7p8qvs805ny3z3vausedzzwnwk27cfe67r69nrxpqe8w0urmegrqsqqqa28uccw5e',
- title: "What's a client?",
- image: '',
- },
- {
- id: 'naddr1qqxnzd3exsurgwfexqersdp5qgsym7p8qvs805ny3z3vausedzzwnwk27cfe67r69nrxpqe8w0urmegrqsqqqa28jvlesq',
- title: 'What are relays?',
- image: '',
- },
- {
- id: 'naddr1qqxnzd3exsur2vpjxserjveeqgsym7p8qvs805ny3z3vausedzzwnwk27cfe67r69nrxpqe8w0urmegrqsqqqa28rqy7mx',
- title: 'What is an event?',
- image: '',
- },
- {
- id: 'naddr1qqxnzd3exsur2vp5xsmnywpnqgsym7p8qvs805ny3z3vausedzzwnwk27cfe67r69nrxpqe8w0urmegrqsqqqa28hxwx4e',
- title: 'How to help Nostr?',
- image: '',
- },
- ],
- },
- {
- title: 'Lume Tutorials',
- data: [],
- },
-];
-
-interface ResourceState {
- resources: Array;
- seens: Set;
- openResource: (id: string) => void;
-}
-
-export const useResources = create()(
- persist(
- (set) => ({
- resources: DEFAULT_RESOURCES,
- seens: new Set(),
- openResource: (id: string) => {
- set((state) => ({ seens: new Set(state.seens).add(id) }));
- },
- }),
- {
- name: 'resources',
- storage: {
- getItem: (name) => {
- const str = localStorage.getItem(name);
- return {
- state: {
- ...JSON.parse(str).state,
- seens: new Set(JSON.parse(str).state.seens),
- },
- };
- },
- setItem: (name, newValue) => {
- const str = JSON.stringify({
- state: {
- ...newValue.state,
- seens: Array.from(newValue.state.seens),
- },
- });
- localStorage.setItem(name, str);
- },
- removeItem: (name) => localStorage.removeItem(name),
- },
- }
- )
-);
diff --git a/src/utils/hooks/useRichContent.tsx b/src/utils/hooks/useRichContent.tsx
index 6132cdc5..681cd039 100644
--- a/src/utils/hooks/useRichContent.tsx
+++ b/src/utils/hooks/useRichContent.tsx
@@ -49,7 +49,7 @@ export function useRichContent(content: string, textmode: boolean = false) {
let videos: string[] = [];
let events: string[] = [];
- const text = content.replace(/\n\s*\n/g, '\n');
+ const text = content.replace(/\n+/g, '\n');
const words = text.split(/( |\n)/);
if (!textmode) {