diff --git a/package.json b/package.json
index ed70e4d2..b310f471 100644
--- a/package.json
+++ b/package.json
@@ -80,7 +80,6 @@
"react-hotkeys-hook": "^4.4.1",
"react-router-dom": "^6.20.1",
"react-string-replace": "^1.1.1",
- "reactflow": "^11.10.1",
"sonner": "^1.2.4",
"tauri-controls": "github:reyamir/tauri-controls",
"tippy.js": "^6.3.7",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index ffebbf17..aa7e38ce 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -191,9 +191,6 @@ dependencies:
react-string-replace:
specifier: ^1.1.1
version: 1.1.1
- reactflow:
- specifier: ^11.10.1
- version: 11.10.1(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0)
sonner:
specifier: ^1.2.4
version: 1.2.4(react-dom@18.2.0)(react@18.2.0)
@@ -1752,114 +1749,6 @@ packages:
'@babel/runtime': 7.23.5
dev: false
- /@reactflow/background@11.3.6(@types/react@18.2.42)(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.42)(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.7(@types/react@18.2.42)(react@18.2.0)
- transitivePeerDependencies:
- - '@types/react'
- - immer
- dev: false
-
- /@reactflow/controls@11.2.6(@types/react@18.2.42)(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.42)(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.7(@types/react@18.2.42)(react@18.2.0)
- transitivePeerDependencies:
- - '@types/react'
- - immer
- dev: false
-
- /@reactflow/core@11.10.1(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-GIh3usY1W3eVobx//OO9+Cwm+5evQBBdPGxDaeXwm25UqPMWRI240nXQA5F/5gL5Mwpf0DUC7DR2EmrKNQy+Rw==}
- peerDependencies:
- react: '>=17'
- react-dom: '>=17'
- dependencies:
- '@types/d3': 7.4.3
- '@types/d3-drag': 3.0.7
- '@types/d3-selection': 3.0.10
- '@types/d3-zoom': 3.0.8
- classcat: 5.0.4
- d3-drag: 3.0.0
- d3-selection: 3.0.0
- d3-zoom: 3.0.0
- react: 18.2.0
- react-dom: 18.2.0(react@18.2.0)
- zustand: 4.4.7(@types/react@18.2.42)(react@18.2.0)
- transitivePeerDependencies:
- - '@types/react'
- - immer
- dev: false
-
- /@reactflow/minimap@11.7.6(@types/react@18.2.42)(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.42)(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
- d3-selection: 3.0.0
- d3-zoom: 3.0.0
- react: 18.2.0
- react-dom: 18.2.0(react@18.2.0)
- zustand: 4.4.7(@types/react@18.2.42)(react@18.2.0)
- transitivePeerDependencies:
- - '@types/react'
- - immer
- dev: false
-
- /@reactflow/node-resizer@2.2.6(@types/react@18.2.42)(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.42)(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.7(@types/react@18.2.42)(react@18.2.0)
- transitivePeerDependencies:
- - '@types/react'
- - immer
- dev: false
-
- /@reactflow/node-toolbar@1.3.6(@types/react@18.2.42)(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.42)(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.7(@types/react@18.2.42)(react@18.2.0)
- transitivePeerDependencies:
- - '@types/react'
- - immer
- dev: false
-
/@remirror/core-constants@2.0.2:
resolution: {integrity: sha512-dyHY+sMF0ihPus3O27ODd4+agdHMEmuRdyiZJ2CCWjPV5UFmn17ZbElvk6WOGVE4rdCJKZQCrPV2BcikOMLUGQ==}
dev: false
@@ -2598,189 +2487,6 @@ packages:
- supports-color
dev: true
- /@types/d3-array@3.2.1:
- resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==}
- dev: false
-
- /@types/d3-axis@3.0.6:
- resolution: {integrity: sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==}
- dependencies:
- '@types/d3-selection': 3.0.10
- dev: false
-
- /@types/d3-brush@3.0.6:
- resolution: {integrity: sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==}
- dependencies:
- '@types/d3-selection': 3.0.10
- dev: false
-
- /@types/d3-chord@3.0.6:
- resolution: {integrity: sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==}
- dev: false
-
- /@types/d3-color@3.1.3:
- resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==}
- dev: false
-
- /@types/d3-contour@3.0.6:
- resolution: {integrity: sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==}
- dependencies:
- '@types/d3-array': 3.2.1
- '@types/geojson': 7946.0.13
- dev: false
-
- /@types/d3-delaunay@6.0.4:
- resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==}
- dev: false
-
- /@types/d3-dispatch@3.0.6:
- resolution: {integrity: sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==}
- dev: false
-
- /@types/d3-drag@3.0.7:
- resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==}
- dependencies:
- '@types/d3-selection': 3.0.10
- dev: false
-
- /@types/d3-dsv@3.0.7:
- resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==}
- dev: false
-
- /@types/d3-ease@3.0.2:
- resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==}
- dev: false
-
- /@types/d3-fetch@3.0.7:
- resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==}
- dependencies:
- '@types/d3-dsv': 3.0.7
- dev: false
-
- /@types/d3-force@3.0.9:
- resolution: {integrity: sha512-IKtvyFdb4Q0LWna6ymywQsEYjK/94SGhPrMfEr1TIc5OBeziTi+1jcCvttts8e0UWZIxpasjnQk9MNk/3iS+kA==}
- dev: false
-
- /@types/d3-format@3.0.4:
- resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==}
- dev: false
-
- /@types/d3-geo@3.1.0:
- resolution: {integrity: sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==}
- dependencies:
- '@types/geojson': 7946.0.13
- dev: false
-
- /@types/d3-hierarchy@3.1.6:
- resolution: {integrity: sha512-qlmD/8aMk5xGorUvTUWHCiumvgaUXYldYjNVOWtYoTYY/L+WwIEAmJxUmTgr9LoGNG0PPAOmqMDJVDPc7DOpPw==}
- dev: false
-
- /@types/d3-interpolate@3.0.4:
- resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==}
- dependencies:
- '@types/d3-color': 3.1.3
- dev: false
-
- /@types/d3-path@3.0.2:
- resolution: {integrity: sha512-WAIEVlOCdd/NKRYTsqCpOMHQHemKBEINf8YXMYOtXH0GA7SY0dqMB78P3Uhgfy+4X+/Mlw2wDtlETkN6kQUCMA==}
- dev: false
-
- /@types/d3-polygon@3.0.2:
- resolution: {integrity: sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==}
- dev: false
-
- /@types/d3-quadtree@3.0.6:
- resolution: {integrity: sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==}
- dev: false
-
- /@types/d3-random@3.0.3:
- resolution: {integrity: sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==}
- dev: false
-
- /@types/d3-scale-chromatic@3.0.3:
- resolution: {integrity: sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==}
- dev: false
-
- /@types/d3-scale@4.0.8:
- resolution: {integrity: sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==}
- dependencies:
- '@types/d3-time': 3.0.3
- dev: false
-
- /@types/d3-selection@3.0.10:
- resolution: {integrity: sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg==}
- dev: false
-
- /@types/d3-shape@3.1.6:
- resolution: {integrity: sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==}
- dependencies:
- '@types/d3-path': 3.0.2
- dev: false
-
- /@types/d3-time-format@4.0.3:
- resolution: {integrity: sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==}
- dev: false
-
- /@types/d3-time@3.0.3:
- resolution: {integrity: sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==}
- dev: false
-
- /@types/d3-timer@3.0.2:
- resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==}
- dev: false
-
- /@types/d3-transition@3.0.8:
- resolution: {integrity: sha512-ew63aJfQ/ms7QQ4X7pk5NxQ9fZH/z+i24ZfJ6tJSfqxJMrYLiK01EAs2/Rtw/JreGUsS3pLPNV644qXFGnoZNQ==}
- dependencies:
- '@types/d3-selection': 3.0.10
- dev: false
-
- /@types/d3-zoom@3.0.8:
- resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==}
- dependencies:
- '@types/d3-interpolate': 3.0.4
- '@types/d3-selection': 3.0.10
- dev: false
-
- /@types/d3@7.4.3:
- resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==}
- dependencies:
- '@types/d3-array': 3.2.1
- '@types/d3-axis': 3.0.6
- '@types/d3-brush': 3.0.6
- '@types/d3-chord': 3.0.6
- '@types/d3-color': 3.1.3
- '@types/d3-contour': 3.0.6
- '@types/d3-delaunay': 6.0.4
- '@types/d3-dispatch': 3.0.6
- '@types/d3-drag': 3.0.7
- '@types/d3-dsv': 3.0.7
- '@types/d3-ease': 3.0.2
- '@types/d3-fetch': 3.0.7
- '@types/d3-force': 3.0.9
- '@types/d3-format': 3.0.4
- '@types/d3-geo': 3.1.0
- '@types/d3-hierarchy': 3.1.6
- '@types/d3-interpolate': 3.0.4
- '@types/d3-path': 3.0.2
- '@types/d3-polygon': 3.0.2
- '@types/d3-quadtree': 3.0.6
- '@types/d3-random': 3.0.3
- '@types/d3-scale': 4.0.8
- '@types/d3-scale-chromatic': 3.0.3
- '@types/d3-selection': 3.0.10
- '@types/d3-shape': 3.1.6
- '@types/d3-time': 3.0.3
- '@types/d3-time-format': 4.0.3
- '@types/d3-timer': 3.0.2
- '@types/d3-transition': 3.0.8
- '@types/d3-zoom': 3.0.8
- dev: false
-
- /@types/geojson@7946.0.13:
- resolution: {integrity: sha512-bmrNrgKMOhM3WsafmbGmC+6dsF2Z308vLFsQ3a/bT8X8Sv5clVYpPars/UPq+sAaJP+5OoLAYgwbkS5QEJdLUQ==}
- dev: false
-
/@types/html-to-text@9.0.4:
resolution: {integrity: sha512-pUY3cKH/Nm2yYrEmDlPR1mR7yszjGx4DrwPjQ702C4/D5CwHuZTgZdIdwPkRbcuhs7BAh2L5rg3CL5cbRiGTCQ==}
dev: true
@@ -3307,10 +3013,6 @@ packages:
fsevents: 2.3.3
dev: true
- /classcat@5.0.4:
- resolution: {integrity: sha512-sbpkOw6z413p+HDGcBENe498WM9woqWHiJxCq7nvmxe9WmrUmqfAcxpIwAiMtM5Q3AhYkzXcNQHqsWq0mND51g==}
- dev: false
-
/cli-cursor@4.0.0:
resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -3403,71 +3105,6 @@ packages:
/csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
- /d3-color@3.1.0:
- resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==}
- engines: {node: '>=12'}
- dev: false
-
- /d3-dispatch@3.0.1:
- resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==}
- engines: {node: '>=12'}
- dev: false
-
- /d3-drag@3.0.0:
- resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==}
- engines: {node: '>=12'}
- dependencies:
- d3-dispatch: 3.0.1
- d3-selection: 3.0.0
- dev: false
-
- /d3-ease@3.0.1:
- resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==}
- engines: {node: '>=12'}
- dev: false
-
- /d3-interpolate@3.0.1:
- resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==}
- engines: {node: '>=12'}
- dependencies:
- d3-color: 3.1.0
- dev: false
-
- /d3-selection@3.0.0:
- resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==}
- engines: {node: '>=12'}
- dev: false
-
- /d3-timer@3.0.1:
- resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==}
- engines: {node: '>=12'}
- dev: false
-
- /d3-transition@3.0.1(d3-selection@3.0.0):
- resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==}
- engines: {node: '>=12'}
- peerDependencies:
- d3-selection: 2 - 3
- dependencies:
- d3-color: 3.1.0
- d3-dispatch: 3.0.1
- d3-ease: 3.0.1
- d3-interpolate: 3.0.1
- d3-selection: 3.0.0
- d3-timer: 3.0.1
- dev: false
-
- /d3-zoom@3.0.0:
- resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==}
- engines: {node: '>=12'}
- dependencies:
- d3-dispatch: 3.0.1
- d3-drag: 3.0.0
- d3-interpolate: 3.0.1
- d3-selection: 3.0.0
- d3-transition: 3.0.1(d3-selection@3.0.0)
- dev: false
-
/d@1.0.1:
resolution: {integrity: sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==}
dependencies:
@@ -5585,25 +5222,6 @@ packages:
loose-envify: 1.4.0
dev: false
- /reactflow@11.10.1(@types/react@18.2.42)(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.42)(react-dom@18.2.0)(react@18.2.0)
- '@reactflow/controls': 11.2.6(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0)
- '@reactflow/core': 11.10.1(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0)
- '@reactflow/minimap': 11.7.6(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0)
- '@reactflow/node-resizer': 2.2.6(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0)
- '@reactflow/node-toolbar': 1.3.6(@types/react@18.2.42)(react-dom@18.2.0)(react@18.2.0)
- react: 18.2.0
- react-dom: 18.2.0(react@18.2.0)
- transitivePeerDependencies:
- - '@types/react'
- - immer
- dev: false
-
/read-cache@1.0.0:
resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
dependencies:
diff --git a/src/app.css b/src/app.css
index 69801706..fac2b4d3 100644
--- a/src/app.css
+++ b/src/app.css
@@ -1,5 +1,3 @@
-/* @import 'reactflow/dist/style.css'; */
-
/* Vidstack */
@import '@vidstack/react/player/styles/default/theme.css';
@import '@vidstack/react/player/styles/default/layouts/video.css';
diff --git a/src/app.tsx b/src/app.tsx
index f5cbc78b..3165aa5b 100644
--- a/src/app.tsx
+++ b/src/app.tsx
@@ -1,11 +1,9 @@
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';
import { ChatsScreen } from '@app/chats';
import { ErrorScreen } from '@app/error';
-import { ExploreScreen } from '@app/explore';
import { useArk } from '@libs/ark';
@@ -87,15 +85,6 @@ export default function App() {
return { Component: RelayScreen };
},
},
- {
- path: 'explore',
- element: (
-
-
-
- ),
- errorElement: ,
- },
{
path: 'chats',
element: ,
diff --git a/src/app/chats/chat.tsx b/src/app/chats/chat.tsx
index 5f66f3d8..a6bccbbb 100644
--- a/src/app/chats/chat.tsx
+++ b/src/app/chats/chat.tsx
@@ -12,16 +12,13 @@ import { useArk } from '@libs/ark';
import { LoaderIcon } from '@shared/icons';
import { User } from '@shared/user';
-import { useNostr } from '@utils/hooks/useNostr';
-
export function ChatScreen() {
const { ark } = useArk();
const { pubkey } = useParams();
- const { fetchNIP04Messages } = useNostr();
const { status, data } = useQuery({
queryKey: ['nip04-dm', pubkey],
queryFn: async () => {
- return await fetchNIP04Messages(pubkey);
+ return await ark.getAllMessagesByPubkey({ pubkey });
},
refetchOnWindowFocus: false,
});
diff --git a/src/app/chats/index.tsx b/src/app/chats/index.tsx
index 67698c9a..700360c8 100644
--- a/src/app/chats/index.tsx
+++ b/src/app/chats/index.tsx
@@ -5,16 +5,16 @@ import { Outlet } from 'react-router-dom';
import { ChatListItem } from '@app/chats/components/chatListItem';
+import { useArk } from '@libs/ark';
+
import { LoaderIcon } from '@shared/icons';
-import { useNostr } from '@utils/hooks/useNostr';
-
export function ChatsScreen() {
- const { getAllNIP04Chats } = useNostr();
+ const { ark } = useArk();
const { status, data } = useQuery({
queryKey: ['nip04-chats'],
queryFn: async () => {
- return await getAllNIP04Chats();
+ return await ark.getAllChats();
},
refetchOnWindowFocus: false,
refetchOnMount: false,
diff --git a/src/app/explore/components/edge.tsx b/src/app/explore/components/edge.tsx
deleted file mode 100644
index 296996b1..00000000
--- a/src/app/explore/components/edge.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { BaseEdge, EdgeProps, getBezierPath } from 'reactflow';
-
-export function Edge({
- sourceX,
- sourceY,
- targetX,
- targetY,
- sourcePosition,
- targetPosition,
- style = {},
- markerEnd,
-}: EdgeProps) {
- const [edgePath] = getBezierPath({
- sourceX,
- sourceY,
- sourcePosition,
- targetX,
- targetY,
- targetPosition,
- });
-
- return (
-
- );
-}
diff --git a/src/app/explore/components/groupTitle.tsx b/src/app/explore/components/groupTitle.tsx
deleted file mode 100644
index 14828d7f..00000000
--- a/src/app/explore/components/groupTitle.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import { memo } from 'react';
-
-import { useProfile } from '@utils/hooks/useProfile';
-
-export const GroupTitle = memo(function GroupTitle({ pubkey }: { pubkey: string }) {
- const { isLoading, user } = useProfile(pubkey);
-
- if (isLoading) {
- return
;
- }
-
- return (
- {`${
- user.name || user.display_name
- }'s network`}
- );
-});
diff --git a/src/app/explore/components/line.tsx b/src/app/explore/components/line.tsx
deleted file mode 100644
index 993667c7..00000000
--- a/src/app/explore/components/line.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-export function Line({ fromX, fromY, toX, toY }) {
- return (
-
-
-
-
- );
-}
diff --git a/src/app/explore/components/userGroupNode.tsx b/src/app/explore/components/userGroupNode.tsx
deleted file mode 100644
index 0356d291..00000000
--- a/src/app/explore/components/userGroupNode.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import { Handle, Position } from 'reactflow';
-
-import { UserWithDrawer } from '@app/explore/components/userWithDrawer';
-
-import { GroupTitle } from './groupTitle';
-
-export function UserGroupNode({ data }) {
- return (
- <>
-
-
- {data.title ? (
-
{data.title}
- ) : (
-
- )}
-
- {data.list.map((user: string) => (
-
- ))}
-
-
-
- >
- );
-}
diff --git a/src/app/explore/components/userLatestPosts.tsx b/src/app/explore/components/userLatestPosts.tsx
deleted file mode 100644
index 05a0d9fb..00000000
--- a/src/app/explore/components/userLatestPosts.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk';
-import { useQuery } from '@tanstack/react-query';
-import { useCallback } from 'react';
-
-import { LoaderIcon } from '@shared/icons';
-import { MemoizedRepost, MemoizedTextNote, UnknownNote } from '@shared/notes';
-
-import { useNostr } from '@utils/hooks/useNostr';
-
-export function UserLatestPosts({ pubkey }: { pubkey: string }) {
- const { getEventsByPubkey } = useNostr();
- const { status, data } = useQuery({
- queryKey: ['user-posts', pubkey],
- queryFn: async () => {
- return await getEventsByPubkey(pubkey);
- },
- refetchOnWindowFocus: false,
- });
-
- const renderItem = useCallback(
- (event: NDKEvent) => {
- switch (event.kind) {
- case NDKKind.Text:
- return ;
- case NDKKind.Repost:
- return ;
- default:
- return ;
- }
- },
- [data]
- );
-
- return (
-
-
- Latest post
-
-
- {status === 'pending' ? (
-
-
-
- Loading latest posts...
-
-
- ) : data.length < 1 ? (
-
-
- No posts from 24 hours ago
-
-
- ) : (
- data.map((event) => renderItem(event))
- )}
-
-
- );
-}
diff --git a/src/app/explore/components/userNode.tsx b/src/app/explore/components/userNode.tsx
deleted file mode 100644
index 0f5af72e..00000000
--- a/src/app/explore/components/userNode.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { Handle, Position } from 'reactflow';
-
-import { User } from '@shared/user';
-
-export function UserNode({ data }) {
- return (
- <>
-
-
- >
- );
-}
diff --git a/src/app/explore/components/userWithDrawer.tsx b/src/app/explore/components/userWithDrawer.tsx
deleted file mode 100644
index f498b70b..00000000
--- a/src/app/explore/components/userWithDrawer.tsx
+++ /dev/null
@@ -1,155 +0,0 @@
-import { NDKEvent, NDKKind, NDKUser } from '@nostr-dev-kit/ndk';
-import * as Dialog from '@radix-ui/react-dialog';
-import { memo, useEffect, useState } from 'react';
-import { Link } from 'react-router-dom';
-import { toast } from 'sonner';
-
-import { useNDK } from '@libs/ndk/provider';
-import { useStorage } from '@libs/storage/provider';
-
-import { NIP05 } from '@shared/nip05';
-import { TextNote } from '@shared/notes';
-import { User } from '@shared/user';
-
-import { useProfile } from '@utils/hooks/useProfile';
-import { displayNpub } from '@utils/shortenKey';
-
-import { UserLatestPosts } from './userLatestPosts';
-
-export const UserWithDrawer = memo(function UserWithDrawer({
- pubkey,
-}: {
- pubkey: string;
-}) {
- const { db } = useStorage();
- const { ndk } = useNDK();
- const { isLoading, user } = useProfile(pubkey);
-
- const [followed, setFollowed] = useState(false);
-
- const follow = async (pubkey: string) => {
- try {
- const user = ndk.getUser({ pubkey: db.account.pubkey });
- const contacts = await user.follows();
- const add = await user.follow(new NDKUser({ pubkey: pubkey }), contacts);
-
- if (add) {
- setFollowed(true);
- } else {
- toast('You already follow this user');
- }
- } catch (error) {
- console.log(error);
- }
- };
-
- const unfollow = async (pubkey: string) => {
- try {
- const user = ndk.getUser({ pubkey: db.account.pubkey });
- const contacts = await user.follows();
- contacts.delete(new NDKUser({ pubkey: pubkey }));
-
- let list: string[][];
- contacts.forEach((el) => list.push(['p', el.pubkey, el.relayUrls?.[0] || '', '']));
-
- const event = new NDKEvent(ndk);
- event.content = '';
- event.kind = NDKKind.Contacts;
- event.tags = list;
-
- const publishedRelays = await event.publish();
- if (publishedRelays) {
- setFollowed(false);
- }
- } catch (error) {
- console.log(error);
- }
- };
-
- useEffect(() => {
- if (db.account.contacts.includes(pubkey)) {
- setFollowed(true);
- }
- }, []);
-
- return (
-
-
-
-
-
-
-
- {isLoading ? (
-
- ) : (
- <>
-
-
-
-
-
-
- {user?.name || user?.display_name || user?.displayName}
-
- {user?.nip05 ? (
-
- ) : (
-
- {displayNpub(pubkey, 16)}
-
- )}
-
- {user?.about ?
: null}
-
-
- {followed ? (
-
- ) : (
-
- )}
-
- Message
-
-
-
-
-
- >
- )}
-
-
-
-
- );
-});
diff --git a/src/app/explore/index.tsx b/src/app/explore/index.tsx
deleted file mode 100644
index 2ec9400d..00000000
--- a/src/app/explore/index.tsx
+++ /dev/null
@@ -1,116 +0,0 @@
-import { useCallback, useMemo, useRef } from 'react';
-import ReactFlow, {
- Background,
- ConnectionMode,
- addEdge,
- useEdgesState,
- useNodesState,
- useReactFlow,
-} from 'reactflow';
-
-import { Edge } from '@app/explore/components/edge';
-import { Line } from '@app/explore/components/line';
-import { UserGroupNode } from '@app/explore/components/userGroupNode';
-import { UserNode } from '@app/explore/components/userNode';
-
-import { useStorage } from '@libs/storage/provider';
-
-import { useNostr } from '@utils/hooks/useNostr';
-import { getMultipleRandom } from '@utils/transform';
-
-let id = 2;
-const getId = () => `${id++}`;
-const nodeTypes = { user: UserNode, userGroup: UserGroupNode };
-const edgeTypes = { buttonedge: Edge };
-
-export function ExploreScreen() {
- const { db } = useStorage();
- const { getContactsByPubkey } = useNostr();
- const { project } = useReactFlow();
-
- const defaultContacts = useMemo(() => getMultipleRandom(db.account.contacts, 10), []);
- const reactFlowWrapper = useRef(null);
- const connectingNodeId = useRef(null);
-
- const initialNodes = [
- {
- id: '0',
- type: 'user',
- position: { x: 141, y: 0 },
- data: { list: [], title: '', pubkey: db.account.pubkey },
- },
- {
- id: '1',
- type: 'userGroup',
- position: { x: 0, y: 200 },
- data: { list: defaultContacts, title: 'Starting Point', pubkey: '' },
- },
- ];
- const initialEdges = [{ id: 'e0-1', type: 'buttonedge', source: '0', target: '1' }];
-
- const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
- const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
-
- const onConnect = useCallback((params) => setEdges((eds) => addEdge(params, eds)), []);
-
- const onConnectStart = useCallback((_, { nodeId }) => {
- connectingNodeId.current = nodeId;
- }, []);
-
- const onConnectEnd = useCallback(
- async (event) => {
- const targetIsPane = event.target.classList.contains('react-flow__pane');
-
- if (targetIsPane) {
- const { top, left } = reactFlowWrapper.current.getBoundingClientRect();
-
- const id = getId();
- const prevData = nodes.slice(-1)[0];
- const randomPubkey = getMultipleRandom(prevData.data.list, 1)[0];
-
- const newContactList = await getContactsByPubkey(randomPubkey);
- const newNode = {
- id,
- type: 'userGroup',
- position: project({ x: event.clientX - left, y: event.clientY - top }),
- data: { list: newContactList, title: null, pubkey: randomPubkey },
- };
-
- setNodes((nds) => nds.concat(newNode));
- setEdges((eds) =>
- eds.concat({
- id,
- type: 'buttonedge',
- source: connectingNodeId.current,
- target: id,
- })
- );
- }
- },
- [project]
- );
-
- return (
-
-
-
-
-
- );
-}
diff --git a/src/libs/ark/ark.ts b/src/libs/ark/ark.ts
index 49290dd7..27d316cb 100644
--- a/src/libs/ark/ark.ts
+++ b/src/libs/ark/ark.ts
@@ -50,9 +50,15 @@ export class Ark {
hashtag: boolean;
};
- constructor({ storage }: { storage: Database }) {
+ constructor({ storage, platform }: { storage: Database; platform: Platform }) {
this.#storage = storage;
- this.#init();
+ this.platform = platform;
+ this.settings = {
+ autoupdate: false,
+ outbox: false,
+ media: true,
+ hashtag: true,
+ };
}
async #keyring_save(key: string, value: string) {
@@ -74,10 +80,8 @@ export class Ark {
}
async #initNostrSigner({ nsecbunker }: { nsecbunker?: boolean }) {
- if (!this.account) {
- this.readyToSign = false;
- return null;
- }
+ const account = await this.getActiveAccount();
+ this.account = account;
try {
// NIP-46 Signer
@@ -128,7 +132,7 @@ export class Ark {
}
}
- async #init() {
+ public async init() {
const outboxSetting = await this.getSettingValue('outbox');
const bunkerSetting = await this.getSettingValue('nsecbunker');
@@ -178,6 +182,7 @@ export class Ark {
this.account.contacts = [...contacts].map((user) => user.pubkey);
}
+ this.relays = [...ndk.pool.relays.values()].map((relay) => relay.url);
this.#ndk = ndk;
this.#fetcher = fetcher;
}
@@ -214,10 +219,8 @@ export class Ark {
);
if (results.length) {
- this.account = results[0];
- this.account.contacts = [];
+ return results[0];
} else {
- console.log('no active account, please create new account');
return null;
}
}
@@ -766,6 +769,72 @@ export class Ark {
return false;
}
+ /**
+ * Return all NIP-04 messages
+ * @deprecated NIP-04 will be replace by NIP-44 in the next update
+ */
+ public async getAllChats() {
+ const events = await this.#fetcher.fetchAllEvents(
+ this.relays,
+ {
+ kinds: [NDKKind.EncryptedDirectMessage],
+ '#p': [this.account.pubkey],
+ },
+ { since: 0 }
+ );
+
+ const dedup: NDKEvent[] = Object.values(
+ events.reduce((ev, { id, content, pubkey, created_at, tags }) => {
+ if (ev[pubkey]) {
+ if (ev[pubkey].created_at < created_at) {
+ ev[pubkey] = { id, content, pubkey, created_at, tags };
+ }
+ } else {
+ ev[pubkey] = { id, content, pubkey, created_at, tags };
+ }
+ return ev;
+ }, {})
+ );
+
+ return dedup;
+ }
+
+ /**
+ * Return all NIP-04 messages by pubkey
+ * @deprecated NIP-04 will be replace by NIP-44 in the next update
+ */
+ public async getAllMessagesByPubkey({ pubkey }: { pubkey: string }) {
+ let senderMessages: NostrEventExt[] = [];
+
+ if (pubkey !== this.account.pubkey) {
+ senderMessages = await this.#fetcher.fetchAllEvents(
+ this.relays,
+ {
+ kinds: [NDKKind.EncryptedDirectMessage],
+ authors: [pubkey],
+ '#p': [this.account.pubkey],
+ },
+ { since: 0 }
+ );
+ }
+
+ const userMessages = await this.#fetcher.fetchAllEvents(
+ this.relays,
+ {
+ kinds: [NDKKind.EncryptedDirectMessage],
+ authors: [this.account.pubkey],
+ '#p': [pubkey],
+ },
+ { since: 0 }
+ );
+
+ const all = [...senderMessages, ...userMessages].sort(
+ (a, b) => a.created_at - b.created_at
+ );
+
+ return all as unknown as NDKEvent[];
+ }
+
public async nip04Decrypt({ event }: { event: NDKEvent }) {
try {
const sender = new NDKUser({
diff --git a/src/libs/ark/provider.tsx b/src/libs/ark/provider.tsx
index 6f1290fa..4e3ecc4a 100644
--- a/src/libs/ark/provider.tsx
+++ b/src/libs/ark/provider.tsx
@@ -1,4 +1,5 @@
import { ask } from '@tauri-apps/plugin-dialog';
+import { platform } from '@tauri-apps/plugin-os';
import { relaunch } from '@tauri-apps/plugin-process';
import Database from '@tauri-apps/plugin-sql';
import { check } from '@tauri-apps/plugin-updater';
@@ -26,9 +27,10 @@ const ArkProvider = ({ children }: PropsWithChildren