Browse Source

move report issue button on error message to gitrepublic

imwald
Silberengel 1 month ago
parent
commit
a8f71b6a7f
  1. 39
      src/components/ErrorBoundary.tsx
  2. 9
      src/pages/primary/NoteListPage/FollowingFeed.tsx
  3. 20
      src/pages/primary/NoteListPage/index.tsx

39
src/components/ErrorBoundary.tsx

@ -1,11 +1,12 @@
import { Button } from '@/components/ui/button' import { Button } from '@/components/ui/button'
import PostContent from '@/components/PostEditor/PostContent'
import { SILBERENGEL_PUBKEY } from '@/constants'
import { MessageCircle, RotateCw } from 'lucide-react' import { MessageCircle, RotateCw } from 'lucide-react'
import React, { Component, ReactNode } from 'react' import React, { Component, ReactNode } from 'react'
import { toast } from 'sonner' import { toast } from 'sonner'
import logger from '@/lib/logger' import logger from '@/lib/logger'
const ISSUES_URL =
'https://gitrepublic.imwald.eu/repos/npub1l5sga6xg72phsz5422ykujprejwud075ggrr3z2hwyrfgr7eylqstegx9z/jumble-imwald-edition?tab=issues'
interface ErrorBoundaryProps { interface ErrorBoundaryProps {
children: ReactNode children: ReactNode
} }
@ -13,17 +14,16 @@ interface ErrorBoundaryProps {
interface ErrorBoundaryState { interface ErrorBoundaryState {
hasError: boolean hasError: boolean
error?: Error error?: Error
showErrorReportDialog: boolean
} }
export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> { export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
constructor(props: ErrorBoundaryProps) { constructor(props: ErrorBoundaryProps) {
super(props) super(props)
this.state = { hasError: false, showErrorReportDialog: false } this.state = { hasError: false }
} }
static getDerivedStateFromError(error: Error) { static getDerivedStateFromError(error: Error) {
return { hasError: true, error, showErrorReportDialog: false } return { hasError: true, error }
} }
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) { componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
@ -36,19 +36,21 @@ export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundarySt
<div className="w-screen h-screen flex flex-col items-center justify-center p-4 gap-4"> <div className="w-screen h-screen flex flex-col items-center justify-center p-4 gap-4">
<h1 className="text-2xl font-bold">Oops, something went wrong.</h1> <h1 className="text-2xl font-bold">Oops, something went wrong.</h1>
<p className="text-lg text-center max-w-md"> <p className="text-lg text-center max-w-md">
Sorry for the inconvenience. You can help by sending me a public message with the error details. Sorry for the inconvenience. You can help by logging an issue with the error details.
</p> </p>
{this.state.error?.message && ( {this.state.error?.message && (
<> <>
<div className="flex gap-2"> <div className="flex gap-2">
<Button <Button asChild className="bg-primary text-primary-foreground">
onClick={() => { <a
this.setState({ showErrorReportDialog: true }) href={ISSUES_URL}
}} target="_blank"
className="bg-primary text-primary-foreground" rel="noopener noreferrer"
className="inline-flex items-center"
> >
<MessageCircle className="w-4 h-4 mr-2" /> <MessageCircle className="w-4 h-4 mr-2" />
Send Error Report Report issue
</a>
</Button> </Button>
<Button <Button
onClick={() => { onClick={() => {
@ -69,19 +71,6 @@ export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundarySt
<RotateCw className="w-4 h-4 mr-2" /> <RotateCw className="w-4 h-4 mr-2" />
Reload Page Reload Page
</Button> </Button>
{this.state.showErrorReportDialog && (
<PostContent
defaultContent={`@${SILBERENGEL_PUBKEY} Jumble Error Report:
${this.state.error?.message || 'Unknown error'}
Please help investigate this issue. Thank you!`}
close={() => {
this.setState({ showErrorReportDialog: false })
}}
/>
)}
</div> </div>
) )
} }

9
src/pages/primary/NoteListPage/FollowingFeed.tsx

@ -3,9 +3,14 @@ import { useFeed } from '@/providers/FeedProvider'
import { useNostr } from '@/providers/NostrProvider' import { useNostr } from '@/providers/NostrProvider'
import client from '@/services/client.service' import client from '@/services/client.service'
import { TFeedSubRequest } from '@/types' import { TFeedSubRequest } from '@/types'
import type { ReactNode } from 'react'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
export default function FollowingFeed() { export default function FollowingFeed({
setSubHeader
}: {
setSubHeader?: (node: ReactNode) => void
}) {
const { pubkey } = useNostr() const { pubkey } = useNostr()
const { feedInfo } = useFeed() const { feedInfo } = useFeed()
const [subRequests, setSubRequests] = useState<TFeedSubRequest[]>([]) const [subRequests, setSubRequests] = useState<TFeedSubRequest[]>([])
@ -24,5 +29,5 @@ export default function FollowingFeed() {
init() init()
}, [feedInfo.feedType, pubkey]) }, [feedInfo.feedType, pubkey])
return <NormalFeed subRequests={subRequests} isMainFeed /> return <NormalFeed subRequests={subRequests} isMainFeed setSubHeader={setSubHeader} />
} }

20
src/pages/primary/NoteListPage/index.tsx

@ -13,6 +13,7 @@ import React, {
Dispatch, Dispatch,
forwardRef, forwardRef,
SetStateAction, SetStateAction,
useCallback,
useEffect, useEffect,
useImperativeHandle, useImperativeHandle,
useRef, useRef,
@ -39,11 +40,18 @@ const NoteListPage = forwardRef((_, ref) => {
const [homeSubHeader, setHomeSubHeader] = useState<React.ReactNode>(null) const [homeSubHeader, setHomeSubHeader] = useState<React.ReactNode>(null)
useImperativeHandle(ref, () => layoutRef.current) useImperativeHandle(ref, () => layoutRef.current)
// Clear subHeader when switching away from relay/relays/all-favorites feed const setHomeSubHeaderStable = useCallback((node: React.ReactNode) => {
setHomeSubHeader(node)
}, [])
// Clear subHeader when switching to a feed that doesn't use it (e.g. bookmarks)
useEffect(() => { useEffect(() => {
const isRelaysFeed = const usesSubHeader =
feedInfo.feedType === 'relay' || feedInfo.feedType === 'relays' || feedInfo.feedType === 'all-favorites' feedInfo.feedType === 'relay' ||
if (!isRelaysFeed) setHomeSubHeader(null) feedInfo.feedType === 'relays' ||
feedInfo.feedType === 'all-favorites' ||
feedInfo.feedType === 'following'
if (!usesSubHeader) setHomeSubHeader(null)
}, [feedInfo.feedType]) }, [feedInfo.feedType])
// REMOVED: Scroll-to-top logic - feed should NEVER scroll to top when drawer opens/closes // REMOVED: Scroll-to-top logic - feed should NEVER scroll to top when drawer opens/closes
@ -90,14 +98,14 @@ const NoteListPage = forwardRef((_, ref) => {
content = <BookmarkList /> content = <BookmarkList />
} }
} else if (feedInfo.feedType === 'following') { } else if (feedInfo.feedType === 'following') {
content = <FollowingFeed /> content = <FollowingFeed setSubHeader={setHomeSubHeaderStable} />
} else { } else {
content = ( content = (
<> <>
{showRelayDetails && feedInfo.feedType === 'relay' && !!feedInfo.id && ( {showRelayDetails && feedInfo.feedType === 'relay' && !!feedInfo.id && (
<RelayInfo url={feedInfo.id!} className="mb-2 pt-3" /> <RelayInfo url={feedInfo.id!} className="mb-2 pt-3" />
)} )}
<RelaysFeed setSubHeader={setHomeSubHeader} /> <RelaysFeed setSubHeader={setHomeSubHeaderStable} />
</> </>
) )
} }

Loading…
Cancel
Save