From 037b81c49e7231cfe47449e3de3488fe24b71df0 Mon Sep 17 00:00:00 2001 From: enes Date: Thu, 26 Dec 2024 16:39:09 +0100 Subject: [PATCH 1/6] fix(games): add no games found in search Closes #141 --- src/pages/search.tsx | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/pages/search.tsx b/src/pages/search.tsx index 683696f..68ff768 100644 --- a/src/pages/search.tsx +++ b/src/pages/search.tsx @@ -39,6 +39,7 @@ import { scrollIntoView } from 'utils' import { useCuratedSet } from 'hooks/useCuratedSet' +import dedup from 'utils/nostr' enum SearchKindEnum { Mods = 'Mods', @@ -508,6 +509,11 @@ const GamesResult = ({ searchTerm }: GamesResultProps) => { return ( <> + {searchTerm !== '' && filteredGames.length === 0 && ( +
+ Game not found. Send us a message where you can reach us to add it +
+ )}
{filteredGames @@ -521,20 +527,14 @@ const GamesResult = ({ searchTerm }: GamesResultProps) => { ))}
- + {searchTerm !== '' && filteredGames.length > MAX_GAMES_PER_PAGE && ( + + )} ) } -function dedup(event1: NDKEvent, event2: NDKEvent) { - // return the newest of the two - if (event1.created_at! > event2.created_at!) { - return event1 - } - - return event2 -} -- 2.34.1 From 4bf978766099a6eeb64f80a4aa9bf840e6f7588e Mon Sep 17 00:00:00 2001 From: enes Date: Thu, 26 Dec 2024 16:40:40 +0100 Subject: [PATCH 2/6] refactor: remove user metadata console errors --- src/contexts/NDKContext.tsx | 2 +- src/hooks/useComments.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/contexts/NDKContext.tsx b/src/contexts/NDKContext.tsx index 853f5c3..fe9b773 100644 --- a/src/contexts/NDKContext.tsx +++ b/src/contexts/NDKContext.tsx @@ -252,7 +252,7 @@ export const NDKContextProvider = ({ children }: { children: ReactNode }) => { }) .catch((err) => { log( - true, + false, // Too many failed requests, turned off for clarity LogType.Error, `An error occurred in fetching user's (${hexKey}) ${userRelaysType}`, err diff --git a/src/hooks/useComments.ts b/src/hooks/useComments.ts index e62f918..4de0403 100644 --- a/src/hooks/useComments.ts +++ b/src/hooks/useComments.ts @@ -39,7 +39,7 @@ export const useComments = ( }) .catch((err) => { log( - true, + false, // Too many failed requests, turned off for clarity LogType.Error, `An error occurred in fetching user's (${author}) ${UserRelaysType.Read}`, err -- 2.34.1 From ad3d069ad55c3ec09679ba705fedbc029b0f6993 Mon Sep 17 00:00:00 2001 From: enes Date: Thu, 26 Dec 2024 16:42:11 +0100 Subject: [PATCH 3/6] refactor: deps cleanup --- src/App.tsx | 7 ++++--- src/layout/index.tsx | 6 +++--- src/utils/nostr.ts | 13 +++++++++++++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 95183ab..fc48012 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,11 +1,12 @@ import { RouterProvider } from 'react-router-dom' -import { useEffect } from 'react' -import { routerWithNdkContext } from 'routes' +import { useEffect, useMemo } from 'react' +import { routerWithNdkContext as routerWithState } from 'routes' import { useNDKContext } from 'hooks' import './styles/styles.css' function App() { const ndkContext = useNDKContext() + const router = useMemo(() => routerWithState(ndkContext), [ndkContext]) useEffect(() => { // Find the element with id 'root' @@ -24,7 +25,7 @@ function App() { } }, []) - return + return } export default App diff --git a/src/layout/index.tsx b/src/layout/index.tsx index f936f04..cdddc70 100644 --- a/src/layout/index.tsx +++ b/src/layout/index.tsx @@ -44,7 +44,7 @@ export const Layout = () => { }) } } - }, [ndk, dispatch]) + }, [dispatch, ndk]) // calculate user's wot useEffect(() => { @@ -60,7 +60,7 @@ export const Layout = () => { toast.error('An error occurred in calculating user web-of-trust!') }) } - }, [ndk, userState.user, dispatch]) + }, [dispatch, ndk, userState.user?.pubkey]) // get site's wot level useEffect(() => { @@ -106,7 +106,7 @@ export const Layout = () => { }) } } - }, [userState.user, dispatch, fetchEventFromUserRelays]) + }, [dispatch, fetchEventFromUserRelays, userState.user?.pubkey]) return ( <> diff --git a/src/utils/nostr.ts b/src/utils/nostr.ts index 772c37b..47ab343 100644 --- a/src/utils/nostr.ts +++ b/src/utils/nostr.ts @@ -274,3 +274,16 @@ export function orderEventsChronologically( return events } + +/** + * Receives two events and returns the "correct" event to use. + * #nip-33 + */ +export default function dedup(event1: NDKEvent, event2: NDKEvent) { + // return the newest of the two + if (event1.created_at! > event2.created_at!) { + return event1 + } + + return event2 +} -- 2.34.1 From ad68ba8e843d9b4caf78cebc9925468bf412b243 Mon Sep 17 00:00:00 2001 From: enes Date: Thu, 26 Dec 2024 16:46:40 +0100 Subject: [PATCH 4/6] fix: add fallback for usersPubkey in loaders --- src/pages/blog/loader.ts | 4 +++- src/pages/mod/loader.ts | 4 +++- src/pages/mods/loader.ts | 18 ++++++++++-------- src/pages/profile/loader.ts | 22 ++++++---------------- src/utils/utils.ts | 20 ++++++++++++++++++++ 5 files changed, 42 insertions(+), 26 deletions(-) diff --git a/src/pages/blog/loader.ts b/src/pages/blog/loader.ts index 0b06b50..f0fc114 100644 --- a/src/pages/blog/loader.ts +++ b/src/pages/blog/loader.ts @@ -13,6 +13,7 @@ import { } from 'types' import { DEFAULT_FILTER_OPTIONS, + getFallbackPubkey, getLocalStorageItem, log, LogType @@ -41,7 +42,8 @@ export const blogRouteLoader = } const userState = store.getState().user - const loggedInUserPubkey = userState?.user?.pubkey as string | undefined + const loggedInUserPubkey = + (userState?.user?.pubkey as string | undefined) || getFallbackPubkey() // Check if editing and the user is the original author // Redirect if NOT diff --git a/src/pages/mod/loader.ts b/src/pages/mod/loader.ts index 032d697..3c7ebc2 100644 --- a/src/pages/mod/loader.ts +++ b/src/pages/mod/loader.ts @@ -16,6 +16,7 @@ import { DEFAULT_FILTER_OPTIONS, extractBlogCardDetails, extractModData, + getFallbackPubkey, getLocalStorageItem, getReportingSet, log, @@ -46,7 +47,8 @@ export const modRouteLoader = } const userState = store.getState().user - const loggedInUserPubkey = userState?.user?.pubkey as string | undefined + const loggedInUserPubkey = + (userState?.user?.pubkey as string | undefined) || getFallbackPubkey() try { // Set up the filters diff --git a/src/pages/mods/loader.ts b/src/pages/mods/loader.ts index 24fc3a4..e7a05ba 100644 --- a/src/pages/mods/loader.ts +++ b/src/pages/mods/loader.ts @@ -1,7 +1,13 @@ import { NDKContextType } from 'contexts/NDKContext' import { store } from 'store' import { MuteLists } from 'types' -import { getReportingSet, CurationSetIdentifiers, log, LogType } from 'utils' +import { + getReportingSet, + CurationSetIdentifiers, + log, + LogType, + getFallbackPubkey +} from 'utils' export interface ModsPageLoaderResult { muteLists: { @@ -31,15 +37,11 @@ export const modsRouteLoader = (ndkContext: NDKContextType) => async () => { // Get the current state const userState = store.getState().user - - // Check if current user is logged in - let userPubkey: string | undefined - if (userState.auth && userState.user?.pubkey) { - userPubkey = userState.user.pubkey as string - } + const loggedInUserPubkey = + (userState?.user?.pubkey as string | undefined) || getFallbackPubkey() const settled = await Promise.allSettled([ - ndkContext.getMuteLists(userPubkey), + ndkContext.getMuteLists(loggedInUserPubkey), getReportingSet(CurationSetIdentifiers.NSFW, ndkContext), getReportingSet(CurationSetIdentifiers.Repost, ndkContext) ]) diff --git a/src/pages/profile/loader.ts b/src/pages/profile/loader.ts index f5bc1b6..13eef6c 100644 --- a/src/pages/profile/loader.ts +++ b/src/pages/profile/loader.ts @@ -6,6 +6,7 @@ import { store } from 'store' import { MuteLists, UserProfile } from 'types' import { CurationSetIdentifiers, + getFallbackPubkey, getReportingSet, log, LogType, @@ -16,7 +17,6 @@ export interface ProfilePageLoaderResult { profilePubkey: string profile: UserProfile isBlocked: boolean - isOwnProfile: boolean muteLists: { admin: MuteLists user: MuteLists @@ -58,21 +58,17 @@ export const profileRouteLoader = // Get the current state const userState = store.getState().user - - // Check if current user is logged in - let userPubkey: string | undefined - if (userState.auth && userState.user?.pubkey) { - userPubkey = userState.user.pubkey as string - } + const loggedInUserPubkey = + (userState?.user?.pubkey as string | undefined) || getFallbackPubkey() // Redirect if profile naddr is missing // - home if user is not logged let profileRoute = appRoutes.home - if (!profilePubkey && userPubkey) { + if (!profilePubkey && loggedInUserPubkey) { // - own profile profileRoute = getProfilePageRoute( nip19.nprofileEncode({ - pubkey: userPubkey + pubkey: loggedInUserPubkey }) ) } @@ -83,7 +79,6 @@ export const profileRouteLoader = profilePubkey: profilePubkey, profile: {}, isBlocked: false, - isOwnProfile: false, muteLists: { admin: { authors: [], @@ -98,14 +93,9 @@ export const profileRouteLoader = repostList: [] } - // Check if user the user is logged in - if (userState.auth && userState.user?.pubkey) { - result.isOwnProfile = userState.user.pubkey === profilePubkey - } - const settled = await Promise.allSettled([ ndkContext.findMetadata(profilePubkey), - ndkContext.getMuteLists(userPubkey), + ndkContext.getMuteLists(loggedInUserPubkey), getReportingSet(CurationSetIdentifiers.NSFW, ndkContext), getReportingSet(CurationSetIdentifiers.Repost, ndkContext) ]) diff --git a/src/utils/utils.ts b/src/utils/utils.ts index bb740e5..e28027d 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -160,3 +160,23 @@ export const parseFormData = (formData: FormData) => { export const capitalizeEachWord = (str: string): string => { return str.replace(/\b\w/g, (char) => char.toUpperCase()) } + +/** + * nostr-login - helper function + * should only be used as the fallback + * user state is not updated before `onAuth` triggers but loaders are faster + */ +export const getFallbackPubkey = () => { + try { + // read nostr-login conf from localStorage + const stored = window.localStorage.getItem('__nostrlogin_nip46') + if (!stored) return + + const info = JSON.parse(stored) + if (info && !info.pubkey) return + + return info.pubkey as string + } catch { + // Silently ignore + } +} -- 2.34.1 From 1c4a9c85867a52d3e0444b17ed390bbd00ccab8b Mon Sep 17 00:00:00 2001 From: enes Date: Thu, 26 Dec 2024 17:20:21 +0100 Subject: [PATCH 5/6] fix: failing links in footer, backup and supporters pages prep Partially #142 --- src/layout/footer.tsx | 22 ++++--- src/pages/backup.tsx | 126 +++++++++++++++++++++++++++++++++++++++ src/pages/supporters.tsx | 3 + src/routes/index.tsx | 14 ++++- src/styles/backup.css | 36 +++++++++++ 5 files changed, 193 insertions(+), 8 deletions(-) create mode 100644 src/pages/backup.tsx create mode 100644 src/pages/supporters.tsx create mode 100644 src/styles/backup.css diff --git a/src/layout/footer.tsx b/src/layout/footer.tsx index 5ddedb3..d0ea3d7 100644 --- a/src/layout/footer.tsx +++ b/src/layout/footer.tsx @@ -1,4 +1,6 @@ +import { Link } from 'react-router-dom' import styles from '../styles/footer.module.scss' +import { appRoutes, getProfilePageRoute } from 'routes' export const Footer = () => { return ( @@ -7,6 +9,7 @@ export const Footer = () => {

Built with  { Nostr {' '} by  - Freakoverse - + , with the support of{' '} - + Supporters - + . Check our  - + Backup Plan - + .

diff --git a/src/pages/backup.tsx b/src/pages/backup.tsx new file mode 100644 index 0000000..682d869 --- /dev/null +++ b/src/pages/backup.tsx @@ -0,0 +1,126 @@ +import { capitalizeEachWord } from 'utils' +import '../styles/backup.css' +import backupPlanImg from '../assets/img/DEG Mods Backup Plan.png' +// import placeholder from '../assets/img/DEGMods Placeholder Img.png' +interface BackupItemProps { + name: string + image: string + link: string + type: 'repo' | 'alt' | 'exe' +} +const BACKUP_LIST: BackupItemProps[] = [ + // { + // name: 'Github', + // type: 'repo', + // image: + // 'https://www.c-sharpcorner.com/article/create-github-repository-and-add-newexisting-project-using-github-desktop/Images/github.png', + // link: '#' + // }, + // { + // name: 'Github, but nostr', + // type: 'repo', + // image: 'https://vitorpamplona.com/images/nostr.gif', + // link: '#' + // }, + // { + // name: 'name', + // type: 'alt', + // image: placeholder, + // link: '#' + // }, + // { + // name: '', + // type: 'exe', + // image: placeholder, + // link: '#' + // } +] + +const BackupItem = ({ name, image, link, type }: BackupItemProps) => { + return ( + +
+

+ {type === 'exe' ? type.toUpperCase() : capitalizeEachWord(type)}:{' '} + {name} +

+
+
+ ) +} + +export const BackupPage = () => { + return ( +
+
+
+
+
+
+
+

+ Backup Plan: Repos, Alts, EXE +

+ +

+ It's pretty clear that authoritarianism and censorship is on + the rise, on all fronts, and from what can be seen, any idea + that push for the opposite gets attacked. That's why DEG + Mods is running on Nostr, and that's why we're also writing + this backup plan. +
+

+

Repositories

+

+ Wherever we can, we'll put DEG Mods' code on multiple + repositories such as Github, and (github but on nostr). + Below you can find the links where we've uploaded the site's + code to. +
+

+

Alternatives

+

+ With the repositories for DEG Mods is up on multiple places, + we encourage people to take the code and duplicate it + elsewhere. Fork it, change the design, remove or add systems + and features, and make your own version. Below you can find + links of alts that we've found. +
+

+

EXE

+

+ One last push we'd like to do is to create a .exe that'll + open up DEG Mods on your PC, as if you've opened the website + normally, with almost all of the functionalities you'd + expect (if not all). We want to do this so that in case + there are no alternatives, or that they're getting shut + down, then you can just rely on this instead. The link to it + will be added here the moment it becomes available. +
+

+
+ {BACKUP_LIST.map((b) => ( + + ))} +
+
+
+
+
+
+
+
+ ) +} diff --git a/src/pages/supporters.tsx b/src/pages/supporters.tsx new file mode 100644 index 0000000..afa326c --- /dev/null +++ b/src/pages/supporters.tsx @@ -0,0 +1,3 @@ +export const SupportersPage = () => { + return

WIP

+} diff --git a/src/routes/index.tsx b/src/routes/index.tsx index bee8638..20bd612 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -28,6 +28,8 @@ import { BlogPage } from '../pages/blog' import { blogRouteLoader } from '../pages/blog/loader' import { blogRouteAction } from '../pages/blog/action' import { reportRouteAction } from '../actions/report' +import { BackupPage } from 'pages/backup' +import { SupportersPage } from 'pages/supporters' export const appRoutes = { home: '/', @@ -51,7 +53,9 @@ export const appRoutes = { settingsAdmin: '/settings-admin', profile: '/profile/:nprofile?', feed: '/feed', - notifications: '/notifications' + notifications: '/notifications', + backup: '/backup', + supporters: '/supporters' } export const getGamePageRoute = (name: string) => @@ -185,6 +189,14 @@ export const routerWithNdkContext = (context: NDKContextType) => } ] }, + { + path: appRoutes.backup, + element: + }, + { + path: appRoutes.supporters, + element: + }, { path: '*', element: diff --git a/src/styles/backup.css b/src/styles/backup.css new file mode 100644 index 0000000..c2ece79 --- /dev/null +++ b/src/styles/backup.css @@ -0,0 +1,36 @@ +.backupList { + width: 100%; + display: flex; + flex-direction: column; + grid-gap: 15px; +} + +.backupListLink { + transition: ease 0.4s; + overflow: hidden; + padding: 15px; + box-shadow: 0 0 8px 0 rgb(0,0,0,0.1); + border-radius: 10px; + /*border: solid 1px rgba(255,255,255,0.1);*/ + position: relative; + color: rgba(255,255,255,0.75); + min-height: 150px; + display: flex; + flex-direction: column; +} + +.backupListLink:hover { + transition: ease 0.4s; + text-decoration: unset; + color: rgb(255,255,255); + transform: scale(1.02); +} + +.backupListLinkInside { + display: flex; + flex-direction: column; + grid-gap: 0px; + flex-grow: 1; + justify-content: end; +} + -- 2.34.1 From 5449591b6ebada6bee45a9808db54b7057d6e234 Mon Sep 17 00:00:00 2001 From: enes Date: Thu, 26 Dec 2024 17:21:19 +0100 Subject: [PATCH 6/6] fix: blogs loading for reported nprofile --- src/pages/profile/index.tsx | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/pages/profile/index.tsx b/src/pages/profile/index.tsx index 3761a5b..05a9a30 100644 --- a/src/pages/profile/index.tsx +++ b/src/pages/profile/index.tsx @@ -46,7 +46,6 @@ export const ProfilePage = () => { profilePubkey, profile, isBlocked: _isBlocked, - isOwnProfile, repostList, muteLists, nsfwList @@ -60,6 +59,10 @@ export const ProfilePage = () => { const displayName = profile?.displayName || profile?.name || '[name not set up]' const [showReportPopUp, setShowReportPopUp] = useState(false) + const isOwnProfile = + userState.auth && + userState.user?.pubkey && + userState.user.pubkey === profilePubkey const [isBlocked, setIsBlocked] = useState(_isBlocked) const handleBlock = async () => { @@ -661,7 +664,7 @@ const ReportUserPopup = ({ } const ProfileTabBlogs = () => { - const { profile, muteLists, nsfwList } = + const { profilePubkey, muteLists, nsfwList } = useLoaderData() as ProfilePageLoaderResult const navigation = useNavigation() const { fetchEvents } = useNDKContext() @@ -669,7 +672,7 @@ const ProfileTabBlogs = () => { const [isLoading, setIsLoading] = useState(true) const blogfilter: NDKFilter = useMemo(() => { const filter: NDKFilter = { - authors: [profile?.pubkey as string], + authors: [profilePubkey], kinds: [kinds.LongFormArticle] } @@ -683,13 +686,13 @@ const ProfileTabBlogs = () => { } return filter - }, [filterOptions.nsfw, filterOptions.source, profile?.pubkey]) + }, [filterOptions.nsfw, filterOptions.source, profilePubkey]) const [page, setPage] = useState(1) const [hasMore, setHasMore] = useState(false) const [blogs, setBlogs] = useState[]>([]) useEffect(() => { - if (profile) { + if (profilePubkey) { // Initial blog fetch, go beyond limit to check for next const filter: NDKFilter = { ...blogfilter, @@ -704,7 +707,7 @@ const ProfileTabBlogs = () => { setIsLoading(false) }) } - }, [blogfilter, fetchEvents, profile]) + }, [blogfilter, fetchEvents, profilePubkey]) const handleNext = useCallback(() => { if (isLoading) return @@ -758,7 +761,7 @@ const ProfileTabBlogs = () => { let _blogs = blogs || [] const isAdmin = userState.user?.npub === import.meta.env.VITE_REPORTING_NPUB const isOwner = - userState.user?.pubkey && userState.user.pubkey === profile?.pubkey + userState.user?.pubkey && userState.user.pubkey === profilePubkey const isUnmoderatedFully = filterOptions.moderated === ModeratedFilter.Unmoderated_Fully @@ -815,7 +818,7 @@ const ProfileTabBlogs = () => { muteLists.user.authors, muteLists.user.replaceableEvents, nsfwList, - profile?.pubkey, + profilePubkey, userState.user?.npub, userState.user?.pubkey ]) @@ -826,10 +829,7 @@ const ProfileTabBlogs = () => { )} - +
{moderatedAndSortedBlogs.map((b) => ( -- 2.34.1