From d8dfc962c11dc8f7db120f2522d8dc63971da84a Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Tue, 21 Nov 2023 09:56:50 +0200 Subject: [PATCH 01/66] lazy load Notifications page --- packages/app/src/Pages/DeckLayout.tsx | 5 +++-- packages/app/src/index.tsx | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/app/src/Pages/DeckLayout.tsx b/packages/app/src/Pages/DeckLayout.tsx index 3b7c59f5..6b957664 100644 --- a/packages/app/src/Pages/DeckLayout.tsx +++ b/packages/app/src/Pages/DeckLayout.tsx @@ -1,5 +1,5 @@ import "./Deck.css"; -import { CSSProperties, createContext, useContext, useEffect, useState } from "react"; +import { CSSProperties, createContext, useContext, useEffect, useState, lazy } from "react"; import { Outlet, useNavigate } from "react-router-dom"; import { FormattedMessage } from "react-intl"; import { NostrLink, TaggedNostrEvent } from "@snort/system"; @@ -12,7 +12,6 @@ import Articles from "@/Element/Deck/Articles"; import TimelineFollows from "@/Element/Feed/TimelineFollows"; import { transformTextCached } from "@/Hooks/useTextTransformCache"; import Icon from "@/Icons/Icon"; -import NotificationsPage from "./Notifications"; import useImgProxy from "@/Hooks/useImgProxy"; import Modal from "@/Element/Modal"; import { Thread } from "@/Element/Event/Thread"; @@ -23,6 +22,8 @@ import Toaster from "@/Toaster"; import useLogin from "@/Hooks/useLogin"; import { LongFormText } from "@/Element/Event/LongFormText"; +const NotificationsPage = lazy(() => import("@/Pages/Notifications")); + type Cols = "notes" | "articles" | "media" | "streams" | "notifications"; interface DeckState { diff --git a/packages/app/src/index.tsx b/packages/app/src/index.tsx index b3696b87..05db901b 100644 --- a/packages/app/src/index.tsx +++ b/packages/app/src/index.tsx @@ -28,6 +28,7 @@ import { removeUndefined, throwIfOffline } from "@snort/shared"; import { lazy, Suspense } from "react"; const NetworkGraph = lazy(() => import("@/Pages/NetworkGraph")); +const NotificationsPage = lazy(() => import("@/Pages/Notifications")); import * as serviceWorkerRegistration from "@/serviceWorkerRegistration"; import { IntlProvider } from "@/IntlProvider"; @@ -35,7 +36,6 @@ import { getCountry, unwrap } from "@/SnortUtils"; import Layout from "@/Pages/Layout"; import ProfilePage from "@/Pages/Profile/ProfilePage"; import { RootRoutes, RootTabRoutes } from "@/Pages/Root"; -import NotificationsPage from "@/Pages/Notifications"; import SettingsPage, { SettingsRoutes } from "@/Pages/SettingsPage"; import ErrorPage from "@/Pages/ErrorPage"; import NostrAddressPage from "@/Pages/NostrAddressPage"; From f69e05d8fc67c9bae62a58217c31321415087506 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Tue, 21 Nov 2023 10:01:23 +0200 Subject: [PATCH 02/66] rollup visualizer output to build dir --- packages/app/vite.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app/vite.config.ts b/packages/app/vite.config.ts index ff798ef3..e111f1a0 100644 --- a/packages/app/vite.config.ts +++ b/packages/app/vite.config.ts @@ -21,7 +21,7 @@ export default defineConfig({ visualizer({ open: true, gzipSize: true, - filename: "dist/stats.html", + filename: "build/stats.html", }), vitePluginVersionMark({ name: "snort", From 60af57059b6e08c242f01427b89b59a3d88733d3 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Tue, 21 Nov 2023 10:10:20 +0200 Subject: [PATCH 03/66] use vitest instead of jest --- packages/app/jest.config.js | 9 - packages/app/package.json | 11 +- packages/app/src/SnortUtils/Utils.test.ts | 2 +- packages/app/vite.config.ts | 4 + yarn.lock | 362 +++++++++++++++++++++- 5 files changed, 357 insertions(+), 31 deletions(-) delete mode 100644 packages/app/jest.config.js diff --git a/packages/app/jest.config.js b/packages/app/jest.config.js deleted file mode 100644 index 928edeee..00000000 --- a/packages/app/jest.config.js +++ /dev/null @@ -1,9 +0,0 @@ -/** @type {import('ts-jest').JestConfigWithTsJest} */ -module.exports = { - bail: true, - preset: "ts-jest", - testEnvironment: "jsdom", - roots: ["src"], - moduleDirectories: ["src", "node_modules"], - setupFiles: ["./src/setupTests.ts"], -}; diff --git a/packages/app/package.json b/packages/app/package.json index 847d621f..b91e59e6 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -50,7 +50,8 @@ "start": "vite", "build": "yarn eslint --fix && vite build", "serve": "vite preview", - "test": "jest --runInBand", + "test": "vitest run", + "test:watch": "vitest watch", "intl-extract": "formatjs extract 'src/**/*.ts*' --ignore='**/*.d.ts' --out-file src/lang.json --flatten true", "intl-compile": "formatjs compile src/lang.json --out-file src/translations/en.json", "eslint": "eslint ." @@ -76,10 +77,8 @@ }, "devDependencies": { "@formatjs/cli": "^6.1.3", - "@jest/globals": "^29.6.1", "@types/config": "^3.3.3", "@types/debug": "^4.1.8", - "@types/jest": "^29.5.1", "@types/node": "^20.4.1", "@types/react": "^18.0.26", "@types/react-dom": "^18.0.10", @@ -97,8 +96,6 @@ "config": "^3.3.9", "eslint": "^8.48.0", "eslint-plugin-formatjs": "^4.11.3", - "jest": "^29.5.0", - "jest-environment-jsdom": "^29.5.0", "postcss": "^8.4.31", "postcss-preset-env": "^9.2.0", "prettier": "2.8.3", @@ -106,10 +103,10 @@ "rollup-plugin-visualizer": "^5.9.2", "tailwindcss": "^3.3.3", "tinybench": "^2.5.1", - "ts-jest": "^29.1.1", "typescript": "^5.2.2", "vite": "^5.0.0", "vite-plugin-pwa": "^0.17.0", - "vite-plugin-version-mark": "^0.0.10" + "vite-plugin-version-mark": "^0.0.10", + "vitest": "^0.34.6" } } diff --git a/packages/app/src/SnortUtils/Utils.test.ts b/packages/app/src/SnortUtils/Utils.test.ts index bbd17a66..be354076 100644 --- a/packages/app/src/SnortUtils/Utils.test.ts +++ b/packages/app/src/SnortUtils/Utils.test.ts @@ -1,5 +1,5 @@ import { magnetURIDecode, getRelayName } from "."; -import { describe, expect } from "@jest/globals"; +import { describe, it, expect } from 'vitest'; describe("magnet", () => { it("should parse magnet link", () => { diff --git a/packages/app/vite.config.ts b/packages/app/vite.config.ts index e111f1a0..7a3942dd 100644 --- a/packages/app/vite.config.ts +++ b/packages/app/vite.config.ts @@ -45,4 +45,8 @@ export default defineConfig({ global: {}, // needed for custom-event lib SINGLE_RELAY: JSON.stringify(process.env.SINGLE_RELAY), }, + test: { + globals: true, + environment: 'jsdom', + }, }); diff --git a/yarn.lock b/yarn.lock index 2fb48cd4..926bbe6b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2348,7 +2348,7 @@ __metadata: languageName: node linkType: hard -"@jest/globals@npm:^29.5.0, @jest/globals@npm:^29.6.1, @jest/globals@npm:^29.7.0": +"@jest/globals@npm:^29.5.0, @jest/globals@npm:^29.7.0": version: 29.7.0 resolution: "@jest/globals@npm:29.7.0" dependencies: @@ -2884,7 +2884,6 @@ __metadata: dependencies: "@cashu/cashu-ts": ^0.6.1 "@formatjs/cli": ^6.1.3 - "@jest/globals": ^29.6.1 "@lightninglabs/lnc-web": ^0.2.3-alpha "@noble/curves": ^1.0.0 "@noble/hashes": ^1.2.0 @@ -2899,7 +2898,6 @@ __metadata: "@szhsin/react-menu": ^3.3.1 "@types/config": ^3.3.3 "@types/debug": ^4.1.8 - "@types/jest": ^29.5.1 "@types/node": ^20.4.1 "@types/react": ^18.0.26 "@types/react-dom": ^18.0.10 @@ -2924,8 +2922,6 @@ __metadata: eslint: ^8.48.0 eslint-plugin-formatjs: ^4.11.3 highlight.js: ^11.8.0 - jest: ^29.5.0 - jest-environment-jsdom: ^29.5.0 light-bolt11-decoder: ^2.1.0 marked: ^9.1.0 marked-footnote: ^1.0.0 @@ -2949,7 +2945,6 @@ __metadata: tailwindcss: ^3.3.3 three: ^0.157.0 tinybench: ^2.5.1 - ts-jest: ^29.1.1 typescript: ^5.2.2 use-long-press: ^3.2.0 use-sync-external-store: ^1.2.0 @@ -2957,6 +2952,7 @@ __metadata: vite: ^5.0.0 vite-plugin-pwa: ^0.17.0 vite-plugin-version-mark: ^0.0.10 + vitest: ^0.34.6 workbox-core: ^6.4.2 workbox-precaching: ^7.0.0 workbox-routing: ^6.4.2 @@ -3319,6 +3315,22 @@ __metadata: languageName: node linkType: hard +"@types/chai-subset@npm:^1.3.3": + version: 1.3.5 + resolution: "@types/chai-subset@npm:1.3.5" + dependencies: + "@types/chai": "*" + checksum: 715c46d3e90f87482c2769389d560456bb257b225716ff44c275c231bdb62c8a30629f355f412bac0ecab07ebc036c1806d9ed9dde9792254f8ef4f07f76033b + languageName: node + linkType: hard + +"@types/chai@npm:*, @types/chai@npm:^4.3.5": + version: 4.3.11 + resolution: "@types/chai@npm:4.3.11" + checksum: d0c05fe5d02b2e6bbca2bd4866a2ab20a59cf729bc04af0060e7a3277eaf2fb65651b90d4c74b0ebf1d152b4b1d49fa8e44143acef276a2bbaa7785fbe5642d3 + languageName: node + linkType: hard + "@types/config@npm:^3.3.3": version: 3.3.3 resolution: "@types/config@npm:3.3.3" @@ -3886,6 +3898,59 @@ __metadata: languageName: node linkType: hard +"@vitest/expect@npm:0.34.6": + version: 0.34.6 + resolution: "@vitest/expect@npm:0.34.6" + dependencies: + "@vitest/spy": 0.34.6 + "@vitest/utils": 0.34.6 + chai: ^4.3.10 + checksum: 37a526f4af7e73fc56b71ba1139d6d93ff1972315d0e0691de967179298d2ad086e8803d2b28defe0e97a1326d808cd886e4b802d1691d8894cb234e35ed5185 + languageName: node + linkType: hard + +"@vitest/runner@npm:0.34.6": + version: 0.34.6 + resolution: "@vitest/runner@npm:0.34.6" + dependencies: + "@vitest/utils": 0.34.6 + p-limit: ^4.0.0 + pathe: ^1.1.1 + checksum: 0357f0a11f4e1e170099f9125e379bbe8049a59faa7b34b919b3e5ee8927f30824c2b3ebb814b6a77c75ec35a30bf9adb8ec2b5e051525b4edd0d17be15725cc + languageName: node + linkType: hard + +"@vitest/snapshot@npm:0.34.6": + version: 0.34.6 + resolution: "@vitest/snapshot@npm:0.34.6" + dependencies: + magic-string: ^0.30.1 + pathe: ^1.1.1 + pretty-format: ^29.5.0 + checksum: c2f164b23741cdf10f449575a0f9996cf385675d0f76d2eb696f53b614743811f2fbefdc5eb0fd3f9544ccfbb566d57a5c50a70595167458579d56429b09151f + languageName: node + linkType: hard + +"@vitest/spy@npm:0.34.6": + version: 0.34.6 + resolution: "@vitest/spy@npm:0.34.6" + dependencies: + tinyspy: ^2.1.1 + checksum: b05e5906f2f489a3234a0380a21cb48635915aa7f28eac92a595e78e9ceefb95340311635e39684b32fff20f9c58fdc33488eeddee39a660cd94c9c6bc2febf7 + languageName: node + linkType: hard + +"@vitest/utils@npm:0.34.6": + version: 0.34.6 + resolution: "@vitest/utils@npm:0.34.6" + dependencies: + diff-sequences: ^29.4.3 + loupe: ^2.3.6 + pretty-format: ^29.5.0 + checksum: acf716af2bab66037e49bd6d3e8bae40b605b9bff515d4926c46d6f8cc2366decfac5a1756ea55029968e71fba1da1f992764c3a57c9b46eccce3f6db7197bd6 + languageName: node + linkType: hard + "@void-cat/api@npm:^1.0.10": version: 1.0.10 resolution: "@void-cat/api@npm:1.0.10" @@ -3956,7 +4021,7 @@ __metadata: languageName: node linkType: hard -"acorn-walk@npm:^8.0.2, acorn-walk@npm:^8.1.1": +"acorn-walk@npm:^8.0.2, acorn-walk@npm:^8.1.1, acorn-walk@npm:^8.2.0": version: 8.3.0 resolution: "acorn-walk@npm:8.3.0" checksum: 15ea56ab6529135be05e7d018f935ca80a572355dd3f6d3cd717e36df3346e0f635a93ae781b1c7942607693e2e5f3ef81af5c6fc697bbadcc377ebda7b7f5f6 @@ -4178,6 +4243,13 @@ __metadata: languageName: node linkType: hard +"assertion-error@npm:^1.1.0": + version: 1.1.0 + resolution: "assertion-error@npm:1.1.0" + checksum: fd9429d3a3d4fd61782eb3962ae76b6d08aa7383123fca0596020013b3ebd6647891a85b05ce821c47d1471ed1271f00b0545cf6a4326cf2fc91efcc3b0fbecf + languageName: node + linkType: hard + "async@npm:^3.2.3": version: 3.2.5 resolution: "async@npm:3.2.5" @@ -4475,6 +4547,13 @@ __metadata: languageName: node linkType: hard +"cac@npm:^6.7.14": + version: 6.7.14 + resolution: "cac@npm:6.7.14" + checksum: 45a2496a9443abbe7f52a49b22fbe51b1905eff46e03fd5e6c98e3f85077be3f8949685a1849b1a9cd2bc3e5567dfebcf64f01ce01847baf918f1b37c839791a + languageName: node + linkType: hard + "cacache@npm:^18.0.0": version: 18.0.0 resolution: "cacache@npm:18.0.0" @@ -4541,6 +4620,21 @@ __metadata: languageName: node linkType: hard +"chai@npm:^4.3.10": + version: 4.3.10 + resolution: "chai@npm:4.3.10" + dependencies: + assertion-error: ^1.1.0 + check-error: ^1.0.3 + deep-eql: ^4.1.3 + get-func-name: ^2.0.2 + loupe: ^2.3.6 + pathval: ^1.1.1 + type-detect: ^4.0.8 + checksum: 536668c60a0d985a0fbd94418028e388d243a925d7c5e858c7443e334753511614a3b6a124bac9ca077dfc4c37acc367d62f8c294960f440749536dc181dfc6d + languageName: node + linkType: hard + "chalk@npm:^2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" @@ -4569,6 +4663,15 @@ __metadata: languageName: node linkType: hard +"check-error@npm:^1.0.3": + version: 1.0.3 + resolution: "check-error@npm:1.0.3" + dependencies: + get-func-name: ^2.0.2 + checksum: e2131025cf059b21080f4813e55b3c480419256914601750b0fee3bd9b2b8315b531e551ef12560419b8b6d92a3636511322752b1ce905703239e7cc451b6399 + languageName: node + linkType: hard + "chokidar@npm:^3.5.3": version: 3.5.3 resolution: "chokidar@npm:3.5.3" @@ -5102,6 +5205,15 @@ __metadata: languageName: node linkType: hard +"deep-eql@npm:^4.1.3": + version: 4.1.3 + resolution: "deep-eql@npm:4.1.3" + dependencies: + type-detect: ^4.0.0 + checksum: 7f6d30cb41c713973dc07eaadded848b2ab0b835e518a88b91bea72f34e08c4c71d167a722a6f302d3a6108f05afd8e6d7650689a84d5d29ec7fe6220420397f + languageName: node + linkType: hard + "deep-is@npm:^0.1.3": version: 0.1.4 resolution: "deep-is@npm:0.1.4" @@ -5180,7 +5292,7 @@ __metadata: languageName: node linkType: hard -"diff-sequences@npm:^29.6.3": +"diff-sequences@npm:^29.4.3, diff-sequences@npm:^29.6.3": version: 29.6.3 resolution: "diff-sequences@npm:29.6.3" checksum: f4914158e1f2276343d98ff5b31fc004e7304f5470bf0f1adb2ac6955d85a531a6458d33e87667f98f6ae52ebd3891bb47d420bb48a5bd8b7a27ee25b20e33aa @@ -6022,6 +6134,13 @@ __metadata: languageName: node linkType: hard +"get-func-name@npm:^2.0.1, get-func-name@npm:^2.0.2": + version: 2.0.2 + resolution: "get-func-name@npm:2.0.2" + checksum: 3f62f4c23647de9d46e6f76d2b3eafe58933a9b3830c60669e4180d6c601ce1b4aa310ba8366143f55e52b139f992087a9f0647274e8745621fa2af7e0acf13b + languageName: node + linkType: hard + "get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.0, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.2": version: 1.2.2 resolution: "get-intrinsic@npm:1.2.2" @@ -7478,6 +7597,13 @@ __metadata: languageName: node linkType: hard +"jsonc-parser@npm:^3.2.0": + version: 3.2.0 + resolution: "jsonc-parser@npm:3.2.0" + checksum: 946dd9a5f326b745aa326d48a7257e3f4a4b62c5e98ec8e49fa2bdd8d96cef7e6febf1399f5c7016114fd1f68a1c62c6138826d5d90bc650448e3cf0951c53c7 + languageName: node + linkType: hard + "jsonfile@npm:^6.0.1": version: 6.1.0 resolution: "jsonfile@npm:6.1.0" @@ -7581,6 +7707,13 @@ __metadata: languageName: node linkType: hard +"local-pkg@npm:^0.4.3": + version: 0.4.3 + resolution: "local-pkg@npm:0.4.3" + checksum: 7825aca531dd6afa3a3712a0208697aa4a5cd009065f32e3fb732aafcc42ed11f277b5ac67229222e96f4def55197171cdf3d5522d0381b489d2e5547b407d55 + languageName: node + linkType: hard + "locate-character@npm:^3.0.0": version: 3.0.0 resolution: "locate-character@npm:3.0.0" @@ -7659,6 +7792,15 @@ __metadata: languageName: node linkType: hard +"loupe@npm:^2.3.6": + version: 2.3.7 + resolution: "loupe@npm:2.3.7" + dependencies: + get-func-name: ^2.0.1 + checksum: 96c058ec7167598e238bb7fb9def2f9339215e97d6685d9c1e3e4bdb33d14600e11fe7a812cf0c003dfb73ca2df374f146280b2287cae9e8d989e9d7a69a203b + languageName: node + linkType: hard + "lru-cache@npm:^10.0.1, lru-cache@npm:^9.1.1 || ^10.0.0": version: 10.0.2 resolution: "lru-cache@npm:10.0.2" @@ -7695,7 +7837,7 @@ __metadata: languageName: node linkType: hard -"magic-string@npm:^0.30.0, magic-string@npm:^0.30.4": +"magic-string@npm:^0.30.0, magic-string@npm:^0.30.1, magic-string@npm:^0.30.4": version: 0.30.5 resolution: "magic-string@npm:0.30.5" dependencies: @@ -7957,6 +8099,18 @@ __metadata: languageName: node linkType: hard +"mlly@npm:^1.2.0, mlly@npm:^1.4.0": + version: 1.4.2 + resolution: "mlly@npm:1.4.2" + dependencies: + acorn: ^8.10.0 + pathe: ^1.1.1 + pkg-types: ^1.0.3 + ufo: ^1.3.0 + checksum: ad0813eca133e59ac03b356b87deea57da96083dce7dda58a8eeb2dce92b7cc2315bedd9268f3ff8e98effe1867ddb1307486d4c5cd8be162daa8e0fa0a98ed4 + languageName: node + linkType: hard + "ms@npm:2.1.2": version: 2.1.2 resolution: "ms@npm:2.1.2" @@ -8215,6 +8369,15 @@ __metadata: languageName: node linkType: hard +"p-limit@npm:^4.0.0": + version: 4.0.0 + resolution: "p-limit@npm:4.0.0" + dependencies: + yocto-queue: ^1.0.0 + checksum: 01d9d70695187788f984226e16c903475ec6a947ee7b21948d6f597bed788e3112cc7ec2e171c1d37125057a5f45f3da21d8653e04a3a793589e12e9e80e756b + languageName: node + linkType: hard + "p-locate@npm:^4.1.0": version: 4.1.0 resolution: "p-locate@npm:4.1.0" @@ -8324,6 +8487,20 @@ __metadata: languageName: node linkType: hard +"pathe@npm:^1.1.0, pathe@npm:^1.1.1": + version: 1.1.1 + resolution: "pathe@npm:1.1.1" + checksum: 34ab3da2e5aa832ebc6a330ffe3f73d7ba8aec6e899b53b8ec4f4018de08e40742802deb12cf5add9c73b7bf719b62c0778246bd376ca62b0fb23e0dde44b759 + languageName: node + linkType: hard + +"pathval@npm:^1.1.1": + version: 1.1.1 + resolution: "pathval@npm:1.1.1" + checksum: 090e3147716647fb7fb5b4b8c8e5b55e5d0a6086d085b6cd23f3d3c01fcf0ff56fd3cc22f2f4a033bd2e46ed55d61ed8379e123b42afe7d531a2a5fc8bb556d6 + languageName: node + linkType: hard + "periscopic@npm:^3.1.0": version: 3.1.0 resolution: "periscopic@npm:3.1.0" @@ -8372,6 +8549,17 @@ __metadata: languageName: node linkType: hard +"pkg-types@npm:^1.0.3": + version: 1.0.3 + resolution: "pkg-types@npm:1.0.3" + dependencies: + jsonc-parser: ^3.2.0 + mlly: ^1.2.0 + pathe: ^1.1.0 + checksum: 4b305c834b912ddcc8a0fe77530c0b0321fe340396f84cbb87aecdbc126606f47f2178f23b8639e71a4870f9631c7217aef52ffed0ae17ea2dbbe7e43d116a6e + languageName: node + linkType: hard + "polished@npm:4": version: 4.2.2 resolution: "polished@npm:4.2.2" @@ -8860,7 +9048,7 @@ __metadata: languageName: node linkType: hard -"pretty-format@npm:^29.0.0, pretty-format@npm:^29.7.0": +"pretty-format@npm:^29.0.0, pretty-format@npm:^29.5.0, pretty-format@npm:^29.7.0": version: 29.7.0 resolution: "pretty-format@npm:29.7.0" dependencies: @@ -9693,6 +9881,13 @@ __metadata: languageName: node linkType: hard +"siginfo@npm:^2.0.0": + version: 2.0.0 + resolution: "siginfo@npm:2.0.0" + checksum: 8aa5a98640ca09fe00d74416eca97551b3e42991614a3d1b824b115fc1401543650914f651ab1311518177e4d297e80b953f4cd4cd7ea1eabe824e8f2091de01 + languageName: node + linkType: hard + "signal-exit@npm:^3.0.3, signal-exit@npm:^3.0.7": version: 3.0.7 resolution: "signal-exit@npm:3.0.7" @@ -9838,6 +10033,20 @@ __metadata: languageName: node linkType: hard +"stackback@npm:0.0.2": + version: 0.0.2 + resolution: "stackback@npm:0.0.2" + checksum: 2d4dc4e64e2db796de4a3c856d5943daccdfa3dd092e452a1ce059c81e9a9c29e0b9badba91b43ef0d5ff5c04ee62feb3bcc559a804e16faf447bac2d883aa99 + languageName: node + linkType: hard + +"std-env@npm:^3.3.3": + version: 3.5.0 + resolution: "std-env@npm:3.5.0" + checksum: 8eba87eab2d6933e0575f13a65a359952a2e3e8c4d24eb55beac5500fe0403b3482c7b59a5de8d035ae13d390c76dd6c677772f9d2a89ea7cf39ae267b71bdd3 + languageName: node + linkType: hard + "string-length@npm:^4.0.1": version: 4.0.2 resolution: "string-length@npm:4.0.2" @@ -9977,6 +10186,15 @@ __metadata: languageName: node linkType: hard +"strip-literal@npm:^1.0.1": + version: 1.3.0 + resolution: "strip-literal@npm:1.3.0" + dependencies: + acorn: ^8.10.0 + checksum: f5fa7e289df8ebe82e90091fd393974faf8871be087ca50114327506519323cf15f2f8fee6ebe68b5e58bfc795269cae8bdc7cb5a83e27b02b3fe953f37b0a89 + languageName: node + linkType: hard + "sucrase@npm:^3.32.0": version: 3.34.0 resolution: "sucrase@npm:3.34.0" @@ -10235,7 +10453,7 @@ __metadata: languageName: node linkType: hard -"tinybench@npm:^2.5.1": +"tinybench@npm:^2.5.0, tinybench@npm:^2.5.1": version: 2.5.1 resolution: "tinybench@npm:2.5.1" checksum: 6d98526c00b68b50ab0a37590b3cc6713b96fee7dd6756a2a77bab071ed1b4a4fc54e7b11e28b35ec2f761c6a806c2befa95f10acf2fee111c49327b6fc3386f @@ -10249,6 +10467,20 @@ __metadata: languageName: node linkType: hard +"tinypool@npm:^0.7.0": + version: 0.7.0 + resolution: "tinypool@npm:0.7.0" + checksum: fdcccd5c750574fce51f8801a877f8284e145d12b79cd5f2d72bfbddfe20c895e915555bc848e122bb6aa968098e7ac4fe1e8e88104904d518dc01cccd18a510 + languageName: node + linkType: hard + +"tinyspy@npm:^2.1.1": + version: 2.2.0 + resolution: "tinyspy@npm:2.2.0" + checksum: 36431acaa648054406147a92b9bde494b7548d0f9f3ffbcc02113c25a6e59f3310cbe924353d7f4c51436299150bec2dbb3dc595748f58c4ddffea22d5baaadb + languageName: node + linkType: hard + "tmpl@npm:1.0.5": version: 1.0.5 resolution: "tmpl@npm:1.0.5" @@ -10318,7 +10550,7 @@ __metadata: languageName: node linkType: hard -"ts-jest@npm:^29.1.0, ts-jest@npm:^29.1.1": +"ts-jest@npm:^29.1.0": version: 29.1.1 resolution: "ts-jest@npm:29.1.1" dependencies: @@ -10405,7 +10637,7 @@ __metadata: languageName: node linkType: hard -"type-detect@npm:4.0.8": +"type-detect@npm:4.0.8, type-detect@npm:^4.0.0, type-detect@npm:^4.0.8": version: 4.0.8 resolution: "type-detect@npm:4.0.8" checksum: 62b5628bff67c0eb0b66afa371bd73e230399a8d2ad30d852716efcc4656a7516904570cd8631a49a3ce57c10225adf5d0cbdcb47f6b0255fe6557c453925a15 @@ -10500,6 +10732,13 @@ __metadata: languageName: node linkType: hard +"ufo@npm:^1.3.0": + version: 1.3.2 + resolution: "ufo@npm:1.3.2" + checksum: f1180bb715ff4dd46152fd4dec41c731e84d7b9eaf1432548a0210b2f7e0cd29de125ac88e582c6a079d8ae5bc9ab04ef2bdbafe125086480b10c1006b81bfce + languageName: node + linkType: hard + "unbox-primitive@npm:^1.0.2": version: 1.0.2 resolution: "unbox-primitive@npm:1.0.2" @@ -10749,6 +10988,22 @@ __metadata: languageName: node linkType: hard +"vite-node@npm:0.34.6": + version: 0.34.6 + resolution: "vite-node@npm:0.34.6" + dependencies: + cac: ^6.7.14 + debug: ^4.3.4 + mlly: ^1.4.0 + pathe: ^1.1.1 + picocolors: ^1.0.0 + vite: ^3.0.0 || ^4.0.0 || ^5.0.0-0 + bin: + vite-node: vite-node.mjs + checksum: 46eba82bf8b69c7dfeed901502533b172cc6303212f0f49f82c2f64758fa4b60acd1b1e37cb96aff944e36b510b0d1beedb50d9cb25ef39e0159b2b9d1136b1f + languageName: node + linkType: hard + "vite-plugin-pwa@npm:^0.17.0": version: 0.17.0 resolution: "vite-plugin-pwa@npm:0.17.0" @@ -10773,7 +11028,7 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.0.0": +"vite@npm:^3.0.0 || ^4.0.0 || ^5.0.0-0, vite@npm:^3.1.0 || ^4.0.0 || ^5.0.0-0, vite@npm:^5.0.0": version: 5.0.0 resolution: "vite@npm:5.0.0" dependencies: @@ -10813,6 +11068,66 @@ __metadata: languageName: node linkType: hard +"vitest@npm:^0.34.6": + version: 0.34.6 + resolution: "vitest@npm:0.34.6" + dependencies: + "@types/chai": ^4.3.5 + "@types/chai-subset": ^1.3.3 + "@types/node": "*" + "@vitest/expect": 0.34.6 + "@vitest/runner": 0.34.6 + "@vitest/snapshot": 0.34.6 + "@vitest/spy": 0.34.6 + "@vitest/utils": 0.34.6 + acorn: ^8.9.0 + acorn-walk: ^8.2.0 + cac: ^6.7.14 + chai: ^4.3.10 + debug: ^4.3.4 + local-pkg: ^0.4.3 + magic-string: ^0.30.1 + pathe: ^1.1.1 + picocolors: ^1.0.0 + std-env: ^3.3.3 + strip-literal: ^1.0.1 + tinybench: ^2.5.0 + tinypool: ^0.7.0 + vite: ^3.1.0 || ^4.0.0 || ^5.0.0-0 + vite-node: 0.34.6 + why-is-node-running: ^2.2.2 + peerDependencies: + "@edge-runtime/vm": "*" + "@vitest/browser": "*" + "@vitest/ui": "*" + happy-dom: "*" + jsdom: "*" + playwright: "*" + safaridriver: "*" + webdriverio: "*" + peerDependenciesMeta: + "@edge-runtime/vm": + optional: true + "@vitest/browser": + optional: true + "@vitest/ui": + optional: true + happy-dom: + optional: true + jsdom: + optional: true + playwright: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + bin: + vitest: vitest.mjs + checksum: 45f5c1987fa8c76dbaf5db379bbdb4f6e3713c484e850149af38247b627e70016c1863286fd7fcfab08a1d98430f66ba1f45af6f14f5c467ded4b1ea6f26afa3 + languageName: node + linkType: hard + "w3c-xmlserializer@npm:^4.0.0": version: 4.0.0 resolution: "w3c-xmlserializer@npm:4.0.0" @@ -10943,6 +11258,18 @@ __metadata: languageName: node linkType: hard +"why-is-node-running@npm:^2.2.2": + version: 2.2.2 + resolution: "why-is-node-running@npm:2.2.2" + dependencies: + siginfo: ^2.0.0 + stackback: 0.0.2 + bin: + why-is-node-running: cli.js + checksum: 50820428f6a82dfc3cbce661570bcae9b658723217359b6037b67e495255409b4c8bc7931745f5c175df71210450464517cab32b2f7458ac9c40b4925065200a + languageName: node + linkType: hard + "workbox-background-sync@npm:7.0.0": version: 7.0.0 resolution: "workbox-background-sync@npm:7.0.0" @@ -11289,3 +11616,10 @@ __metadata: checksum: f77b3d8d00310def622123df93d4ee654fc6a0096182af8bd60679ddcdfb3474c56c6c7190817c84a2785648cdee9d721c0154eb45698c62176c322fb46fc700 languageName: node linkType: hard + +"yocto-queue@npm:^1.0.0": + version: 1.0.0 + resolution: "yocto-queue@npm:1.0.0" + checksum: 2cac84540f65c64ccc1683c267edce396b26b1e931aa429660aefac8fbe0188167b7aee815a3c22fa59a28a58d898d1a2b1825048f834d8d629f4c2a5d443801 + languageName: node + linkType: hard From dd941ae70ecc0e51a11bed532eee20777fda4cb5 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Tue, 21 Nov 2023 11:57:25 +0200 Subject: [PATCH 04/66] wip 3-col layout --- packages/app/src/Pages/Layout.tsx | 202 ------------------ .../app/src/Pages/Layout/AccountHeader.tsx | 104 +++++++++ .../app/src/Pages/{ => Layout}/Layout.css | 0 packages/app/src/Pages/Layout/LogoHeader.tsx | 30 +++ packages/app/src/Pages/Layout/NavSidebar.tsx | 56 +++++ packages/app/src/Pages/Layout/RightColumn.tsx | 11 + packages/app/src/Pages/Layout/index.tsx | 99 +++++++++ .../app/src/Pages/Profile/ProfilePage.css | 2 - packages/app/src/SnortUtils/Utils.test.ts | 2 +- packages/app/src/index.css | 12 -- packages/app/vite.config.ts | 2 +- 11 files changed, 302 insertions(+), 218 deletions(-) delete mode 100644 packages/app/src/Pages/Layout.tsx create mode 100644 packages/app/src/Pages/Layout/AccountHeader.tsx rename packages/app/src/Pages/{ => Layout}/Layout.css (100%) create mode 100644 packages/app/src/Pages/Layout/LogoHeader.tsx create mode 100644 packages/app/src/Pages/Layout/NavSidebar.tsx create mode 100644 packages/app/src/Pages/Layout/RightColumn.tsx create mode 100644 packages/app/src/Pages/Layout/index.tsx diff --git a/packages/app/src/Pages/Layout.tsx b/packages/app/src/Pages/Layout.tsx deleted file mode 100644 index c71fd502..00000000 --- a/packages/app/src/Pages/Layout.tsx +++ /dev/null @@ -1,202 +0,0 @@ -import "./Layout.css"; -import { useEffect, useMemo, useState } from "react"; -import { Link, Outlet, useLocation, useNavigate } from "react-router-dom"; -import { FormattedMessage } from "react-intl"; -import { useUserProfile } from "@snort/system-react"; -import { base64 } from "@scure/base"; -import { unwrap } from "@snort/shared"; - -import Icon from "@/Icons/Icon"; -import useLoginFeed from "@/Feed/LoginFeed"; -import { mapPlanName } from "./subscribe"; -import useLogin from "@/Hooks/useLogin"; -import Avatar from "@/Element/User/Avatar"; -import { isHalloween, isFormElement, isStPatricksDay, isChristmas } from "@/SnortUtils"; -import { getCurrentSubscription } from "@/Subscription"; -import Toaster from "@/Toaster"; -import { useTheme } from "@/Hooks/useTheme"; -import { useLoginRelays } from "@/Hooks/useLoginRelays"; -import { LoginUnlock } from "@/Element/PinPrompt"; -import useKeyboardShortcut from "@/Hooks/useKeyboardShortcut"; -import { LoginStore } from "@/Login"; -import { NoteCreatorButton } from "@/Element/Event/NoteCreatorButton"; -import { ProfileLink } from "@/Element/User/ProfileLink"; -import SearchBox from "../Element/SearchBox"; -import SnortApi from "@/External/SnortApi"; -import useEventPublisher from "@/Hooks/useEventPublisher"; - -export default function Layout() { - const location = useLocation(); - const [pageClass, setPageClass] = useState("page"); - const { id, stalker } = useLogin(s => ({ id: s.id, stalker: s.stalker ?? false })); - - useLoginFeed(); - useTheme(); - useLoginRelays(); - useKeyboardShortcut(".", event => { - // if event happened in a form element, do nothing, otherwise focus on search input - if (event.target && !isFormElement(event.target as HTMLElement)) { - event.preventDefault(); - window.scrollTo({ - top: 0, - behavior: "smooth", - }); - } - }); - - const shouldHideHeader = useMemo(() => { - const hideOn = ["/login", "/new"]; - return hideOn.some(a => location.pathname.startsWith(a)); - }, [location]); - - useEffect(() => { - const widePage = ["/login", "/messages"]; - const noScroll = ["/messages"]; - if (widePage.some(a => location.pathname.startsWith(a))) { - setPageClass(noScroll.some(a => location.pathname.startsWith(a)) ? "scroll-lock" : ""); - } else { - setPageClass("page"); - } - }, [location]); - - return ( - <> -
- {!shouldHideHeader && ( -
- - -
- )} - - - -
- - {stalker && ( -
{ - LoginStore.removeSession(id); - }}> - -
- )} - - ); -} - -const AccountHeader = () => { - const navigate = useNavigate(); - - useKeyboardShortcut("/", event => { - // if event happened in a form element, do nothing, otherwise focus on search input - if (event.target && !isFormElement(event.target as HTMLElement)) { - event.preventDefault(); - document.querySelector(".search input")?.focus(); - } - }); - - const { publicKey, latestNotification, readNotifications, readonly } = useLogin(s => ({ - publicKey: s.publicKey, - latestNotification: s.latestNotification, - readNotifications: s.readNotifications, - readonly: s.readonly, - })); - const profile = useUserProfile(publicKey); - const { publisher } = useEventPublisher(); - - const hasNotifications = useMemo( - () => latestNotification > readNotifications, - [latestNotification, readNotifications], - ); - const unreadDms = useMemo(() => (publicKey ? 0 : 0), [publicKey]); - - async function goToNotifications() { - // request permissions to send notifications - if ("Notification" in window) { - try { - if (Notification.permission !== "granted") { - const res = await Notification.requestPermission(); - console.debug(res); - } - } catch (e) { - console.error(e); - } - } - try { - if ("serviceWorker" in navigator) { - const reg = await navigator.serviceWorker.ready; - if (reg && publisher) { - const api = new SnortApi(undefined, publisher); - const sub = await reg.pushManager.subscribe({ - userVisibleOnly: true, - applicationServerKey: (await api.getPushNotificationInfo()).publicKey, - }); - await api.registerPushNotifications({ - endpoint: sub.endpoint, - p256dh: base64.encode(new Uint8Array(unwrap(sub.getKey("p256dh")))), - auth: base64.encode(new Uint8Array(unwrap(sub.getKey("auth")))), - scope: `${location.protocol}//${location.hostname}`, - }); - } - } - } catch (e) { - console.error(e); - } - } - - if (!publicKey) { - return ( - - ); - } - return ( -
- {!location.pathname.startsWith("/search") ? :
} - {!readonly && ( - - - {unreadDms > 0 && } - - )} - - - {hasNotifications && } - - - - -
- ); -}; - -function LogoHeader() { - const { subscriptions } = useLogin(); - const currentSubscription = getCurrentSubscription(subscriptions); - - const extra = () => { - if (isHalloween()) return "🎃"; - if (isStPatricksDay()) return "🍀"; - if (isChristmas()) return "🎄"; - }; - - return ( - -

- {extra()} - {CONFIG.appName} -

- {currentSubscription && ( -
- - {mapPlanName(currentSubscription.type)} -
- )} - - ); -} diff --git a/packages/app/src/Pages/Layout/AccountHeader.tsx b/packages/app/src/Pages/Layout/AccountHeader.tsx new file mode 100644 index 00000000..1b118724 --- /dev/null +++ b/packages/app/src/Pages/Layout/AccountHeader.tsx @@ -0,0 +1,104 @@ +import { Link, useNavigate } from "react-router-dom"; +import { useUserProfile } from "@snort/system-react"; +import { useMemo } from "react"; +import { base64 } from "@scure/base"; +import { unwrap } from "@snort/shared"; +import { FormattedMessage } from "react-intl"; +import SearchBox from "../../Element/SearchBox"; +import { ProfileLink } from "../../Element/User/ProfileLink"; +import Avatar from "../../Element/User/Avatar"; +import Icon from "../../Icons/Icon"; +import useKeyboardShortcut from "../../Hooks/useKeyboardShortcut"; +import { isFormElement } from "../../SnortUtils"; +import useLogin from "../../Hooks/useLogin"; +import useEventPublisher from "../../Hooks/useEventPublisher"; +import SnortApi from "../../External/SnortApi"; + +const AccountHeader = () => { + const navigate = useNavigate(); + + useKeyboardShortcut("/", event => { + // if event happened in a form element, do nothing, otherwise focus on search input + if (event.target && !isFormElement(event.target as HTMLElement)) { + event.preventDefault(); + document.querySelector(".search input")?.focus(); + } + }); + + const { publicKey, latestNotification, readNotifications, readonly } = useLogin(s => ({ + publicKey: s.publicKey, + latestNotification: s.latestNotification, + readNotifications: s.readNotifications, + readonly: s.readonly, + })); + const profile = useUserProfile(publicKey); + const { publisher } = useEventPublisher(); + + const hasNotifications = useMemo( + () => latestNotification > readNotifications, + [latestNotification, readNotifications], + ); + const unreadDms = useMemo(() => (publicKey ? 0 : 0), [publicKey]); + + async function goToNotifications() { + // request permissions to send notifications + if ("Notification" in window) { + try { + if (Notification.permission !== "granted") { + const res = await Notification.requestPermission(); + console.debug(res); + } + } catch (e) { + console.error(e); + } + } + try { + if ("serviceWorker" in navigator) { + const reg = await navigator.serviceWorker.ready; + if (reg && publisher) { + const api = new SnortApi(undefined, publisher); + const sub = await reg.pushManager.subscribe({ + userVisibleOnly: true, + applicationServerKey: (await api.getPushNotificationInfo()).publicKey, + }); + await api.registerPushNotifications({ + endpoint: sub.endpoint, + p256dh: base64.encode(new Uint8Array(unwrap(sub.getKey("p256dh")))), + auth: base64.encode(new Uint8Array(unwrap(sub.getKey("auth")))), + scope: `${location.protocol}//${location.hostname}`, + }); + } + } + } catch (e) { + console.error(e); + } + } + + if (!publicKey) { + return ( + + ); + } + return ( +
+ {!location.pathname.startsWith("/search") ? :
} + {!readonly && ( + + + {unreadDms > 0 && } + + )} + + + {hasNotifications && } + + + + +
+ ); +}; + +export default AccountHeader; diff --git a/packages/app/src/Pages/Layout.css b/packages/app/src/Pages/Layout/Layout.css similarity index 100% rename from packages/app/src/Pages/Layout.css rename to packages/app/src/Pages/Layout/Layout.css diff --git a/packages/app/src/Pages/Layout/LogoHeader.tsx b/packages/app/src/Pages/Layout/LogoHeader.tsx new file mode 100644 index 00000000..43c6774a --- /dev/null +++ b/packages/app/src/Pages/Layout/LogoHeader.tsx @@ -0,0 +1,30 @@ +import useLogin from "../../Hooks/useLogin"; +import { getCurrentSubscription } from "../../Subscription"; +import { isChristmas, isHalloween, isStPatricksDay } from "../../SnortUtils"; +import { Link } from "react-router-dom"; +import { mapPlanName } from "../subscribe"; +export function LogoHeader() { + const { subscriptions } = useLogin(); + const currentSubscription = getCurrentSubscription(subscriptions); + + const extra = () => { + if (isHalloween()) return "🎃"; + if (isStPatricksDay()) return "🍀"; + if (isChristmas()) return "🎄"; + }; + + return ( + +

+ {extra()} + {CONFIG.appName} +

+ {currentSubscription && ( +
+ + {mapPlanName(currentSubscription.type)} +
+ )} + + ); +} diff --git a/packages/app/src/Pages/Layout/NavSidebar.tsx b/packages/app/src/Pages/Layout/NavSidebar.tsx new file mode 100644 index 00000000..9caf2f14 --- /dev/null +++ b/packages/app/src/Pages/Layout/NavSidebar.tsx @@ -0,0 +1,56 @@ +import { LogoHeader } from "./LogoHeader"; +import { Link } from "react-router-dom"; +import Icon from "@/Icons/Icon"; + +const MENU_ITEMS = [ + { + label: "Home", + icon: "home", + link: "/", + }, + { + label: "Messages", + icon: "mail", + link: "/messages", + }, + { + label: "Notifications", + icon: "bell-02", + link: "/notifications", + }, + { + label: "Settings", + icon: "cog", + link: "/settings", + }, +]; + +export default function NavSidebar() { + return ( +
+ +
+
+ {MENU_ITEMS.map(item => ( + + + {item.label} + + ))} +
+
+
+ ); +} + +function NavLink({ children, ...props }) { + return ( + + {children} + + ); +} diff --git a/packages/app/src/Pages/Layout/RightColumn.tsx b/packages/app/src/Pages/Layout/RightColumn.tsx new file mode 100644 index 00000000..a39522ea --- /dev/null +++ b/packages/app/src/Pages/Layout/RightColumn.tsx @@ -0,0 +1,11 @@ +import SearchBox from "../../Element/SearchBox"; + +export default function RightColumn() { + return ( +
+
+ +
+
+ ); +} diff --git a/packages/app/src/Pages/Layout/index.tsx b/packages/app/src/Pages/Layout/index.tsx new file mode 100644 index 00000000..a570e238 --- /dev/null +++ b/packages/app/src/Pages/Layout/index.tsx @@ -0,0 +1,99 @@ +import "./Layout.css"; +import { useCallback, useEffect, useMemo, useState } from "react"; +import { Outlet, useLocation } from "react-router-dom"; + +import Icon from "@/Icons/Icon"; +import useLogin from "@/Hooks/useLogin"; +import { isFormElement } from "@/SnortUtils"; +import Toaster from "@/Toaster"; +import { useTheme } from "@/Hooks/useTheme"; +import { useLoginRelays } from "@/Hooks/useLoginRelays"; +import { LoginUnlock } from "@/Element/PinPrompt"; +import useKeyboardShortcut from "@/Hooks/useKeyboardShortcut"; +import { LoginStore } from "@/Login"; +import { NoteCreatorButton } from "@/Element/Event/NoteCreatorButton"; +import NavSidebar from "./NavSidebar"; +import AccountHeader from "./AccountHeader"; +import RightColumn from "./RightColumn"; +import { LogoHeader } from "./LogoHeader"; + +export default function Index() { + const location = useLocation(); + const [pageClass, setPageClass] = useState("page"); + const { id, stalker } = useLogin(s => ({ id: s.id, stalker: s.stalker ?? false })); + + useTheme(); + useLoginRelays(); + + const hideHeaderPaths = ["/login", "/new"]; + const shouldHideHeader = hideHeaderPaths.some(path => location.pathname.startsWith(path)); + + const pageClassPaths = useMemo( + () => ({ + widePage: ["/login", "/messages"], + noScroll: ["/messages"], + }), + [], + ); + + useEffect(() => { + const isWidePage = pageClassPaths.widePage.some(path => location.pathname.startsWith(path)); + const isNoScroll = pageClassPaths.noScroll.some(path => location.pathname.startsWith(path)); + setPageClass(isWidePage ? (isNoScroll ? "scroll-lock" : "") : "page"); + }, [location, pageClassPaths]); + + const handleKeyboardShortcut = useCallback(event => { + if (event.target && !isFormElement(event.target as HTMLElement)) { + event.preventDefault(); + window.scrollTo({ top: 0, behavior: "smooth" }); + } + }, []); + + useKeyboardShortcut(".", handleKeyboardShortcut); + + const isStalker = !!stalker; + + return ( +
+
+
+ + + +
+ + +
+ + {isStalker && } +
+ ); +} + +function MainContent({ shouldHideHeader }) { + return ( +
+ {!shouldHideHeader &&
} + +
+ ); +} + +function Header() { + return ( +
+ + +
+ ); +} + +function StalkerModal({ id }) { + return ( +
LoginStore.removeSession(id)}> + +
+ ); +} diff --git a/packages/app/src/Pages/Profile/ProfilePage.css b/packages/app/src/Pages/Profile/ProfilePage.css index 6c0851eb..0f0c0f8f 100644 --- a/packages/app/src/Pages/Profile/ProfilePage.css +++ b/packages/app/src/Pages/Profile/ProfilePage.css @@ -39,8 +39,6 @@ @media (min-width: 520px) { .profile .banner { - width: 100%; - max-width: 720px; height: 280px; } diff --git a/packages/app/src/SnortUtils/Utils.test.ts b/packages/app/src/SnortUtils/Utils.test.ts index be354076..16646ed0 100644 --- a/packages/app/src/SnortUtils/Utils.test.ts +++ b/packages/app/src/SnortUtils/Utils.test.ts @@ -1,5 +1,5 @@ import { magnetURIDecode, getRelayName } from "."; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from "vitest"; describe("magnet", () => { it("should parse magnet link", () => { diff --git a/packages/app/src/index.css b/packages/app/src/index.css index ff01884f..c3665f7e 100644 --- a/packages/app/src/index.css +++ b/packages/app/src/index.css @@ -136,19 +136,7 @@ a.ext { overflow-x: hidden; } -.page { - width: 100vw; - margin-left: auto; - margin-right: auto; -} - @media (min-width: 768px) { - .page { - width: 640px; - margin-left: auto; - margin-right: auto; - } - .main-content { border: 1px solid var(--border-color); } diff --git a/packages/app/vite.config.ts b/packages/app/vite.config.ts index 7a3942dd..8c69f69d 100644 --- a/packages/app/vite.config.ts +++ b/packages/app/vite.config.ts @@ -47,6 +47,6 @@ export default defineConfig({ }, test: { globals: true, - environment: 'jsdom', + environment: "jsdom", }, }); From 4dfa610c872dad26c17faaf9ccb6d91a0133dd21 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Tue, 21 Nov 2023 14:17:47 +0200 Subject: [PATCH 05/66] simplify settings page --- packages/app/src/Pages/Layout/NavSidebar.tsx | 8 +- packages/app/src/Pages/settings/Root.tsx | 118 ++++++------------- 2 files changed, 43 insertions(+), 83 deletions(-) diff --git a/packages/app/src/Pages/Layout/NavSidebar.tsx b/packages/app/src/Pages/Layout/NavSidebar.tsx index 9caf2f14..467184cb 100644 --- a/packages/app/src/Pages/Layout/NavSidebar.tsx +++ b/packages/app/src/Pages/Layout/NavSidebar.tsx @@ -30,15 +30,15 @@ export default function NavSidebar() {
-
+
{MENU_ITEMS.map(item => ( - - {item.label} + + {item.label} ))}
diff --git a/packages/app/src/Pages/settings/Root.tsx b/packages/app/src/Pages/settings/Root.tsx index 21674550..df16e332 100644 --- a/packages/app/src/Pages/settings/Root.tsx +++ b/packages/app/src/Pages/settings/Root.tsx @@ -1,5 +1,5 @@ import "./Root.css"; -import { useEffect, useMemo } from "react"; +import { useCallback, useEffect } from "react"; import { FormattedMessage } from "react-intl"; import { Outlet, useLocation, useNavigate } from "react-router-dom"; import Icon from "@/Icons/Icon"; @@ -7,7 +7,6 @@ import { LoginStore, logout } from "@/Login"; import useLogin from "@/Hooks/useLogin"; import { getCurrentSubscription } from "@/Subscription"; import usePageWidth from "@/Hooks/usePageWidth"; - import messages from "./messages"; const SettingsIndex = () => { @@ -17,98 +16,59 @@ const SettingsIndex = () => { const pageWidth = usePageWidth(); const sub = getCurrentSubscription(LoginStore.allSubscriptions()); - function handleLogout() { + const handleNavigate = useCallback((path) => { + navigate(path); + }, [navigate]); + + const handleLogout = useCallback(() => { logout(login.id); navigate("/"); - } + }, [login.id, navigate]); useEffect(() => { if (location.pathname === "/settings" && pageWidth >= 768) { navigate("/settings/profile", { replace: true }); } - }, [location, pageWidth]); + }, [location, navigate, pageWidth]); - const [hideMenu, hideContent] = useMemo(() => { - return [location.pathname !== "/settings" && pageWidth < 768, location.pathname === "/settings" && pageWidth < 768]; - }, [location, pageWidth]); + const [hideMenu, hideContent] = [location.pathname !== "/settings" && pageWidth < 768, location.pathname === "/settings" && pageWidth < 768]; + + const menuItems = [ + { icon: "profile", message: messages.Profile, path: "profile" }, + { icon: "relay", message: messages.Relays, path: "relays" }, + { icon: "key", message: "Export Keys", id: "08zn6O", path: "keys" }, + { icon: "shield-tick", message: "Moderation", id: "wofVHy", path: "moderation" }, + { icon: "badge", message: "Nostr Address", id: "9pMqYs", path: "handle" }, + { icon: "gear", message: messages.Preferences, path: "preferences" }, + { icon: "wallet", message: "Wallet", id: "3yk8fB", path: "wallet" }, + { icon: "heart", message: messages.Donate, path: "/donate" }, + { icon: "hard-drive", message: "Cache", id: "DBiVK1", path: "cache" }, + { icon: "profile", message: messages.SocialGraph, path: "/graph" } + ]; + + if (CONFIG.features.subscriptions) { + menuItems.push({ icon: "diamond", message: "Subscription", id: "R/6nsx", path: "/subscribe/manage" }); + } + + if (CONFIG.features.zapPool) { + menuItems.push({ icon: "piggy-bank", message: "Zap Pool", id: "i/dBAR", path: "/zap-pool" }); + } + + if (sub) { + menuItems.push({ icon: "code-circle", message: "Account Switcher", id: "7BX/yC", path: "accounts" }); + } return (
{!hideMenu && (
-
navigate("profile")}> - - - -
-
navigate("relays")}> - - - -
-
navigate("keys")}> - - - -
-
navigate("moderation")}> - - - -
-
navigate("handle")}> - - - -
- {CONFIG.features.subscriptions && ( -
navigate("/subscribe/manage")}> - - + {menuItems.map(({ icon, message, id, path }) => ( +
handleNavigate(path)} key={path}> + +
- )} - {sub && ( -
navigate("accounts")}> - - - -
- )} - -
navigate("preferences")}> - - - -
- -
navigate("wallet")}> - - - -
-
navigate("/donate")}> - - - -
- {CONFIG.features.zapPool && ( -
navigate("/zap-pool")}> - - - -
- )} -
navigate("cache")}> - - - -
-
navigate("/graph")}> - - - -
+ ))}
From 667bce637f333c56b1c2f7c1770cfb7a926a46e3 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Tue, 21 Nov 2023 14:30:56 +0200 Subject: [PATCH 06/66] profile link to nav sidebar --- packages/app/src/Pages/Layout/NavSidebar.tsx | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/packages/app/src/Pages/Layout/NavSidebar.tsx b/packages/app/src/Pages/Layout/NavSidebar.tsx index 467184cb..db277382 100644 --- a/packages/app/src/Pages/Layout/NavSidebar.tsx +++ b/packages/app/src/Pages/Layout/NavSidebar.tsx @@ -1,6 +1,10 @@ import { LogoHeader } from "./LogoHeader"; import { Link } from "react-router-dom"; import Icon from "@/Icons/Icon"; +import {ProfileLink} from "../../Element/User/ProfileLink"; +import Avatar from "../../Element/User/Avatar"; +import useLogin from "../../Hooks/useLogin"; +import {useUserProfile} from "@snort/system-react"; const MENU_ITEMS = [ { @@ -26,6 +30,14 @@ const MENU_ITEMS = [ ]; export default function NavSidebar() { + const { publicKey } = useLogin(s => ({ + publicKey: s.publicKey, + latestNotification: s.latestNotification, + readNotifications: s.readNotifications, + readonly: s.readonly, + })); + const profile = useUserProfile(publicKey); + return (
@@ -43,6 +55,14 @@ export default function NavSidebar() { ))}
+ {publicKey ? ( + +
+ + {profile?.name} +
+
+ ) : ''}
); } From 8e5acc3ea5a1c094308ca89412874f6232368ee0 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Tue, 21 Nov 2023 14:55:22 +0200 Subject: [PATCH 07/66] settings & notes icons --- packages/app/src/Pages/Layout/NavSidebar.tsx | 6 +++--- packages/app/src/icons.svg | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/app/src/Pages/Layout/NavSidebar.tsx b/packages/app/src/Pages/Layout/NavSidebar.tsx index db277382..c41b532b 100644 --- a/packages/app/src/Pages/Layout/NavSidebar.tsx +++ b/packages/app/src/Pages/Layout/NavSidebar.tsx @@ -8,8 +8,8 @@ import {useUserProfile} from "@snort/system-react"; const MENU_ITEMS = [ { - label: "Home", - icon: "home", + label: "Notes", + icon: "notes", link: "/", }, { @@ -24,7 +24,7 @@ const MENU_ITEMS = [ }, { label: "Settings", - icon: "cog", + icon: "settings", link: "/settings", }, ]; diff --git a/packages/app/src/icons.svg b/packages/app/src/icons.svg index 8f36b012..ae63bd24 100644 --- a/packages/app/src/icons.svg +++ b/packages/app/src/icons.svg @@ -382,5 +382,12 @@ + + + + + + + \ No newline at end of file From c5d22b84be317f536076b40459f7549848efc459 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Tue, 21 Nov 2023 17:41:37 +0200 Subject: [PATCH 08/66] layout --- .../src/Element/Event/NoteCreatorButton.tsx | 5 +++- packages/app/src/Pages/Layout/NavSidebar.tsx | 26 ++++++++++++------- packages/app/src/Pages/Layout/index.tsx | 4 ++- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/packages/app/src/Element/Event/NoteCreatorButton.tsx b/packages/app/src/Element/Event/NoteCreatorButton.tsx index cd16d59e..fef8c184 100644 --- a/packages/app/src/Element/Event/NoteCreatorButton.tsx +++ b/packages/app/src/Element/Event/NoteCreatorButton.tsx @@ -10,7 +10,7 @@ import Icon from "@/Icons/Icon"; import { useNoteCreator } from "@/State/NoteCreator"; import { NoteCreator } from "./NoteCreator"; -export const NoteCreatorButton = ({ className }: { className?: string }) => { +export const NoteCreatorButton = ({ className, alwaysShow }: { className?: string, alwaysShow?: boolean }) => { const buttonRef = useRef(null); const location = useLocation(); const { readonly } = useLogin(s => ({ readonly: s.readonly })); @@ -27,6 +27,9 @@ export const NoteCreatorButton = ({ className }: { className?: string }) => { }); const shouldHideNoteCreator = useMemo(() => { + if (alwaysShow) { + return false; + } const isReply = replyTo && show; const hideOn = [ "/settings", diff --git a/packages/app/src/Pages/Layout/NavSidebar.tsx b/packages/app/src/Pages/Layout/NavSidebar.tsx index c41b532b..bab6befb 100644 --- a/packages/app/src/Pages/Layout/NavSidebar.tsx +++ b/packages/app/src/Pages/Layout/NavSidebar.tsx @@ -5,10 +5,11 @@ import {ProfileLink} from "../../Element/User/ProfileLink"; import Avatar from "../../Element/User/Avatar"; import useLogin from "../../Hooks/useLogin"; import {useUserProfile} from "@snort/system-react"; +import {NoteCreatorButton} from "../../Element/Event/NoteCreatorButton"; const MENU_ITEMS = [ { - label: "Notes", + label: "Home", icon: "notes", link: "/", }, @@ -39,29 +40,34 @@ export default function NavSidebar() { const profile = useUserProfile(publicKey); return ( -
+
-
+
{MENU_ITEMS.map(item => ( {item.label} ))} +
+ +
{publicKey ? ( - -
- - {profile?.name} -
-
+ <> + +
+ + {profile?.name} +
+
+ ) : ''}
); diff --git a/packages/app/src/Pages/Layout/index.tsx b/packages/app/src/Pages/Layout/index.tsx index a570e238..e1382465 100644 --- a/packages/app/src/Pages/Layout/index.tsx +++ b/packages/app/src/Pages/Layout/index.tsx @@ -61,7 +61,9 @@ export default function Index() {
- +
+ +
From 59ffb84458b93ade0bab0f1144c430ca16c3ef6e Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Tue, 21 Nov 2023 19:06:03 +0200 Subject: [PATCH 09/66] /new/discover -> /discover --- packages/app/src/Pages/Root.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app/src/Pages/Root.tsx b/packages/app/src/Pages/Root.tsx index 7431f56e..c2d593b2 100644 --- a/packages/app/src/Pages/Root.tsx +++ b/packages/app/src/Pages/Root.tsx @@ -49,7 +49,7 @@ const FollowsHint = () => { {...messages.NoFollows} values={{ newUsersPage: ( - + ), From 9aafc329cb2816b596e4fde4832d5cd861e92d63 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Tue, 21 Nov 2023 19:14:08 +0200 Subject: [PATCH 10/66] home icon --- packages/app/src/Pages/Layout/NavSidebar.tsx | 2 +- packages/app/src/icons.svg | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/app/src/Pages/Layout/NavSidebar.tsx b/packages/app/src/Pages/Layout/NavSidebar.tsx index bab6befb..0b360651 100644 --- a/packages/app/src/Pages/Layout/NavSidebar.tsx +++ b/packages/app/src/Pages/Layout/NavSidebar.tsx @@ -10,7 +10,7 @@ import {NoteCreatorButton} from "../../Element/Event/NoteCreatorButton"; const MENU_ITEMS = [ { label: "Home", - icon: "notes", + icon: "home", link: "/", }, { diff --git a/packages/app/src/icons.svg b/packages/app/src/icons.svg index ae63bd24..c6093943 100644 --- a/packages/app/src/icons.svg +++ b/packages/app/src/icons.svg @@ -389,5 +389,8 @@ + + + \ No newline at end of file From cb5fd783822baca97b1a5c5b04b5298a29348d6a Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Wed, 22 Nov 2023 10:17:32 +0200 Subject: [PATCH 11/66] sidebar items for non-logged-in user --- packages/app/src/Pages/Layout/NavSidebar.tsx | 47 ++++++++++++++------ packages/app/src/icons.svg | 3 ++ 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/packages/app/src/Pages/Layout/NavSidebar.tsx b/packages/app/src/Pages/Layout/NavSidebar.tsx index 0b360651..32b85ae7 100644 --- a/packages/app/src/Pages/Layout/NavSidebar.tsx +++ b/packages/app/src/Pages/Layout/NavSidebar.tsx @@ -1,17 +1,19 @@ import { LogoHeader } from "./LogoHeader"; -import { Link } from "react-router-dom"; +import {Link, useNavigate} from "react-router-dom"; import Icon from "@/Icons/Icon"; import {ProfileLink} from "../../Element/User/ProfileLink"; import Avatar from "../../Element/User/Avatar"; import useLogin from "../../Hooks/useLogin"; import {useUserProfile} from "@snort/system-react"; import {NoteCreatorButton} from "../../Element/Event/NoteCreatorButton"; +import {FormattedMessage} from "react-intl"; const MENU_ITEMS = [ { label: "Home", icon: "home", link: "/", + nonLoggedIn: true, }, { label: "Messages", @@ -38,25 +40,42 @@ export default function NavSidebar() { readonly: s.readonly, })); const profile = useUserProfile(publicKey); + const navigate = useNavigate(); return (
- {MENU_ITEMS.map(item => ( - - - {item.label} - - ))} -
- -
+ {MENU_ITEMS.map(item => { + if (!item.nonLoggedIn && !publicKey) { + return ''; + } + return ( + + + {item.label} + + ); + })} + {publicKey ? ( +
+ +
+ ) : ( +
+ +
+ )}
{publicKey ? ( diff --git a/packages/app/src/icons.svg b/packages/app/src/icons.svg index c6093943..4ed62511 100644 --- a/packages/app/src/icons.svg +++ b/packages/app/src/icons.svg @@ -392,5 +392,8 @@ + + + \ No newline at end of file From 77984f9124fdfc719221eadf240a6b24aa2334b7 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Wed, 22 Nov 2023 10:27:54 +0200 Subject: [PATCH 12/66] right col border --- packages/app/src/Pages/Layout/RightColumn.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app/src/Pages/Layout/RightColumn.tsx b/packages/app/src/Pages/Layout/RightColumn.tsx index a39522ea..04eecaae 100644 --- a/packages/app/src/Pages/Layout/RightColumn.tsx +++ b/packages/app/src/Pages/Layout/RightColumn.tsx @@ -2,7 +2,7 @@ import SearchBox from "../../Element/SearchBox"; export default function RightColumn() { return ( -
+
From f5bb52462818275be15971db49151cf42cc843fb Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Wed, 22 Nov 2023 13:32:18 +0200 Subject: [PATCH 13/66] Revert "lazy load Notifications page" This reverts commit d8dfc962c11dc8f7db120f2522d8dc63971da84a. --- packages/app/src/Pages/DeckLayout.tsx | 5 ++--- packages/app/src/index.tsx | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/app/src/Pages/DeckLayout.tsx b/packages/app/src/Pages/DeckLayout.tsx index 6b957664..3b7c59f5 100644 --- a/packages/app/src/Pages/DeckLayout.tsx +++ b/packages/app/src/Pages/DeckLayout.tsx @@ -1,5 +1,5 @@ import "./Deck.css"; -import { CSSProperties, createContext, useContext, useEffect, useState, lazy } from "react"; +import { CSSProperties, createContext, useContext, useEffect, useState } from "react"; import { Outlet, useNavigate } from "react-router-dom"; import { FormattedMessage } from "react-intl"; import { NostrLink, TaggedNostrEvent } from "@snort/system"; @@ -12,6 +12,7 @@ import Articles from "@/Element/Deck/Articles"; import TimelineFollows from "@/Element/Feed/TimelineFollows"; import { transformTextCached } from "@/Hooks/useTextTransformCache"; import Icon from "@/Icons/Icon"; +import NotificationsPage from "./Notifications"; import useImgProxy from "@/Hooks/useImgProxy"; import Modal from "@/Element/Modal"; import { Thread } from "@/Element/Event/Thread"; @@ -22,8 +23,6 @@ import Toaster from "@/Toaster"; import useLogin from "@/Hooks/useLogin"; import { LongFormText } from "@/Element/Event/LongFormText"; -const NotificationsPage = lazy(() => import("@/Pages/Notifications")); - type Cols = "notes" | "articles" | "media" | "streams" | "notifications"; interface DeckState { diff --git a/packages/app/src/index.tsx b/packages/app/src/index.tsx index 05db901b..b3696b87 100644 --- a/packages/app/src/index.tsx +++ b/packages/app/src/index.tsx @@ -28,7 +28,6 @@ import { removeUndefined, throwIfOffline } from "@snort/shared"; import { lazy, Suspense } from "react"; const NetworkGraph = lazy(() => import("@/Pages/NetworkGraph")); -const NotificationsPage = lazy(() => import("@/Pages/Notifications")); import * as serviceWorkerRegistration from "@/serviceWorkerRegistration"; import { IntlProvider } from "@/IntlProvider"; @@ -36,6 +35,7 @@ import { getCountry, unwrap } from "@/SnortUtils"; import Layout from "@/Pages/Layout"; import ProfilePage from "@/Pages/Profile/ProfilePage"; import { RootRoutes, RootTabRoutes } from "@/Pages/Root"; +import NotificationsPage from "@/Pages/Notifications"; import SettingsPage, { SettingsRoutes } from "@/Pages/SettingsPage"; import ErrorPage from "@/Pages/ErrorPage"; import NostrAddressPage from "@/Pages/NostrAddressPage"; From f9d0318f36e8452a34bf99db328d15b86884cb3f Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Wed, 22 Nov 2023 13:53:59 +0200 Subject: [PATCH 14/66] rm main-content border --- packages/app/src/index.css | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/app/src/index.css b/packages/app/src/index.css index c3665f7e..10f078ac 100644 --- a/packages/app/src/index.css +++ b/packages/app/src/index.css @@ -136,12 +136,6 @@ a.ext { overflow-x: hidden; } -@media (min-width: 768px) { - .main-content { - border: 1px solid var(--border-color); - } -} - .b { border: 1px solid var(--border-color); } From f9e7bc8558df1fe406683cbae8abd793f43ae85e Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Wed, 22 Nov 2023 14:06:42 +0200 Subject: [PATCH 15/66] add trending stuff to right column --- .../src/Element/Event/NoteCreatorButton.tsx | 2 +- packages/app/src/Element/TrendingHashtags.tsx | 4 +-- packages/app/src/Element/TrendingPosts.tsx | 4 ++- packages/app/src/Element/TrendingUsers.tsx | 4 +-- packages/app/src/Pages/Layout/NavSidebar.tsx | 16 ++++++----- packages/app/src/Pages/Layout/RightColumn.tsx | 26 ++++++++++++++++-- packages/app/src/Pages/settings/Root.tsx | 16 +++++++---- packages/app/src/lang.json | 27 +++++++++---------- packages/app/src/translations/en.json | 9 +++---- 9 files changed, 68 insertions(+), 40 deletions(-) diff --git a/packages/app/src/Element/Event/NoteCreatorButton.tsx b/packages/app/src/Element/Event/NoteCreatorButton.tsx index fef8c184..f044ae03 100644 --- a/packages/app/src/Element/Event/NoteCreatorButton.tsx +++ b/packages/app/src/Element/Event/NoteCreatorButton.tsx @@ -10,7 +10,7 @@ import Icon from "@/Icons/Icon"; import { useNoteCreator } from "@/State/NoteCreator"; import { NoteCreator } from "./NoteCreator"; -export const NoteCreatorButton = ({ className, alwaysShow }: { className?: string, alwaysShow?: boolean }) => { +export const NoteCreatorButton = ({ className, alwaysShow }: { className?: string; alwaysShow?: boolean }) => { const buttonRef = useRef(null); const location = useLocation(); const { readonly } = useLogin(s => ({ readonly: s.readonly })); diff --git a/packages/app/src/Element/TrendingHashtags.tsx b/packages/app/src/Element/TrendingHashtags.tsx index 7d8692f8..dfce3eca 100644 --- a/packages/app/src/Element/TrendingHashtags.tsx +++ b/packages/app/src/Element/TrendingHashtags.tsx @@ -6,7 +6,7 @@ import { ErrorOrOffline } from "./ErrorOrOffline"; import { HashTagHeader } from "@/Pages/HashTagsPage"; import { useLocale } from "@/IntlProvider"; -export default function TrendingHashtags({ title }: { title?: ReactNode }) { +export default function TrendingHashtags({ title, count = 5 }: { title?: ReactNode; count?: number }) { const [hashtags, setHashtags] = useState>(); const [error, setError] = useState(); const { lang } = useLocale(); @@ -14,7 +14,7 @@ export default function TrendingHashtags({ title }: { title?: ReactNode }) { async function loadTrendingHashtags() { const api = new NostrBandApi(); const rsp = await api.trendingHashtags(lang); - setHashtags(rsp.hashtags); + setHashtags(rsp.hashtags.slice(0, count)); // Limit the number of hashtags to the count } useEffect(() => { diff --git a/packages/app/src/Element/TrendingPosts.tsx b/packages/app/src/Element/TrendingPosts.tsx index 7e42b7c0..90e170d0 100644 --- a/packages/app/src/Element/TrendingPosts.tsx +++ b/packages/app/src/Element/TrendingPosts.tsx @@ -9,7 +9,8 @@ import { ErrorOrOffline } from "@/Element/ErrorOrOffline"; import { useLocale } from "@/IntlProvider"; import useModeration from "@/Hooks/useModeration"; -export default function TrendingNotes() { +export default function TrendingNotes({ count = Infinity }) { + // Added count prop with a default value const [posts, setPosts] = useState>(); const [error, setError] = useState(); const { lang } = useLocale(); @@ -37,6 +38,7 @@ export default function TrendingNotes() { <> {posts .filter(a => !isEventMuted(a)) + .slice(0, count) // Limit the number of posts displayed .map(e => ( ))} diff --git a/packages/app/src/Element/TrendingUsers.tsx b/packages/app/src/Element/TrendingUsers.tsx index 011c7bb4..86579469 100644 --- a/packages/app/src/Element/TrendingUsers.tsx +++ b/packages/app/src/Element/TrendingUsers.tsx @@ -6,14 +6,14 @@ import PageSpinner from "@/Element/PageSpinner"; import NostrBandApi from "@/External/NostrBand"; import { ErrorOrOffline } from "./ErrorOrOffline"; -export default function TrendingUsers({ title }: { title?: ReactNode }) { +export default function TrendingUsers({ title, count = 5 }: { title?: ReactNode; count?: number }) { const [userList, setUserList] = useState(); const [error, setError] = useState(); async function loadTrendingUsers() { const api = new NostrBandApi(); const users = await api.trendingProfiles(); - const keys = users.profiles.map(a => a.pubkey); + const keys = users.profiles.map(a => a.pubkey).slice(0, count); // Limit the user list to the count setUserList(keys); } diff --git a/packages/app/src/Pages/Layout/NavSidebar.tsx b/packages/app/src/Pages/Layout/NavSidebar.tsx index 32b85ae7..cb1ecbc5 100644 --- a/packages/app/src/Pages/Layout/NavSidebar.tsx +++ b/packages/app/src/Pages/Layout/NavSidebar.tsx @@ -1,12 +1,12 @@ import { LogoHeader } from "./LogoHeader"; -import {Link, useNavigate} from "react-router-dom"; +import { Link, useNavigate } from "react-router-dom"; import Icon from "@/Icons/Icon"; -import {ProfileLink} from "../../Element/User/ProfileLink"; +import { ProfileLink } from "../../Element/User/ProfileLink"; import Avatar from "../../Element/User/Avatar"; import useLogin from "../../Hooks/useLogin"; -import {useUserProfile} from "@snort/system-react"; -import {NoteCreatorButton} from "../../Element/Event/NoteCreatorButton"; -import {FormattedMessage} from "react-intl"; +import { useUserProfile } from "@snort/system-react"; +import { NoteCreatorButton } from "../../Element/Event/NoteCreatorButton"; +import { FormattedMessage } from "react-intl"; const MENU_ITEMS = [ { @@ -49,7 +49,7 @@ export default function NavSidebar() {
{MENU_ITEMS.map(item => { if (!item.nonLoggedIn && !publicKey) { - return ''; + return ""; } return ( - ) : ''} + ) : ( + "" + )}
); } diff --git a/packages/app/src/Pages/Layout/RightColumn.tsx b/packages/app/src/Pages/Layout/RightColumn.tsx index 04eecaae..c9172f45 100644 --- a/packages/app/src/Pages/Layout/RightColumn.tsx +++ b/packages/app/src/Pages/Layout/RightColumn.tsx @@ -1,11 +1,33 @@ -import SearchBox from "../../Element/SearchBox"; +import SearchBox from "@/Element/SearchBox"; +import TrendingUsers from "@/Element/TrendingUsers"; +import TrendingHashtags from "@/Element/TrendingHashtags"; +import TrendingNotes from "@/Element/TrendingPosts"; +import { FormattedMessage } from "react-intl"; export default function RightColumn() { return ( -
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
); } diff --git a/packages/app/src/Pages/settings/Root.tsx b/packages/app/src/Pages/settings/Root.tsx index df16e332..cd4dd022 100644 --- a/packages/app/src/Pages/settings/Root.tsx +++ b/packages/app/src/Pages/settings/Root.tsx @@ -16,9 +16,12 @@ const SettingsIndex = () => { const pageWidth = usePageWidth(); const sub = getCurrentSubscription(LoginStore.allSubscriptions()); - const handleNavigate = useCallback((path) => { - navigate(path); - }, [navigate]); + const handleNavigate = useCallback( + path => { + navigate(path); + }, + [navigate], + ); const handleLogout = useCallback(() => { logout(login.id); @@ -31,7 +34,10 @@ const SettingsIndex = () => { } }, [location, navigate, pageWidth]); - const [hideMenu, hideContent] = [location.pathname !== "/settings" && pageWidth < 768, location.pathname === "/settings" && pageWidth < 768]; + const [hideMenu, hideContent] = [ + location.pathname !== "/settings" && pageWidth < 768, + location.pathname === "/settings" && pageWidth < 768, + ]; const menuItems = [ { icon: "profile", message: messages.Profile, path: "profile" }, @@ -43,7 +49,7 @@ const SettingsIndex = () => { { icon: "wallet", message: "Wallet", id: "3yk8fB", path: "wallet" }, { icon: "heart", message: messages.Donate, path: "/donate" }, { icon: "hard-drive", message: "Cache", id: "DBiVK1", path: "cache" }, - { icon: "profile", message: messages.SocialGraph, path: "/graph" } + { icon: "profile", message: messages.SocialGraph, path: "/graph" }, ]; if (CONFIG.features.subscriptions) { diff --git a/packages/app/src/lang.json b/packages/app/src/lang.json index 6182470c..9bda7c2a 100644 --- a/packages/app/src/lang.json +++ b/packages/app/src/lang.json @@ -57,9 +57,6 @@ "00LcfG": { "defaultMessage": "Load more" }, - "08zn6O": { - "defaultMessage": "Export Keys" - }, "0Azlrb": { "defaultMessage": "Manage" }, @@ -159,9 +156,6 @@ "3tVy+Z": { "defaultMessage": "{n} Followers" }, - "3yk8fB": { - "defaultMessage": "Wallet" - }, "450Fty": { "defaultMessage": "None" }, @@ -234,6 +228,9 @@ "6ewQqw": { "defaultMessage": "Likes ({n})" }, + "6k7xfM": { + "defaultMessage": "Trending notes" + }, "6uMqL1": { "defaultMessage": "Unpaid" }, @@ -243,9 +240,6 @@ "712i26": { "defaultMessage": "Proxy uses HODL invoices to forward the payment, which hides the pubkey of your node" }, - "7BX/yC": { - "defaultMessage": "Account Switcher" - }, "7UOvbT": { "defaultMessage": "Offline" }, @@ -261,6 +255,9 @@ "8ED/4u": { "defaultMessage": "Reply To" }, + "8HJxXG": { + "defaultMessage": "Sign up" + }, "8QDesP": { "defaultMessage": "Zap {n} sats" }, @@ -368,6 +365,9 @@ "CVWeJ6": { "defaultMessage": "Trending People" }, + "CbM2hK": { + "defaultMessage": "Trending hashtags" + }, "CmZ9ls": { "defaultMessage": "{n} Muted" }, @@ -729,9 +729,6 @@ "Qxv0B2": { "defaultMessage": "You currently have {number} sats in your zap pool." }, - "R/6nsx": { - "defaultMessage": "Subscription" - }, "R81upa": { "defaultMessage": "People you follow" }, @@ -940,6 +937,9 @@ "aWpBzj": { "defaultMessage": "Show more" }, + "arZnG2": { + "defaultMessage": "Trending users" + }, "b12Goz": { "defaultMessage": "Mnemonic" }, @@ -1458,9 +1458,6 @@ "wih7iJ": { "defaultMessage": "name is blocked" }, - "wofVHy": { - "defaultMessage": "Moderation" - }, "wqyN/i": { "defaultMessage": "Find out more info about {service} at {link}" }, diff --git a/packages/app/src/translations/en.json b/packages/app/src/translations/en.json index 1d8a8cb7..ae58caaf 100644 --- a/packages/app/src/translations/en.json +++ b/packages/app/src/translations/en.json @@ -18,7 +18,6 @@ "/d6vEc": "Make your profile easier to find and share", "/n5KSF": "{n} ms", "00LcfG": "Load more", - "08zn6O": "Export Keys", "0Azlrb": "Manage", "0BUTMv": "Search...", "0HFX0T": "Use Exact Location", @@ -52,7 +51,6 @@ "3qnJlS": "You are voting with {amount} sats", "3t3kok": "{n,plural,=1{{n} new note} other{{n} new notes}}", "3tVy+Z": "{n} Followers", - "3yk8fB": "Wallet", "450Fty": "None", "47FYwb": "Cancel", "4IPzdn": "Primary Developers", @@ -77,15 +75,16 @@ "6TfgXX": "{site} is an open source project built by passionate people in their free time", "6bgpn+": "Not all clients support this, you may still receive some zaps as if zap splits was not configured", "6ewQqw": "Likes ({n})", + "6k7xfM": "Trending notes", "6uMqL1": "Unpaid", "7+Domh": "Notes", "712i26": "Proxy uses HODL invoices to forward the payment, which hides the pubkey of your node", - "7BX/yC": "Account Switcher", "7UOvbT": "Offline", "7hp70g": "NIP-05", "8/vBbP": "Reposts ({n})", "89q5wc": "Confirm Reposts", "8ED/4u": "Reply To", + "8HJxXG": "Sign up", "8QDesP": "Zap {n} sats", "8Rkoyb": "Recipient", "8Y6bZQ": "Invalid zap split: {input}", @@ -121,6 +120,7 @@ "C8HhVE": "Suggested Follows", "CHTbO3": "Failed to load invoice", "CVWeJ6": "Trending People", + "CbM2hK": "Trending hashtags", "CmZ9ls": "{n} Muted", "CsCUYo": "{n} sats", "Cu/K85": "Translated from {lang}", @@ -240,7 +240,6 @@ "QDFTjG": "{n} Relays", "QWhotP": "Zap Pool only works if you use one of the supported wallet connections (WebLN, LNC, LNDHub or Nostr Wallet Connect)", "Qxv0B2": "You currently have {number} sats in your zap pool.", - "R/6nsx": "Subscription", "R81upa": "People you follow", "RSr2uB": "Username must only contain lowercase letters and numbers", "RahCRH": "Expired", @@ -309,6 +308,7 @@ "aHje0o": "Name or nym", "aMaLBK": "Supported Extensions", "aWpBzj": "Show more", + "arZnG2": "Trending users", "b12Goz": "Mnemonic", "b5vAk0": "Your handle will act like a lightning address and will redirect to your chosen LNURL or Lightning address", "bLZL5a": "Get Address", @@ -480,7 +480,6 @@ "wSZR47": "Submit", "wWLwvh": "Anon", "wih7iJ": "name is blocked", - "wofVHy": "Moderation", "wqyN/i": "Find out more info about {service} at {link}", "wtLjP6": "Copy ID", "x/Fx2P": "Fund the services that you use by splitting a portion of all your zaps into a pool of funds!", From e97b9bdba4ce33fc11bb35feba8b3d9e6df974df Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Wed, 22 Nov 2023 14:13:40 +0200 Subject: [PATCH 16/66] scrollable trending column --- packages/app/src/Pages/Layout/RightColumn.tsx | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/packages/app/src/Pages/Layout/RightColumn.tsx b/packages/app/src/Pages/Layout/RightColumn.tsx index c9172f45..9204754a 100644 --- a/packages/app/src/Pages/Layout/RightColumn.tsx +++ b/packages/app/src/Pages/Layout/RightColumn.tsx @@ -6,27 +6,29 @@ import { FormattedMessage } from "react-intl"; export default function RightColumn() { return ( -
-
+
+
-
-
- +
+
+
+ +
+
- -
-
-
- +
+
+ +
+
- -
-
-
- +
+
+ +
+
-
); From ced63ab6d16e83c9455b849c59077a263e9b322f Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Wed, 22 Nov 2023 14:25:43 +0200 Subject: [PATCH 17/66] new note text in sidebar btn --- .../src/Element/Event/NoteCreatorButton.tsx | 18 ++++++++++++++++-- packages/app/src/Pages/Layout/NavSidebar.tsx | 2 +- packages/app/src/lang.json | 3 +++ packages/app/src/translations/en.json | 1 + 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/packages/app/src/Element/Event/NoteCreatorButton.tsx b/packages/app/src/Element/Event/NoteCreatorButton.tsx index f044ae03..107bf543 100644 --- a/packages/app/src/Element/Event/NoteCreatorButton.tsx +++ b/packages/app/src/Element/Event/NoteCreatorButton.tsx @@ -9,8 +9,17 @@ import useLogin from "@/Hooks/useLogin"; import Icon from "@/Icons/Icon"; import { useNoteCreator } from "@/State/NoteCreator"; import { NoteCreator } from "./NoteCreator"; +import { FormattedMessage } from "react-intl"; -export const NoteCreatorButton = ({ className, alwaysShow }: { className?: string; alwaysShow?: boolean }) => { +export const NoteCreatorButton = ({ + className, + alwaysShow, + showText, +}: { + className?: string; + alwaysShow?: boolean; + showText?: boolean; +}) => { const buttonRef = useRef(null); const location = useLocation(); const { readonly } = useLogin(s => ({ readonly: s.readonly })); @@ -51,7 +60,7 @@ export const NoteCreatorButton = ({ className, alwaysShow }: { className?: strin {!shouldHideNoteCreator && ( )} diff --git a/packages/app/src/Pages/Layout/NavSidebar.tsx b/packages/app/src/Pages/Layout/NavSidebar.tsx index cb1ecbc5..001c551c 100644 --- a/packages/app/src/Pages/Layout/NavSidebar.tsx +++ b/packages/app/src/Pages/Layout/NavSidebar.tsx @@ -64,7 +64,7 @@ export default function NavSidebar() { })} {publicKey ? (
- +
) : (
diff --git a/packages/app/src/lang.json b/packages/app/src/lang.json index 9bda7c2a..c01b4437 100644 --- a/packages/app/src/lang.json +++ b/packages/app/src/lang.json @@ -129,6 +129,9 @@ "2k0Cv+": { "defaultMessage": "Dislikes ({n})" }, + "2mcwT8": { + "defaultMessage": "New Note" + }, "2ukA4d": { "defaultMessage": "{n} hours" }, diff --git a/packages/app/src/translations/en.json b/packages/app/src/translations/en.json index ae58caaf..13e79805 100644 --- a/packages/app/src/translations/en.json +++ b/packages/app/src/translations/en.json @@ -42,6 +42,7 @@ "2O2sfp": "Finish", "2a2YiP": "{n} Bookmarks", "2k0Cv+": "Dislikes ({n})", + "2mcwT8": "New Note", "2ukA4d": "{n} hours", "2zJXeA": "Profiles", "39AHJm": "Sign Up", From 28bf0ea581a26058dad81b4c8f9ac4b07db5d783 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Wed, 22 Nov 2023 14:31:08 +0200 Subject: [PATCH 18/66] sticky right column --- packages/app/src/Pages/Layout/RightColumn.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/app/src/Pages/Layout/RightColumn.tsx b/packages/app/src/Pages/Layout/RightColumn.tsx index 9204754a..fe9dd7df 100644 --- a/packages/app/src/Pages/Layout/RightColumn.tsx +++ b/packages/app/src/Pages/Layout/RightColumn.tsx @@ -6,11 +6,11 @@ import { FormattedMessage } from "react-intl"; export default function RightColumn() { return ( -
-
+
+
-
+
{/* Adjusted for scrollbar and spacing */}
From e788e01c6d04726dbefb94886ddab318e1894630 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Wed, 22 Nov 2023 15:02:45 +0200 Subject: [PATCH 19/66] sticky header in mobile size --- packages/app/src/Pages/Layout/index.tsx | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/packages/app/src/Pages/Layout/index.tsx b/packages/app/src/Pages/Layout/index.tsx index e1382465..08d0b8e4 100644 --- a/packages/app/src/Pages/Layout/index.tsx +++ b/packages/app/src/Pages/Layout/index.tsx @@ -56,9 +56,12 @@ export default function Index() { return (
+ {!shouldHideHeader &&
}
- +
+ +
@@ -72,18 +75,9 @@ export default function Index() { ); } -function MainContent({ shouldHideHeader }) { - return ( -
- {!shouldHideHeader &&
} - -
- ); -} - function Header() { return ( -
+
From c5bc1cdbe7402e674a847f5e1c4e89f1c8200b85 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Wed, 22 Nov 2023 15:13:33 +0200 Subject: [PATCH 20/66] app icon in navbar --- packages/app/config/default.json | 1 + packages/app/config/iris.json | 1 + packages/app/custom.d.ts | 1 + packages/app/public/iris/img/icon128.png | Bin 0 -> 15042 bytes packages/app/src/Pages/Layout/LogoHeader.tsx | 9 ++++++--- 5 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 packages/app/public/iris/img/icon128.png diff --git a/packages/app/config/default.json b/packages/app/config/default.json index c0db1394..0ff86e0b 100644 --- a/packages/app/config/default.json +++ b/packages/app/config/default.json @@ -6,6 +6,7 @@ "nip05Domain": "snort.social", "favicon": "public/favicon.ico", "appleTouchIconUrl": "/nostrich_512.png", + "navLogo": "/nostrich_256.png", "publicDir": "public/snort", "httpCache": "", "animalNamePlaceholders": false, diff --git a/packages/app/config/iris.json b/packages/app/config/iris.json index 18eb7149..a117f1fe 100644 --- a/packages/app/config/iris.json +++ b/packages/app/config/iris.json @@ -6,6 +6,7 @@ "nip05Domain": "iris.to", "favicon": "public/iris/favicon.ico", "appleTouchIconUrl": "/img/apple-touch-icon.png", + "navLogo": "/img/icon128.png", "publicDir": "public/iris", "httpCache": "https://api.iris.to", "animalNamePlaceholders": true, diff --git a/packages/app/custom.d.ts b/packages/app/custom.d.ts index dc8d941f..2cf23a10 100644 --- a/packages/app/custom.d.ts +++ b/packages/app/custom.d.ts @@ -48,6 +48,7 @@ declare const CONFIG: { nip05Domain: string; favicon: string; appleTouchIconUrl: string; + navLogo: string; httpCache: string; animalNamePlaceholders: boolean; defaultZapPoolFee?: number; diff --git a/packages/app/public/iris/img/icon128.png b/packages/app/public/iris/img/icon128.png new file mode 100644 index 0000000000000000000000000000000000000000..9546ad506bc11f3d06789967ce65ad9d53b7fb2a GIT binary patch literal 15042 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 C+hfcC literal 0 HcmV?d00001 diff --git a/packages/app/src/Pages/Layout/LogoHeader.tsx b/packages/app/src/Pages/Layout/LogoHeader.tsx index 43c6774a..57910bd8 100644 --- a/packages/app/src/Pages/Layout/LogoHeader.tsx +++ b/packages/app/src/Pages/Layout/LogoHeader.tsx @@ -15,9 +15,12 @@ export function LogoHeader() { return ( -

- {extra()} - {CONFIG.appName} +

+ +
+ {extra()} + {CONFIG.appName} +

{currentSubscription && (
From 131e564bd00bec80f7073d90ce15ea3337ffeee4 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Wed, 22 Nov 2023 15:24:30 +0200 Subject: [PATCH 21/66] left nav layout --- packages/app/src/Pages/Layout/NavSidebar.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/app/src/Pages/Layout/NavSidebar.tsx b/packages/app/src/Pages/Layout/NavSidebar.tsx index 001c551c..80bfbba3 100644 --- a/packages/app/src/Pages/Layout/NavSidebar.tsx +++ b/packages/app/src/Pages/Layout/NavSidebar.tsx @@ -43,7 +43,7 @@ export default function NavSidebar() { const navigate = useNavigate(); return ( -
+
@@ -55,10 +55,10 @@ export default function NavSidebar() { - {item.label} + {item.label} ); })} @@ -70,7 +70,7 @@ export default function NavSidebar() {
@@ -83,7 +83,7 @@ export default function NavSidebar() {
- {profile?.name} + {profile?.name}
From 55fae3aa4155573471fae56a976e91aead0073d1 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Wed, 22 Nov 2023 16:13:36 +0200 Subject: [PATCH 22/66] restore useLoginFeed --- packages/app/src/Pages/Layout/index.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/app/src/Pages/Layout/index.tsx b/packages/app/src/Pages/Layout/index.tsx index 08d0b8e4..948355a8 100644 --- a/packages/app/src/Pages/Layout/index.tsx +++ b/packages/app/src/Pages/Layout/index.tsx @@ -16,6 +16,7 @@ import NavSidebar from "./NavSidebar"; import AccountHeader from "./AccountHeader"; import RightColumn from "./RightColumn"; import { LogoHeader } from "./LogoHeader"; +import useLoginFeed from "@/Feed/LoginFeed"; export default function Index() { const location = useLocation(); @@ -24,6 +25,7 @@ export default function Index() { useTheme(); useLoginRelays(); + useLoginFeed(); const hideHeaderPaths = ["/login", "/new"]; const shouldHideHeader = hideHeaderPaths.some(path => location.pathname.startsWith(path)); From 1af8316453bd92822696c49bb391d4da8366d582 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Wed, 22 Nov 2023 16:45:39 +0200 Subject: [PATCH 23/66] add Deck nav link --- packages/app/src/Pages/Layout/LogoHeader.tsx | 6 +++++- packages/app/src/Pages/Layout/NavSidebar.tsx | 5 +++++ packages/app/src/icons.svg | 4 ++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/app/src/Pages/Layout/LogoHeader.tsx b/packages/app/src/Pages/Layout/LogoHeader.tsx index 57910bd8..4562bc96 100644 --- a/packages/app/src/Pages/Layout/LogoHeader.tsx +++ b/packages/app/src/Pages/Layout/LogoHeader.tsx @@ -13,8 +13,12 @@ export function LogoHeader() { if (isChristmas()) return "🎄"; }; + const handleLogoClick = () => { + window.scrollTo({ top: 0 }); + }; + return ( - +

diff --git a/packages/app/src/Pages/Layout/NavSidebar.tsx b/packages/app/src/Pages/Layout/NavSidebar.tsx index 80bfbba3..e17e0074 100644 --- a/packages/app/src/Pages/Layout/NavSidebar.tsx +++ b/packages/app/src/Pages/Layout/NavSidebar.tsx @@ -25,6 +25,11 @@ const MENU_ITEMS = [ icon: "bell-02", link: "/notifications", }, + { + label: "Deck", + icon: "deck", + link: "/deck", + }, { label: "Settings", icon: "settings", diff --git a/packages/app/src/icons.svg b/packages/app/src/icons.svg index 4ed62511..9b17e2b4 100644 --- a/packages/app/src/icons.svg +++ b/packages/app/src/icons.svg @@ -395,5 +395,9 @@ + + + + \ No newline at end of file From de524b50fc78187175ef368a02afd8f76b971d20 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Wed, 22 Nov 2023 17:10:00 +0200 Subject: [PATCH 24/66] make whole page element scrollable --- packages/app/src/Pages/Layout/LogoHeader.tsx | 2 +- packages/app/src/Pages/Layout/index.tsx | 10 +++++----- packages/app/src/index.css | 4 ---- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/app/src/Pages/Layout/LogoHeader.tsx b/packages/app/src/Pages/Layout/LogoHeader.tsx index 4562bc96..4641afaf 100644 --- a/packages/app/src/Pages/Layout/LogoHeader.tsx +++ b/packages/app/src/Pages/Layout/LogoHeader.tsx @@ -14,7 +14,7 @@ export function LogoHeader() { }; const handleLogoClick = () => { - window.scrollTo({ top: 0 }); + window.scrollTo({ top: 0, behavior: "instant" }); }; return ( diff --git a/packages/app/src/Pages/Layout/index.tsx b/packages/app/src/Pages/Layout/index.tsx index 948355a8..89b18e76 100644 --- a/packages/app/src/Pages/Layout/index.tsx +++ b/packages/app/src/Pages/Layout/index.tsx @@ -47,7 +47,7 @@ export default function Index() { const handleKeyboardShortcut = useCallback(event => { if (event.target && !isFormElement(event.target as HTMLElement)) { event.preventDefault(); - window.scrollTo({ top: 0, behavior: "smooth" }); + window.scrollTo({ top: 0, behavior: "instant" }); } }, []); @@ -56,15 +56,15 @@ export default function Index() { const isStalker = !!stalker; return ( -
-
+
+
{!shouldHideHeader &&
}
- +
- +
diff --git a/packages/app/src/index.css b/packages/app/src/index.css index 10f078ac..5a827e94 100644 --- a/packages/app/src/index.css +++ b/packages/app/src/index.css @@ -132,10 +132,6 @@ a.ext { overflow-wrap: break-word; } -#root { - overflow-x: hidden; -} - .b { border: 1px solid var(--border-color); } From b52b84e4667d2a3e8854fb08f1638644e756be95 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Wed, 22 Nov 2023 17:15:01 +0200 Subject: [PATCH 25/66] deck icon --- packages/app/src/icons.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app/src/icons.svg b/packages/app/src/icons.svg index 9b17e2b4..9fa39a97 100644 --- a/packages/app/src/icons.svg +++ b/packages/app/src/icons.svg @@ -395,7 +395,7 @@ - + From 90c00c5fa4ef2ec2e2181ea585bda48ad3e5e115 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Wed, 22 Nov 2023 17:28:22 +0200 Subject: [PATCH 26/66] TrendingUsers and Hashtags default count Infinity --- packages/app/src/Element/TrendingHashtags.tsx | 2 +- packages/app/src/Element/TrendingUsers.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/app/src/Element/TrendingHashtags.tsx b/packages/app/src/Element/TrendingHashtags.tsx index dfce3eca..572dfbb9 100644 --- a/packages/app/src/Element/TrendingHashtags.tsx +++ b/packages/app/src/Element/TrendingHashtags.tsx @@ -6,7 +6,7 @@ import { ErrorOrOffline } from "./ErrorOrOffline"; import { HashTagHeader } from "@/Pages/HashTagsPage"; import { useLocale } from "@/IntlProvider"; -export default function TrendingHashtags({ title, count = 5 }: { title?: ReactNode; count?: number }) { +export default function TrendingHashtags({ title, count = Infinity }: { title?: ReactNode; count?: number }) { const [hashtags, setHashtags] = useState>(); const [error, setError] = useState(); const { lang } = useLocale(); diff --git a/packages/app/src/Element/TrendingUsers.tsx b/packages/app/src/Element/TrendingUsers.tsx index 86579469..db8ecf29 100644 --- a/packages/app/src/Element/TrendingUsers.tsx +++ b/packages/app/src/Element/TrendingUsers.tsx @@ -6,7 +6,7 @@ import PageSpinner from "@/Element/PageSpinner"; import NostrBandApi from "@/External/NostrBand"; import { ErrorOrOffline } from "./ErrorOrOffline"; -export default function TrendingUsers({ title, count = 5 }: { title?: ReactNode; count?: number }) { +export default function TrendingUsers({ title, count = Infinity }: { title?: ReactNode; count?: number }) { const [userList, setUserList] = useState(); const [error, setError] = useState(); From 62e99a4ed4ef76ea371137b7364da105413889cb Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Wed, 22 Nov 2023 18:14:34 +0200 Subject: [PATCH 27/66] right column trending bg --- packages/app/src/Pages/Layout/RightColumn.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/app/src/Pages/Layout/RightColumn.tsx b/packages/app/src/Pages/Layout/RightColumn.tsx index fe9dd7df..278d5e94 100644 --- a/packages/app/src/Pages/Layout/RightColumn.tsx +++ b/packages/app/src/Pages/Layout/RightColumn.tsx @@ -6,25 +6,25 @@ import { FormattedMessage } from "react-intl"; export default function RightColumn() { return ( -
+
-
{/* Adjusted for scrollbar and spacing */} -
-
+
+
+
-
-
+
+
-
-
+
+
From f3eb414c6a636febbc81645895f7545c2ec34ee8 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Thu, 23 Nov 2023 09:52:19 +0200 Subject: [PATCH 28/66] hide right col scrollbar --- packages/app/src/Pages/Layout/RightColumn.tsx | 2 +- packages/app/src/index.css | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/app/src/Pages/Layout/RightColumn.tsx b/packages/app/src/Pages/Layout/RightColumn.tsx index 278d5e94..f393602f 100644 --- a/packages/app/src/Pages/Layout/RightColumn.tsx +++ b/packages/app/src/Pages/Layout/RightColumn.tsx @@ -10,7 +10,7 @@ export default function RightColumn() {
-
+
diff --git a/packages/app/src/index.css b/packages/app/src/index.css index 5a827e94..10bb056a 100644 --- a/packages/app/src/index.css +++ b/packages/app/src/index.css @@ -936,3 +936,12 @@ svg.zap-solid { .light .modal button.secondary:hover { background: #fff !important; } + +.hide-scrollbar { + scrollbar-width: none; + -ms-overflow-style: none; +} + +.hide-scrollbar::-webkit-scrollbar { + display: none; /* Safari and Chrome */ +} \ No newline at end of file From bfc42bcd3661779c1aa063cc0c95d5409fed89ba Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Thu, 23 Nov 2023 10:14:41 +0200 Subject: [PATCH 29/66] add search icon to navbar --- packages/app/src/Pages/Layout/NavSidebar.tsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/app/src/Pages/Layout/NavSidebar.tsx b/packages/app/src/Pages/Layout/NavSidebar.tsx index e17e0074..169e3759 100644 --- a/packages/app/src/Pages/Layout/NavSidebar.tsx +++ b/packages/app/src/Pages/Layout/NavSidebar.tsx @@ -16,15 +16,20 @@ const MENU_ITEMS = [ nonLoggedIn: true, }, { - label: "Messages", - icon: "mail", - link: "/messages", + label: "Search", + icon: "search", + link: "/search", }, { label: "Notifications", icon: "bell-02", link: "/notifications", }, + { + label: "Messages", + icon: "mail", + link: "/messages", + }, { label: "Deck", icon: "deck", From 7e69e9a42a621680a24349da68e6871ac9d11eb2 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Thu, 23 Nov 2023 10:31:19 +0200 Subject: [PATCH 30/66] active nav item style --- packages/app/src/Pages/Layout/NavSidebar.tsx | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/packages/app/src/Pages/Layout/NavSidebar.tsx b/packages/app/src/Pages/Layout/NavSidebar.tsx index 169e3759..53eb2531 100644 --- a/packages/app/src/Pages/Layout/NavSidebar.tsx +++ b/packages/app/src/Pages/Layout/NavSidebar.tsx @@ -1,5 +1,5 @@ import { LogoHeader } from "./LogoHeader"; -import { Link, useNavigate } from "react-router-dom"; +import { NavLink, useNavigate } from "react-router-dom"; import Icon from "@/Icons/Icon"; import { ProfileLink } from "../../Element/User/ProfileLink"; import Avatar from "../../Element/User/Avatar"; @@ -42,6 +42,12 @@ const MENU_ITEMS = [ }, ]; +const getNavLinkClass = (isActive: boolean) => { + return isActive ? + "xl:ml-1 py-4 hover:no-underline flex flex-row items-center text-nostr-purple" : + "xl:ml-1 py-4 hover:no-underline hover:text-nostr-purple flex flex-row items-center"; +}; + export default function NavSidebar() { const { publicKey } = useLogin(s => ({ publicKey: s.publicKey, @@ -65,8 +71,7 @@ export default function NavSidebar() { + className={({ isActive }) => getNavLinkClass(isActive)}> {item.label} @@ -103,11 +108,3 @@ export default function NavSidebar() {
); } - -function NavLink({ children, ...props }) { - return ( - - {children} - - ); -} From ef776064271a44f33be5cae686eb8735f2a3e068 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Thu, 23 Nov 2023 10:57:28 +0200 Subject: [PATCH 31/66] active settings menu item style --- packages/app/src/Pages/settings/Root.css | 1 + packages/app/src/Pages/settings/Root.tsx | 22 ++++++++++++---------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/packages/app/src/Pages/settings/Root.css b/packages/app/src/Pages/settings/Root.css index 434ebed1..d9fd3bdc 100644 --- a/packages/app/src/Pages/settings/Root.css +++ b/packages/app/src/Pages/settings/Root.css @@ -49,6 +49,7 @@ } .settings-row:hover, +.settings-row.active, .settings-group-header:hover { color: var(--highlight); } diff --git a/packages/app/src/Pages/settings/Root.tsx b/packages/app/src/Pages/settings/Root.tsx index cd4dd022..f004344d 100644 --- a/packages/app/src/Pages/settings/Root.tsx +++ b/packages/app/src/Pages/settings/Root.tsx @@ -1,7 +1,7 @@ import "./Root.css"; import { useCallback, useEffect } from "react"; import { FormattedMessage } from "react-intl"; -import { Outlet, useLocation, useNavigate } from "react-router-dom"; +import {Outlet, NavLink, useNavigate, useLocation} from "react-router-dom"; import Icon from "@/Icons/Icon"; import { LoginStore, logout } from "@/Login"; import useLogin from "@/Hooks/useLogin"; @@ -16,13 +16,6 @@ const SettingsIndex = () => { const pageWidth = usePageWidth(); const sub = getCurrentSubscription(LoginStore.allSubscriptions()); - const handleNavigate = useCallback( - path => { - navigate(path); - }, - [navigate], - ); - const handleLogout = useCallback(() => { logout(login.id); navigate("/"); @@ -64,16 +57,25 @@ const SettingsIndex = () => { menuItems.push({ icon: "code-circle", message: "Account Switcher", id: "7BX/yC", path: "accounts" }); } + const getNavLinkClass = ({ isActive }: { isActive: boolean }) => { + return isActive ? "settings-row active" : "settings-row"; + }; + return (
{!hideMenu && (
{menuItems.map(({ icon, message, id, path }) => ( -
handleNavigate(path)} key={path}> + -
+ ))}
From 4eb0408c2780c8cef65d5e72c6488ca64db3e4b6 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Thu, 23 Nov 2023 11:01:17 +0200 Subject: [PATCH 32/66] use same navbar in deck view --- .../app/src/Element/{Deck => }/Articles.tsx | 2 +- packages/app/src/Element/Deck/Nav.css | 12 ------ packages/app/src/Element/Deck/Nav.tsx | 38 ------------------- .../src/Element/Event/NoteCreatorButton.tsx | 2 +- packages/app/src/Pages/DeckLayout.tsx | 6 +-- packages/app/src/Pages/Layout/NavSidebar.tsx | 11 ++---- packages/app/src/Pages/settings/Root.tsx | 9 +---- packages/app/src/index.css | 4 +- 8 files changed, 13 insertions(+), 71 deletions(-) rename packages/app/src/Element/{Deck => }/Articles.tsx (96%) delete mode 100644 packages/app/src/Element/Deck/Nav.css delete mode 100644 packages/app/src/Element/Deck/Nav.tsx diff --git a/packages/app/src/Element/Deck/Articles.tsx b/packages/app/src/Element/Articles.tsx similarity index 96% rename from packages/app/src/Element/Deck/Articles.tsx rename to packages/app/src/Element/Articles.tsx index 4cd8d6ca..0cc436cb 100644 --- a/packages/app/src/Element/Deck/Articles.tsx +++ b/packages/app/src/Element/Articles.tsx @@ -3,7 +3,7 @@ import { useReactions } from "@snort/system-react"; import { useArticles } from "@/Feed/ArticlesFeed"; import { orderDescending } from "@/SnortUtils"; -import Note from "../Event/Note"; +import Note from "./Event/Note"; import { useContext } from "react"; import { DeckContext } from "@/Pages/DeckLayout"; diff --git a/packages/app/src/Element/Deck/Nav.css b/packages/app/src/Element/Deck/Nav.css deleted file mode 100644 index 2c707da0..00000000 --- a/packages/app/src/Element/Deck/Nav.css +++ /dev/null @@ -1,12 +0,0 @@ -nav.deck { - width: 48px; - height: calc(100vh - 20px); - padding: 10px 8px; - border-right: 1px solid var(--border-color); - text-align: center; -} - -nav.deck .avatar { - width: 40px; - height: 40px; -} diff --git a/packages/app/src/Element/Deck/Nav.tsx b/packages/app/src/Element/Deck/Nav.tsx deleted file mode 100644 index 784caf2f..00000000 --- a/packages/app/src/Element/Deck/Nav.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { useUserProfile } from "@snort/system-react"; -import Avatar from "@/Element/User/Avatar"; -import useLogin from "@/Hooks/useLogin"; -import "./Nav.css"; -import Icon from "@/Icons/Icon"; -import { Link } from "react-router-dom"; -import { NoteCreatorButton } from "@/Element/Event/NoteCreatorButton"; -import { ProfileLink } from "@/Element/User/ProfileLink"; - -export function DeckNav() { - const { publicKey } = useLogin(); - const profile = useUserProfile(publicKey); - - const unreadDms = 0; - - return ( - - ); -} diff --git a/packages/app/src/Element/Event/NoteCreatorButton.tsx b/packages/app/src/Element/Event/NoteCreatorButton.tsx index 107bf543..b569791f 100644 --- a/packages/app/src/Element/Event/NoteCreatorButton.tsx +++ b/packages/app/src/Element/Event/NoteCreatorButton.tsx @@ -60,7 +60,7 @@ export const NoteCreatorButton = ({ {!shouldHideNoteCreator && (
)} @@ -95,7 +99,7 @@ export default function NavSidebar() {
- {profile?.name} + {!narrow && {profile?.name}}
From a0151745bf2d0de69894701c5758b98d87d100c6 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Thu, 23 Nov 2023 11:41:38 +0200 Subject: [PATCH 34/66] mv social graph link from settings menu to nav --- packages/app/src/Pages/Layout/NavSidebar.tsx | 5 +++++ packages/app/src/Pages/settings/Root.tsx | 1 - packages/app/src/icons.svg | 10 +++++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/app/src/Pages/Layout/NavSidebar.tsx b/packages/app/src/Pages/Layout/NavSidebar.tsx index 0b8fbfa3..7255bcb4 100644 --- a/packages/app/src/Pages/Layout/NavSidebar.tsx +++ b/packages/app/src/Pages/Layout/NavSidebar.tsx @@ -36,6 +36,11 @@ const MENU_ITEMS = [ icon: "deck", link: "/deck", }, + { + label: "Social Graph", + icon: "graph", + link: "/graph", + }, { label: "Settings", icon: "settings", diff --git a/packages/app/src/Pages/settings/Root.tsx b/packages/app/src/Pages/settings/Root.tsx index af5a3761..51ba3ad7 100644 --- a/packages/app/src/Pages/settings/Root.tsx +++ b/packages/app/src/Pages/settings/Root.tsx @@ -42,7 +42,6 @@ const SettingsIndex = () => { { icon: "wallet", message: "Wallet", id: "3yk8fB", path: "wallet" }, { icon: "heart", message: messages.Donate, path: "/donate" }, { icon: "hard-drive", message: "Cache", id: "DBiVK1", path: "cache" }, - { icon: "profile", message: messages.SocialGraph, path: "/graph" }, ]; if (CONFIG.features.subscriptions) { diff --git a/packages/app/src/icons.svg b/packages/app/src/icons.svg index 9fa39a97..e6fc4acb 100644 --- a/packages/app/src/icons.svg +++ b/packages/app/src/icons.svg @@ -390,7 +390,7 @@ - + @@ -399,5 +399,13 @@ + + + + + + + + \ No newline at end of file From 6bef3ccf58aedc5c6d4b490de4834325ab954446 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Thu, 23 Nov 2023 11:43:55 +0200 Subject: [PATCH 35/66] remove link directional particles from social graph --- packages/app/src/Pages/NetworkGraph.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app/src/Pages/NetworkGraph.tsx b/packages/app/src/Pages/NetworkGraph.tsx index e0fa4f10..699e9858 100644 --- a/packages/app/src/Pages/NetworkGraph.tsx +++ b/packages/app/src/Pages/NetworkGraph.tsx @@ -239,7 +239,7 @@ const NetworkGraph = () => { nodeLabel={node => `${node.profile?.name || node.address}`} nodeAutoColorBy="distance" linkAutoColorBy="distance" - linkDirectionalParticles={1} + linkDirectionalParticles={0} nodeVisibility="visible" numDimensions={3} linkDirectionalArrowLength={0} From 29bba9aef37cb18cf0199919aaf15f65bf881975 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Thu, 23 Nov 2023 11:51:44 +0200 Subject: [PATCH 36/66] close graph on esc --- packages/app/src/Pages/Layout/LogoHeader.tsx | 10 ++++--- packages/app/src/Pages/Layout/NavSidebar.tsx | 17 ++++++++---- packages/app/src/Pages/NetworkGraph.tsx | 29 ++++++++++++++++++-- packages/app/src/lang.json | 3 ++ packages/app/src/translations/en.json | 1 + 5 files changed, 47 insertions(+), 13 deletions(-) diff --git a/packages/app/src/Pages/Layout/LogoHeader.tsx b/packages/app/src/Pages/Layout/LogoHeader.tsx index 0779353c..41a6433d 100644 --- a/packages/app/src/Pages/Layout/LogoHeader.tsx +++ b/packages/app/src/Pages/Layout/LogoHeader.tsx @@ -21,10 +21,12 @@ export function LogoHeader({ showText = false }) {

- {showText &&
- {extra()} - {CONFIG.appName} -
} + {showText && ( +
+ {extra()} + {CONFIG.appName} +
+ )}

{currentSubscription && (
diff --git a/packages/app/src/Pages/Layout/NavSidebar.tsx b/packages/app/src/Pages/Layout/NavSidebar.tsx index 7255bcb4..09325ca3 100644 --- a/packages/app/src/Pages/Layout/NavSidebar.tsx +++ b/packages/app/src/Pages/Layout/NavSidebar.tsx @@ -52,7 +52,7 @@ const getNavLinkClass = (isActive: boolean, narrow: boolean) => { const c = isActive ? "py-4 hover:no-underline flex flex-row items-center text-nostr-purple" : "py-4 hover:no-underline hover:text-nostr-purple flex flex-row items-center"; - return classNames(c, { "xl:ml-1": !narrow }) + return classNames(c, { "xl:ml-1": !narrow }); }; export default function NavSidebar({ narrow = false }) { @@ -65,13 +65,16 @@ export default function NavSidebar({ narrow = false }) { const profile = useUserProfile(publicKey); const navigate = useNavigate(); - const className = classNames({"xl:w-56 xl:gap-3 xl:items-start": !narrow}, "sticky items-center border-r border-neutral-900 top-0 z-20 h-screen max-h-screen hidden md:flex flex-col px-2 py-4 flex-shrink-0 gap-2") + const className = classNames( + { "xl:w-56 xl:gap-3 xl:items-start": !narrow }, + "sticky items-center border-r border-neutral-900 top-0 z-20 h-screen max-h-screen hidden md:flex flex-col px-2 py-4 flex-shrink-0 gap-2", + ); return (
-
+
{MENU_ITEMS.map(item => { if (!item.nonLoggedIn && !publicKey) { return ""; @@ -91,9 +94,11 @@ export default function NavSidebar({ narrow = false }) {
)} diff --git a/packages/app/src/Pages/NetworkGraph.tsx b/packages/app/src/Pages/NetworkGraph.tsx index 699e9858..8e4506c3 100644 --- a/packages/app/src/Pages/NetworkGraph.tsx +++ b/packages/app/src/Pages/NetworkGraph.tsx @@ -6,6 +6,8 @@ import * as THREE from "three"; import { defaultAvatar } from "../SnortUtils"; import { proxyImg } from "@/Hooks/useImgProxy"; import { LoginStore } from "@/Login"; +import { FormattedMessage } from "react-intl"; +import Icon from "@/Icons/Icon"; interface GraphNode { id: UID; @@ -71,6 +73,27 @@ const NetworkGraph = () => { // const [direction, setDirection] = useState(Direction.OUTBOUND); // const [renderLimit, setRenderLimit] = useState(NODE_LIMIT); + const handleCloseGraph = () => { + setOpen(false); + }; + + const handleKeyDown = (event: { key: string; }) => { + if (event.key === "Escape") { + handleCloseGraph(); + } + }; + + useEffect(() => { + if (open) { + window.addEventListener("keydown", handleKeyDown); + } + + // Cleanup function to remove the event listener + return () => { + window.removeEventListener("keydown", handleKeyDown); + }; + }, [open]); + const updateConfig = async (changes: Partial) => { setGraphConfig(old => { const newConfig = Object.assign({}, old, changes); @@ -197,13 +220,13 @@ const NetworkGraph = () => { setOpen(true); refreshData(); }}> - Show graph + )} {open && graphData && (
-
Degrees of separation
diff --git a/packages/app/src/lang.json b/packages/app/src/lang.json index c01b4437..137191e8 100644 --- a/packages/app/src/lang.json +++ b/packages/app/src/lang.json @@ -1122,6 +1122,9 @@ "hY4lzx": { "defaultMessage": "Supports" }, + "ha8JKG": { + "defaultMessage": "Show graph" + }, "hicxcO": { "defaultMessage": "Show replies" }, diff --git a/packages/app/src/translations/en.json b/packages/app/src/translations/en.json index 13e79805..eb538ee8 100644 --- a/packages/app/src/translations/en.json +++ b/packages/app/src/translations/en.json @@ -369,6 +369,7 @@ "hMzcSq": "Messages", "hRTfTR": "PRO", "hY4lzx": "Supports", + "ha8JKG": "Show graph", "hicxcO": "Show replies", "hmZ3Bz": "Media", "hniz8Z": "here", From 2c14a8f404b503f9e5ab302b8ebae140a7657368 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Fri, 24 Nov 2023 13:32:19 +0200 Subject: [PATCH 37/66] scrollable left navbar --- packages/app/src/Pages/Layout/NavSidebar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app/src/Pages/Layout/NavSidebar.tsx b/packages/app/src/Pages/Layout/NavSidebar.tsx index 09325ca3..f6a06014 100644 --- a/packages/app/src/Pages/Layout/NavSidebar.tsx +++ b/packages/app/src/Pages/Layout/NavSidebar.tsx @@ -67,7 +67,7 @@ export default function NavSidebar({ narrow = false }) { const className = classNames( { "xl:w-56 xl:gap-3 xl:items-start": !narrow }, - "sticky items-center border-r border-neutral-900 top-0 z-20 h-screen max-h-screen hidden md:flex flex-col px-2 py-4 flex-shrink-0 gap-2", + "overflow-y-auto hide-scrollbar sticky items-center border-r border-neutral-900 top-0 z-20 h-screen max-h-screen hidden md:flex flex-col px-2 py-4 flex-shrink-0 gap-2", ); return ( From 47aec5437dd8dc03d70e9f8f2ab70743daaef54a Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Fri, 24 Nov 2023 15:50:40 +0200 Subject: [PATCH 38/66] fuse fuzzy user search --- packages/app/package.json | 1 + packages/app/src/Element/SearchBox.tsx | 45 +++++++++++++++++++++---- packages/app/src/FuzzySearch.ts | 43 +++++++++++++++++++++++ packages/app/src/Pages/NetworkGraph.tsx | 2 +- packages/app/src/index.tsx | 36 ++++++++++++++++++++ yarn.lock | 8 +++++ 6 files changed, 128 insertions(+), 7 deletions(-) create mode 100644 packages/app/src/FuzzySearch.ts diff --git a/packages/app/package.json b/packages/app/package.json index b91e59e6..2a59b9da 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -21,6 +21,7 @@ "debug": "^4.3.4", "dexie": "^3.2.4", "emojilib": "^3.0.10", + "fuse.js": "^7.0.0", "highlight.js": "^11.8.0", "light-bolt11-decoder": "^2.1.0", "marked": "^9.1.0", diff --git a/packages/app/src/Element/SearchBox.tsx b/packages/app/src/Element/SearchBox.tsx index 0c516d36..fd021c03 100644 --- a/packages/app/src/Element/SearchBox.tsx +++ b/packages/app/src/Element/SearchBox.tsx @@ -8,7 +8,9 @@ import { NostrLink, tryParseNostrLink } from "@snort/system"; import { useLocation, useNavigate } from "react-router-dom"; import { unixNow } from "@snort/shared"; import useTimelineFeed, { TimelineFeedOptions, TimelineSubject } from "../Feed/TimelineFeed"; -import Note from "./Event/Note"; +import { fuzzySearch, FuzzySearchResult } from "@/index"; +import ProfileImage from "@/Element/User/ProfileImage"; +import { socialGraphInstance } from "@snort/system"; const MAX_RESULTS = 3; @@ -39,6 +41,37 @@ export default function SearchBox() { const { main } = useTimelineFeed(subject, options); + const [results, setResults] = useState([]); + useEffect(() => { + const searchString = search.trim(); + const fuseResults = fuzzySearch.search(searchString); + + const followDistanceNormalizationFactor = 3; + + const combinedResults = fuseResults.map(result => { + const fuseScore = result.score === undefined ? 1 : result.score; + const followDistance = socialGraphInstance.getFollowDistance(result.item.pubkey) / followDistanceNormalizationFactor; + + const startsWithSearchString = [result.item.name, result.item.display_name, result.item.nip05] + .some(field => field && field.toLowerCase?.().startsWith(searchString.toLowerCase())); + + const boostFactor = startsWithSearchString ? 0.25 : 1; + + const weightForFuseScore = 0.8; + const weightForFollowDistance = 0.2; + + const combinedScore = (fuseScore * weightForFuseScore + followDistance * weightForFollowDistance) * boostFactor; + + return { ...result, combinedScore }; + }); + + // Sort by combined score, lower is better + combinedResults.sort((a, b) => a.combinedScore - b.combinedScore); + + setResults(combinedResults.map(r => r.item)); +}, [search, main]); + + useEffect(() => { const handleGlobalKeyDown = (e: KeyboardEvent) => { if (e.key === "Escape") { @@ -92,8 +125,8 @@ export default function SearchBox() { case "Enter": if (activeIndex === 0) { navigate(`/search/${encodeURIComponent(search)}`); - } else if (activeIndex > 0 && main) { - const selectedResult = main[activeIndex - 1]; + } else if (activeIndex > 0 && results) { + const selectedResult = results[activeIndex - 1]; navigate(`/${new NostrLink(CONFIG.profileLinkPrefix, selectedResult.pubkey).encode()}`); } else { executeSearch(); @@ -101,7 +134,7 @@ export default function SearchBox() { break; case "ArrowDown": e.preventDefault(); - setActiveIndex(prev => Math.min(prev + 1, Math.min(MAX_RESULTS, main ? main.length : 0))); + setActiveIndex(prev => Math.min(prev + 1, Math.min(MAX_RESULTS, results ? results.length : 0))); break; case "ArrowUp": e.preventDefault(); @@ -143,7 +176,7 @@ export default function SearchBox() { onClick={() => navigate(`/search/${encodeURIComponent(search)}`, { state: { forceRefresh: true } })}> : {search}
- {main?.slice(0, MAX_RESULTS).map((result, idx) => ( + {results?.slice(0, MAX_RESULTS).map((result, idx) => (
setActiveIndex(idx + 1)}> - +
))}
diff --git a/packages/app/src/FuzzySearch.ts b/packages/app/src/FuzzySearch.ts new file mode 100644 index 00000000..9ffe810c --- /dev/null +++ b/packages/app/src/FuzzySearch.ts @@ -0,0 +1,43 @@ +import Fuse from "fuse.js"; +import { socialGraphInstance } from "@snort/system"; +import { System } from "."; + +export type FuzzySearchResult = { + pubkey: string; + name?: string; + username?: string; + nip05?: string; +}; + +export const fuzzySearch = new Fuse([], { + keys: ["name", "username", { name: "nip05", weight: 0.5 }], + threshold: 0.3, + // sortFn here? +}); + +const profileTimestamps = new Map(); // is this somewhere in cache? + +System.on("event", ev => { + if (ev.kind === 0) { + const existing = profileTimestamps.get(ev.pubkey); + if (existing) { + if (existing > ev.created_at) { + return; + } + fuzzySearch.remove(doc => doc.pubkey === ev.pubkey); + } + profileTimestamps.set(ev.pubkey, ev.created_at); + try { + const data = JSON.parse(ev.content); + if (ev.pubkey && (data.name || data.username || data.nip05)) { + data.pubkey = ev.pubkey; + fuzzySearch.add(data); + } + } catch (e) { + console.error(e); + } + } + if (ev.kind === 3) { + socialGraphInstance.handleFollowEvent(ev); + } +}); diff --git a/packages/app/src/Pages/NetworkGraph.tsx b/packages/app/src/Pages/NetworkGraph.tsx index 8e4506c3..31ef8299 100644 --- a/packages/app/src/Pages/NetworkGraph.tsx +++ b/packages/app/src/Pages/NetworkGraph.tsx @@ -77,7 +77,7 @@ const NetworkGraph = () => { setOpen(false); }; - const handleKeyDown = (event: { key: string; }) => { + const handleKeyDown = (event: { key: string }) => { if (event.key === "Escape") { handleCloseGraph(); } diff --git a/packages/app/src/index.tsx b/packages/app/src/index.tsx index b3696b87..e10f0f44 100644 --- a/packages/app/src/index.tsx +++ b/packages/app/src/index.tsx @@ -59,6 +59,7 @@ import { AboutPage } from "@/Pages/About"; import { OnboardingRoutes } from "@/Pages/onboarding"; import { setupWebLNWalletConfig } from "@/Wallet/WebLN"; import { Wallets } from "@/Wallet"; +import Fuse from "fuse.js"; declare global { interface Window { @@ -111,7 +112,42 @@ System.on("auth", async (c, r, cb) => { } }); +export type FuzzySearchResult = { + pubkey: string; + name?: string; + display_name?: string; + nip05?: string; +}; + +export const fuzzySearch = new Fuse([], { + keys: ["name", "display_name", { name: "nip05", weight: 0.5 }], + threshold: 0.3, + // sortFn here? +}); + +const profileTimestamps = new Map(); + +// how to also add entries from ProfileCache? System.on("event", ev => { + if (ev.kind === 0) { + const existing = profileTimestamps.get(ev.pubkey); + if (existing) { + if (existing > ev.created_at) { + return; + } + fuzzySearch.remove(doc => doc.pubkey === ev.pubkey); + } + profileTimestamps.set(ev.pubkey, ev.created_at); + try { + const data = JSON.parse(ev.content); + if (ev.pubkey && (data.name || data.display_name || data.nip05)) { + data.pubkey = ev.pubkey; + fuzzySearch.add(data); + } + } catch (e) { + console.error(e); + } + } if (ev.kind === 3) { socialGraphInstance.handleFollowEvent(ev); } diff --git a/yarn.lock b/yarn.lock index 926bbe6b..3b608f39 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2921,6 +2921,7 @@ __metadata: emojilib: ^3.0.10 eslint: ^8.48.0 eslint-plugin-formatjs: ^4.11.3 + fuse.js: ^7.0.0 highlight.js: ^11.8.0 light-bolt11-decoder: ^2.1.0 marked: ^9.1.0 @@ -6120,6 +6121,13 @@ __metadata: languageName: node linkType: hard +"fuse.js@npm:^7.0.0": + version: 7.0.0 + resolution: "fuse.js@npm:7.0.0" + checksum: d15750efec1808370c0cae92ec9473aa7261c59bca1f15f1cf60039ba6f804b8f95340b5cabd83a4ef55839c1034764856e0128e443921f072aa0d8a20e4cacf + languageName: node + linkType: hard + "gensync@npm:^1.0.0-beta.2": version: 1.0.0-beta.2 resolution: "gensync@npm:1.0.0-beta.2" From 13b76e77096e2aea76e33ca00247e4bb58c20c39 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Fri, 24 Nov 2023 16:18:32 +0200 Subject: [PATCH 39/66] show "followed by" on profile pages --- packages/app/src/Element/SearchBox.tsx | 17 +++++------ .../app/src/Pages/Profile/ProfilePage.tsx | 28 +++++++++++++++++++ packages/app/src/lang.json | 6 ++++ packages/app/src/translations/en.json | 2 ++ .../system/src/SocialGraph/SocialGraph.ts | 11 ++++++++ 5 files changed, 56 insertions(+), 8 deletions(-) diff --git a/packages/app/src/Element/SearchBox.tsx b/packages/app/src/Element/SearchBox.tsx index fd021c03..cb674dad 100644 --- a/packages/app/src/Element/SearchBox.tsx +++ b/packages/app/src/Element/SearchBox.tsx @@ -50,10 +50,12 @@ export default function SearchBox() { const combinedResults = fuseResults.map(result => { const fuseScore = result.score === undefined ? 1 : result.score; - const followDistance = socialGraphInstance.getFollowDistance(result.item.pubkey) / followDistanceNormalizationFactor; + const followDistance = + socialGraphInstance.getFollowDistance(result.item.pubkey) / followDistanceNormalizationFactor; - const startsWithSearchString = [result.item.name, result.item.display_name, result.item.nip05] - .some(field => field && field.toLowerCase?.().startsWith(searchString.toLowerCase())); + const startsWithSearchString = [result.item.name, result.item.display_name, result.item.nip05].some( + field => field && field.toLowerCase?.().startsWith(searchString.toLowerCase()), + ); const boostFactor = startsWithSearchString ? 0.25 : 1; @@ -65,12 +67,11 @@ export default function SearchBox() { return { ...result, combinedScore }; }); - // Sort by combined score, lower is better - combinedResults.sort((a, b) => a.combinedScore - b.combinedScore); - - setResults(combinedResults.map(r => r.item)); -}, [search, main]); + // Sort by combined score, lower is better + combinedResults.sort((a, b) => a.combinedScore - b.combinedScore); + setResults(combinedResults.map(r => r.item)); + }, [search, main]); useEffect(() => { const handleGlobalKeyDown = (e: KeyboardEvent) => { diff --git a/packages/app/src/Pages/Profile/ProfilePage.tsx b/packages/app/src/Pages/Profile/ProfilePage.tsx index 7e555029..fdc5c1ae 100644 --- a/packages/app/src/Pages/Profile/ProfilePage.tsx +++ b/packages/app/src/Pages/Profile/ProfilePage.tsx @@ -9,6 +9,7 @@ import { MetadataCache, NostrLink, NostrPrefix, + socialGraphInstance, TLVEntryType, tryParseNostrLink, } from "@snort/system"; @@ -152,6 +153,8 @@ export default function ProfilePage({ id: propId, state }: ProfilePageProps) { } function username() { + const followedByFriends = user.pubkey ? socialGraphInstance.followedByFriends(user.pubkey) : new Set(); + const MAX_FOLLOWED_BY_FRIENDS = 3; return ( <>
@@ -160,6 +163,31 @@ export default function ProfilePage({ id: propId, state }: ProfilePageProps) {

{user?.nip05 && } + {followedByFriends.size > 0 && ( +
+ + + + {Array.from(followedByFriends) + .slice(0, MAX_FOLLOWED_BY_FRIENDS) + .map(a => { + return ( + + + + ); + })} + {followedByFriends.size > MAX_FOLLOWED_BY_FRIENDS && ( + + + + )} +
+ )}
{showBadges && } {showStatus && <>{musicStatus()}} diff --git a/packages/app/src/lang.json b/packages/app/src/lang.json index 137191e8..c30a6eb8 100644 --- a/packages/app/src/lang.json +++ b/packages/app/src/lang.json @@ -234,6 +234,9 @@ "6k7xfM": { "defaultMessage": "Trending notes" }, + "6mr8WU": { + "defaultMessage": "Followed by" + }, "6uMqL1": { "defaultMessage": "Unpaid" }, @@ -368,6 +371,9 @@ "CVWeJ6": { "defaultMessage": "Trending People" }, + "CYkOCI": { + "defaultMessage": "and {count} others you follow" + }, "CbM2hK": { "defaultMessage": "Trending hashtags" }, diff --git a/packages/app/src/translations/en.json b/packages/app/src/translations/en.json index eb538ee8..4757cd0d 100644 --- a/packages/app/src/translations/en.json +++ b/packages/app/src/translations/en.json @@ -77,6 +77,7 @@ "6bgpn+": "Not all clients support this, you may still receive some zaps as if zap splits was not configured", "6ewQqw": "Likes ({n})", "6k7xfM": "Trending notes", + "6mr8WU": "Followed by", "6uMqL1": "Unpaid", "7+Domh": "Notes", "712i26": "Proxy uses HODL invoices to forward the payment, which hides the pubkey of your node", @@ -121,6 +122,7 @@ "C8HhVE": "Suggested Follows", "CHTbO3": "Failed to load invoice", "CVWeJ6": "Trending People", + "CYkOCI": "and {count} others you follow", "CbM2hK": "Trending hashtags", "CmZ9ls": "{n} Muted", "CsCUYo": "{n} sats", diff --git a/packages/system/src/SocialGraph/SocialGraph.ts b/packages/system/src/SocialGraph/SocialGraph.ts index c3264aea..96bccf8b 100644 --- a/packages/system/src/SocialGraph/SocialGraph.ts +++ b/packages/system/src/SocialGraph/SocialGraph.ts @@ -211,6 +211,17 @@ export default class SocialGraph { return count; } + followedByFriends(address: HexKey) { + const id = ID(address); + const set = new Set(); + for (const follower of this.followersByUser.get(id) ?? []) { + if (this.followedByUser.get(this.root)?.has(follower)) { + set.add(STR(follower)); + } + } + return set; + } + getFollowedByUser(user: HexKey, includeSelf = false): Set { const userId = ID(user); const set = new Set(); From e0b85b90f97cfc1c60ab845af610b45940a6b395 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Fri, 24 Nov 2023 16:37:12 +0200 Subject: [PATCH 40/66] user?.pubkey --- packages/app/src/Pages/Profile/ProfilePage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app/src/Pages/Profile/ProfilePage.tsx b/packages/app/src/Pages/Profile/ProfilePage.tsx index fdc5c1ae..0e42f9da 100644 --- a/packages/app/src/Pages/Profile/ProfilePage.tsx +++ b/packages/app/src/Pages/Profile/ProfilePage.tsx @@ -153,7 +153,7 @@ export default function ProfilePage({ id: propId, state }: ProfilePageProps) { } function username() { - const followedByFriends = user.pubkey ? socialGraphInstance.followedByFriends(user.pubkey) : new Set(); + const followedByFriends = user?.pubkey ? socialGraphInstance.followedByFriends(user.pubkey) : new Set(); const MAX_FOLLOWED_BY_FRIENDS = 3; return ( <> From b7545295d444a539540c9b78d0e2f9e67facf256 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Fri, 24 Nov 2023 17:04:12 +0200 Subject: [PATCH 41/66] tmp disable tweet embed (require is not defined error) --- packages/app/src/Element/HyperText.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/app/src/Element/HyperText.tsx b/packages/app/src/Element/HyperText.tsx index 61e12b52..4d7e4fd2 100644 --- a/packages/app/src/Element/HyperText.tsx +++ b/packages/app/src/Element/HyperText.tsx @@ -1,8 +1,8 @@ -import { TwitterTweetEmbed } from "react-twitter-embed"; +// import { TwitterTweetEmbed } from "react-twitter-embed"; import { YoutubeUrlRegex, - TweetUrlRegex, + //TweetUrlRegex, TidalRegex, SoundCloudRegex, MixCloudRegex, @@ -37,7 +37,7 @@ export default function HyperText({ link, depth, showLinkPreview, children }: Hy try { const url = new URL(a); const youtubeId = YoutubeUrlRegex.test(a) && RegExp.$1; - const tweetId = TweetUrlRegex.test(a) && RegExp.$2; + //const tweetId = TweetUrlRegex.test(a) && RegExp.$2; const tidalId = TidalRegex.test(a) && RegExp.$1; const soundcloundId = SoundCloudRegex.test(a) && RegExp.$1; const mixcloudId = MixCloudRegex.test(a) && RegExp.$1; @@ -46,13 +46,13 @@ export default function HyperText({ link, depth, showLinkPreview, children }: Hy const isAppleMusicLink = AppleMusicRegex.test(a); const isNostrNestsLink = NostrNestsRegex.test(a); const isWavlakeLink = WavlakeRegex.test(a); - if (tweetId) { + /*if (tweetId) { // tmp disabled, react-twitter-embed causes "require is not defined" error return (
); - } else if (youtubeId) { + } else*/ if (youtubeId) { return (