diff --git a/src/components/CellList.tsx b/src/components/CellList.tsx index d9a3d70..576baa9 100644 --- a/src/components/CellList.tsx +++ b/src/components/CellList.tsx @@ -127,7 +127,7 @@ const CellItem: React.FC<{ cell: Cell }> = ({ cell }) => { diff --git a/src/components/CommentCard.tsx b/src/components/CommentCard.tsx index 020c054..1a8823b 100644 --- a/src/components/CommentCard.tsx +++ b/src/components/CommentCard.tsx @@ -129,9 +129,12 @@ const CommentCard: React.FC = ({
50 ? '...' : '')} + title={ + comment.content.substring(0, 50) + + (comment.content.length > 50 ? '...' : '') + } /> Create New Cell
- + { e.preventDefault()} + onSelect={e => e.preventDefault()} className="flex items-center space-x-2 text-orange-400 focus:text-orange-400" > @@ -306,7 +306,8 @@ const Header = () => { Clear Local Database - This will permanently delete all locally stored data including: + This will permanently delete all locally stored + data including:
• Posts and comments
• User identities and preferences
• Bookmarks and votes diff --git a/src/components/PostCard.tsx b/src/components/PostCard.tsx index bc33a7d..662e3e3 100644 --- a/src/components/PostCard.tsx +++ b/src/components/PostCard.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Link } from 'react-router-dom'; -import { ArrowUp, ArrowDown, MessageSquare, Clipboard } from 'lucide-react'; +import { ArrowUp, ArrowDown, MessageSquare } from 'lucide-react'; import { formatDistanceToNow } from 'date-fns'; import { Post } from '@/types/forum'; import { @@ -70,7 +70,6 @@ const PostCard: React.FC = ({ post, commentCount = 0 }) => { await toggleBookmark(); }; - return (
@@ -180,7 +179,7 @@ const PostCard: React.FC = ({ post, commentCount = 0 }) => { )} diff --git a/src/components/PostDetail.tsx b/src/components/PostDetail.tsx index a121a80..944f8e5 100644 --- a/src/components/PostDetail.tsx +++ b/src/components/PostDetail.tsx @@ -255,7 +255,7 @@ const PostDetail = () => { showText={true} /> diff --git a/src/components/PostList.tsx b/src/components/PostList.tsx index c8fb2f0..1811db6 100644 --- a/src/components/PostList.tsx +++ b/src/components/PostList.tsx @@ -7,7 +7,7 @@ import { usePermissions, useUserVotes, useAuth, - usePostComments, + useForumData, } from '@/hooks'; import { EVerificationStatus } from '@/types/identity'; import { Button } from '@/components/ui/button'; @@ -56,6 +56,7 @@ const PostList = () => { const { canPost, canVote, canModerate } = usePermissions(); const userVotes = useUserVotes(); const { currentUser, verificationStatus } = useAuth(); + const { commentsByPost } = useForumData(); const [newPostTitle, setNewPostTitle] = useState(''); const [newPostContent, setNewPostContent] = useState(''); @@ -339,7 +340,7 @@ const PostList = () => { - {usePostComments(post.id).totalCount} comments + {commentsByPost[post.id]?.length || 0} comments - {showText && ( - Share - )} + {showText && Share} ); -} \ No newline at end of file +} diff --git a/src/components/ui/wallet-wizard.tsx b/src/components/ui/wallet-wizard.tsx index f1b29a7..9c3f9a0 100644 --- a/src/components/ui/wallet-wizard.tsx +++ b/src/components/ui/wallet-wizard.tsx @@ -55,21 +55,9 @@ export function WalletWizard({ onOpenChange(false); }; - // Business logic: determine step status based on current wizard step + // Consolidated step status logic const getStepStatus = (step: WizardStep) => { - if (step < currentStep) { - return 'complete'; - } else if (step === currentStep) { - return 'current'; - } else { - return 'disabled'; - } - }; - - const renderStepIcon = (step: WizardStep) => { - const status = getStepStatus(step); - - // Check if step is actually completed based on auth state + // Check actual completion status first const isActuallyComplete = (step: WizardStep): boolean => { switch (step) { case 1: @@ -83,7 +71,19 @@ export function WalletWizard({ } }; - if (status === 'complete' || isActuallyComplete(step)) { + if (isActuallyComplete(step)) { + return 'complete'; + } else if (step === currentStep) { + return 'current'; + } else { + return 'disabled'; + } + }; + + const renderStepIcon = (step: WizardStep) => { + const status = getStepStatus(step); + + if (status === 'complete') { return ; } else if (status === 'current') { return ; @@ -107,7 +107,7 @@ export function WalletWizard({ return ( - + Setup Your Account @@ -116,21 +116,16 @@ export function WalletWizard({ {/* Progress Indicator */} -
- {[1, 2, 3].map(step => ( +
+ {[1, 2, 3].map((step, index) => (
-
+
{renderStepIcon(step as WizardStep)}
- {step < 3 && ( + {index < 2 && (
- {/* Step Content - Fixed height container */} -
+ {/* Step Content - Flexible height container */} +
{currentStep === 1 && ( handleStepComplete(1)} @@ -185,7 +176,7 @@ export function WalletWizard({
{/* Footer */} -
+

Step {currentStep} of 3

{currentStep > 1 && ( diff --git a/src/contexts/AuthContext.tsx b/src/contexts/AuthContext.tsx index 39ab060..cd531e9 100644 --- a/src/contexts/AuthContext.tsx +++ b/src/contexts/AuthContext.tsx @@ -118,13 +118,18 @@ export function AuthProvider({ children }: { children: React.ReactNode }) { return { ...user, - ensDetails: identity.ensName ? { ensName: identity.ensName } : undefined, + ensDetails: identity.ensName + ? { ensName: identity.ensName } + : undefined, ordinalDetails: identity.ordinalDetails, verificationStatus: identity.verificationStatus, lastChecked: Date.now(), }; } catch (error) { - console.error('Error verifying ownership via UserIdentityService:', error); + console.error( + 'Error verifying ownership via UserIdentityService:', + error + ); return { ...user, ensDetails: undefined, @@ -210,12 +215,15 @@ export function AuthProvider({ children }: { children: React.ReactNode }) { EVerificationStatus.ENS_ORDINAL_VERIFIED ); await saveUser(updatedUser); - await localDatabase.upsertUserIdentity(updatedUser.address, { - ensName: walletInfo.ensName, - verificationStatus: - EVerificationStatus.ENS_ORDINAL_VERIFIED, - lastUpdated: Date.now(), - }); + await localDatabase.upsertUserIdentity( + updatedUser.address, + { + ensName: walletInfo.ensName, + verificationStatus: + EVerificationStatus.ENS_ORDINAL_VERIFIED, + lastUpdated: Date.now(), + } + ); } else { setCurrentUser(newUser); setVerificationStatus(EVerificationStatus.WALLET_CONNECTED); diff --git a/src/lib/database/LocalDatabase.ts b/src/lib/database/LocalDatabase.ts index dcacd6f..3d4658e 100644 --- a/src/lib/database/LocalDatabase.ts +++ b/src/lib/database/LocalDatabase.ts @@ -121,7 +121,7 @@ export class LocalDatabase { public async clearAll(): Promise { // Clear in-memory cache this.clear(); - + // Clear all IndexedDB stores if (!this.db) return; @@ -140,7 +140,7 @@ export class LocalDatabase { ]; const tx = this.db.transaction(storeNames, 'readwrite'); - + await Promise.all( storeNames.map(storeName => { return new Promise((resolve, reject) => { @@ -632,7 +632,8 @@ export class LocalDatabase { record: Partial & { lastUpdated?: number } ): Promise { const existing: UserIdentityCache[string] = - this.cache.userIdentities[address] || { + this.cache.userIdentities[address] || + ({ ensName: undefined, ordinalDetails: undefined, callSign: undefined, @@ -644,12 +645,15 @@ export class LocalDatabase { // Casting below ensures the object satisfies the interface at compile time. lastUpdated: 0, verificationStatus: EVerificationStatus.WALLET_UNCONNECTED, - } as unknown as UserIdentityCache[string]; + } as unknown as UserIdentityCache[string]); const merged: UserIdentityCache[string] = { ...existing, ...record, - lastUpdated: Math.max(existing.lastUpdated ?? 0, record.lastUpdated ?? Date.now()), + lastUpdated: Math.max( + existing.lastUpdated ?? 0, + record.lastUpdated ?? Date.now() + ), } as UserIdentityCache[string]; this.cache.userIdentities[address] = merged; diff --git a/src/lib/services/Ordinals.ts b/src/lib/services/Ordinals.ts index 4a76fe8..9513d71 100644 --- a/src/lib/services/Ordinals.ts +++ b/src/lib/services/Ordinals.ts @@ -1,36 +1,47 @@ -import {Ordiscan, Inscription} from 'ordiscan' +import { Ordiscan, Inscription } from 'ordiscan'; const API_KEY = import.meta.env.VITE_ORDISCAN_API; class Ordinals { - private static instance: Ordinals | null = null; - private ordiscan: Ordiscan; - private readonly PARENT_INSCRIPTION_ID = "add60add0325f7c82e80d4852a8b8d5c46dbde4317e76fe4def2e718dd84b87ci0" + private static instance: Ordinals | null = null; + private ordiscan: Ordiscan; + private readonly PARENT_INSCRIPTION_ID = + 'add60add0325f7c82e80d4852a8b8d5c46dbde4317e76fe4def2e718dd84b87ci0'; - private constructor(ordiscan: Ordiscan) { - this.ordiscan = ordiscan; - } + private constructor(ordiscan: Ordiscan) { + this.ordiscan = ordiscan; + } - static getInstance(): Ordinals { - if (!Ordinals.instance) { - Ordinals.instance = new Ordinals(new Ordiscan(API_KEY)); - } - return Ordinals.instance; + static getInstance(): Ordinals { + if (!Ordinals.instance) { + Ordinals.instance = new Ordinals(new Ordiscan(API_KEY)); } + return Ordinals.instance; + } - /** - * Get Ordinal details for a Bitcoin address - */ - async getOrdinalDetails(address: string): Promise { - const inscriptions = await this.ordiscan.address.getInscriptions({address}) - if (inscriptions.length > 0) { - if (inscriptions.some(inscription => inscription.parent_inscription_id === this.PARENT_INSCRIPTION_ID)) { - return inscriptions.filter(inscription => inscription.parent_inscription_id === this.PARENT_INSCRIPTION_ID) - } else { - return null - } - } - return null + /** + * Get Ordinal details for a Bitcoin address + */ + async getOrdinalDetails(address: string): Promise { + const inscriptions = await this.ordiscan.address.getInscriptions({ + address, + }); + if (inscriptions.length > 0) { + if ( + inscriptions.some( + inscription => + inscription.parent_inscription_id === this.PARENT_INSCRIPTION_ID + ) + ) { + return inscriptions.filter( + inscription => + inscription.parent_inscription_id === this.PARENT_INSCRIPTION_ID + ); + } else { + return null; + } } + return null; + } } -export const ordinals = Ordinals.getInstance(); \ No newline at end of file +export const ordinals = Ordinals.getInstance(); diff --git a/src/lib/wallet/index.ts b/src/lib/wallet/index.ts index 1d7bdf6..90d0f8b 100644 --- a/src/lib/wallet/index.ts +++ b/src/lib/wallet/index.ts @@ -100,7 +100,9 @@ export class WalletManager { /** * Resolve Ordinal details for a Bitcoin address */ - static async resolveOperatorOrdinals(address: string): Promise { + static async resolveOperatorOrdinals( + address: string + ): Promise { try { return await ordinals.getOrdinalDetails(address); } catch (error) { diff --git a/src/pages/DebugPage.tsx b/src/pages/DebugPage.tsx index f151ba3..d4483f1 100644 --- a/src/pages/DebugPage.tsx +++ b/src/pages/DebugPage.tsx @@ -15,7 +15,9 @@ export default function DebugPage() { useEffect(() => { // Subscribe to inbound messages from reliable channel unsubscribeRef.current = messageManager.onMessageReceived(msg => { - setMessages(prev => [{ receivedAt: Date.now(), message: msg }, ...prev].slice(0, 500)); + setMessages(prev => + [{ receivedAt: Date.now(), message: msg }, ...prev].slice(0, 500) + ); }); return () => { @@ -47,7 +49,9 @@ export default function DebugPage() { Total received: {messages.length}
-
+
{Object.values(MessageType).map(t => (
- {t}: {typeCounts[t] || 0} + {t}:{' '} + {typeCounts[t] || 0}
))}
-
-
Recent messages
+
+
+ Recent messages +
ID / Author
Msg Timestamp
{messages.map(m => ( - +
{formatTs(m.receivedAt)}
-
{m.message.type}
+
+ {m.message.type} +
- {m.message.id} — {m.message.author} + {m.message.id} —{' '} + {m.message.author} +
+
+ {formatTs(m.message.timestamp)}
-
{formatTs(m.message.timestamp)}
))}