mirror of
https://github.com/logos-messaging/OpChan.git
synced 2026-01-05 22:33:07 +00:00
chore: fix CSS + useMemo
This commit is contained in:
parent
97d7926659
commit
2dc3cd1e63
@ -127,7 +127,7 @@ const CellItem: React.FC<{ cell: Cell }> = ({ cell }) => {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<ShareButton
|
<ShareButton
|
||||||
size='sm'
|
size="sm"
|
||||||
url={`${window.location.origin}/cell/${cell.id}`}
|
url={`${window.location.origin}/cell/${cell.id}`}
|
||||||
title={cell.name}
|
title={cell.name}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -129,9 +129,12 @@ const CommentCard: React.FC<CommentCardProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<ShareButton
|
<ShareButton
|
||||||
size='sm'
|
size="sm"
|
||||||
url={`${window.location.origin}/post/${postId}#comment-${comment.id}`}
|
url={`${window.location.origin}/post/${postId}#comment-${comment.id}`}
|
||||||
title={comment.content.substring(0, 50) + (comment.content.length > 50 ? '...' : '')}
|
title={
|
||||||
|
comment.content.substring(0, 50) +
|
||||||
|
(comment.content.length > 50 ? '...' : '')
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<BookmarkButton
|
<BookmarkButton
|
||||||
isBookmarked={isBookmarked}
|
isBookmarked={isBookmarked}
|
||||||
|
|||||||
@ -118,7 +118,11 @@ export function CreateCellDialog({
|
|||||||
<DialogTitle className="text-glow">Create New Cell</DialogTitle>
|
<DialogTitle className="text-glow">Create New Cell</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)} onKeyDown={handleKeyDown} className="space-y-4">
|
<form
|
||||||
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
|
onKeyDown={handleKeyDown}
|
||||||
|
className="space-y-4"
|
||||||
|
>
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="title"
|
name="title"
|
||||||
|
|||||||
@ -293,7 +293,7 @@ const Header = () => {
|
|||||||
<AlertDialog>
|
<AlertDialog>
|
||||||
<AlertDialogTrigger asChild>
|
<AlertDialogTrigger asChild>
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
onSelect={(e) => e.preventDefault()}
|
onSelect={e => e.preventDefault()}
|
||||||
className="flex items-center space-x-2 text-orange-400 focus:text-orange-400"
|
className="flex items-center space-x-2 text-orange-400 focus:text-orange-400"
|
||||||
>
|
>
|
||||||
<Trash2 className="w-4 h-4" />
|
<Trash2 className="w-4 h-4" />
|
||||||
@ -306,7 +306,8 @@ const Header = () => {
|
|||||||
Clear Local Database
|
Clear Local Database
|
||||||
</AlertDialogTitle>
|
</AlertDialogTitle>
|
||||||
<AlertDialogDescription className="text-cyber-neutral">
|
<AlertDialogDescription className="text-cyber-neutral">
|
||||||
This will permanently delete all locally stored data including:
|
This will permanently delete all locally stored
|
||||||
|
data including:
|
||||||
<br />• Posts and comments
|
<br />• Posts and comments
|
||||||
<br />• User identities and preferences
|
<br />• User identities and preferences
|
||||||
<br />• Bookmarks and votes
|
<br />• Bookmarks and votes
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
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 { formatDistanceToNow } from 'date-fns';
|
||||||
import { Post } from '@/types/forum';
|
import { Post } from '@/types/forum';
|
||||||
import {
|
import {
|
||||||
@ -70,7 +70,6 @@ const PostCard: React.FC<PostCardProps> = ({ post, commentCount = 0 }) => {
|
|||||||
await toggleBookmark();
|
await toggleBookmark();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="thread-card mb-2">
|
<div className="thread-card mb-2">
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
@ -180,7 +179,7 @@ const PostCard: React.FC<PostCardProps> = ({ post, commentCount = 0 }) => {
|
|||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
<ShareButton
|
<ShareButton
|
||||||
size='sm'
|
size="sm"
|
||||||
url={`${window.location.origin}/post/${post.id}`}
|
url={`${window.location.origin}/post/${post.id}`}
|
||||||
title={post.title}
|
title={post.title}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -255,7 +255,7 @@ const PostDetail = () => {
|
|||||||
showText={true}
|
showText={true}
|
||||||
/>
|
/>
|
||||||
<ShareButton
|
<ShareButton
|
||||||
size='lg'
|
size="lg"
|
||||||
url={`${window.location.origin}/post/${post.id}`}
|
url={`${window.location.origin}/post/${post.id}`}
|
||||||
title={post.title}
|
title={post.title}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import {
|
|||||||
usePermissions,
|
usePermissions,
|
||||||
useUserVotes,
|
useUserVotes,
|
||||||
useAuth,
|
useAuth,
|
||||||
usePostComments,
|
useForumData,
|
||||||
} from '@/hooks';
|
} from '@/hooks';
|
||||||
import { EVerificationStatus } from '@/types/identity';
|
import { EVerificationStatus } from '@/types/identity';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
@ -56,6 +56,7 @@ const PostList = () => {
|
|||||||
const { canPost, canVote, canModerate } = usePermissions();
|
const { canPost, canVote, canModerate } = usePermissions();
|
||||||
const userVotes = useUserVotes();
|
const userVotes = useUserVotes();
|
||||||
const { currentUser, verificationStatus } = useAuth();
|
const { currentUser, verificationStatus } = useAuth();
|
||||||
|
const { commentsByPost } = useForumData();
|
||||||
|
|
||||||
const [newPostTitle, setNewPostTitle] = useState('');
|
const [newPostTitle, setNewPostTitle] = useState('');
|
||||||
const [newPostContent, setNewPostContent] = useState('');
|
const [newPostContent, setNewPostContent] = useState('');
|
||||||
@ -339,7 +340,7 @@ const PostList = () => {
|
|||||||
<span>•</span>
|
<span>•</span>
|
||||||
<span>
|
<span>
|
||||||
<MessageSquare className="inline w-3 h-3 mr-1" />
|
<MessageSquare className="inline w-3 h-3 mr-1" />
|
||||||
{usePostComments(post.id).totalCount} comments
|
{commentsByPost[post.id]?.length || 0} comments
|
||||||
</span>
|
</span>
|
||||||
<ShareButton
|
<ShareButton
|
||||||
url={`${window.location.origin}/post/${post.id}`}
|
url={`${window.location.origin}/post/${post.id}`}
|
||||||
|
|||||||
@ -15,8 +15,6 @@ interface ShareButtonProps {
|
|||||||
|
|
||||||
export function ShareButton({
|
export function ShareButton({
|
||||||
url,
|
url,
|
||||||
title,
|
|
||||||
description = 'Check out this post',
|
|
||||||
size = 'sm',
|
size = 'sm',
|
||||||
variant = 'ghost',
|
variant = 'ghost',
|
||||||
className,
|
className,
|
||||||
@ -73,9 +71,7 @@ export function ShareButton({
|
|||||||
title="Copy link"
|
title="Copy link"
|
||||||
>
|
>
|
||||||
<Share2 size={iconSize[size]} />
|
<Share2 size={iconSize[size]} />
|
||||||
{showText && (
|
{showText && <span className="ml-2 text-xs">Share</span>}
|
||||||
<span className="ml-2 text-xs">Share</span>
|
|
||||||
)}
|
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,21 +55,9 @@ export function WalletWizard({
|
|||||||
onOpenChange(false);
|
onOpenChange(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Business logic: determine step status based on current wizard step
|
// Consolidated step status logic
|
||||||
const getStepStatus = (step: WizardStep) => {
|
const getStepStatus = (step: WizardStep) => {
|
||||||
if (step < currentStep) {
|
// Check actual completion status first
|
||||||
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
|
|
||||||
const isActuallyComplete = (step: WizardStep): boolean => {
|
const isActuallyComplete = (step: WizardStep): boolean => {
|
||||||
switch (step) {
|
switch (step) {
|
||||||
case 1:
|
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 <CheckCircle className="h-5 w-5 text-green-500" />;
|
return <CheckCircle className="h-5 w-5 text-green-500" />;
|
||||||
} else if (status === 'current') {
|
} else if (status === 'current') {
|
||||||
return <Loader2 className="h-5 w-5 text-blue-500 animate-spin" />;
|
return <Loader2 className="h-5 w-5 text-blue-500 animate-spin" />;
|
||||||
@ -107,7 +107,7 @@ export function WalletWizard({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={open} onOpenChange={handleClose}>
|
<Dialog open={open} onOpenChange={handleClose}>
|
||||||
<DialogContent className="sm:max-w-md border-neutral-800 bg-black text-white">
|
<DialogContent className="sm:max-w-lg border-neutral-800 bg-black text-white">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle className="text-xl">Setup Your Account</DialogTitle>
|
<DialogTitle className="text-xl">Setup Your Account</DialogTitle>
|
||||||
<DialogDescription className="text-neutral-400">
|
<DialogDescription className="text-neutral-400">
|
||||||
@ -116,21 +116,16 @@ export function WalletWizard({
|
|||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|
||||||
{/* Progress Indicator */}
|
{/* Progress Indicator */}
|
||||||
<div className="flex items-center justify-between mb-6">
|
<div className="flex items-center justify-center mb-8">
|
||||||
{[1, 2, 3].map(step => (
|
{[1, 2, 3].map((step, index) => (
|
||||||
<div key={step} className="flex items-center">
|
<div key={step} className="flex items-center">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex flex-col items-center gap-2">
|
||||||
{renderStepIcon(step as WizardStep)}
|
{renderStepIcon(step as WizardStep)}
|
||||||
<span
|
<span
|
||||||
className={`text-sm ${
|
className={`text-sm font-medium ${
|
||||||
getStepStatus(step as WizardStep) === 'current'
|
getStepStatus(step as WizardStep) === 'current'
|
||||||
? 'text-blue-500 font-medium'
|
? 'text-blue-500'
|
||||||
: getStepStatus(step as WizardStep) === 'complete' ||
|
: getStepStatus(step as WizardStep) === 'complete'
|
||||||
(step === 1 && isAuthenticated) ||
|
|
||||||
(step === 2 &&
|
|
||||||
verificationStatus !==
|
|
||||||
EVerificationStatus.WALLET_UNCONNECTED) ||
|
|
||||||
(step === 3 && delegationStatus.isValid)
|
|
||||||
? 'text-green-500'
|
? 'text-green-500'
|
||||||
: 'text-gray-400'
|
: 'text-gray-400'
|
||||||
}`}
|
}`}
|
||||||
@ -138,14 +133,10 @@ export function WalletWizard({
|
|||||||
{getStepTitle(step as WizardStep)}
|
{getStepTitle(step as WizardStep)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{step < 3 && (
|
{index < 2 && (
|
||||||
<div
|
<div
|
||||||
className={`w-8 h-px mx-2 ${
|
className={`w-16 h-px mx-4 ${
|
||||||
getStepStatus(step as WizardStep) === 'complete' ||
|
getStepStatus(step as WizardStep) === 'complete'
|
||||||
(step === 1 && isAuthenticated) ||
|
|
||||||
(step === 2 &&
|
|
||||||
verificationStatus !==
|
|
||||||
EVerificationStatus.WALLET_UNCONNECTED)
|
|
||||||
? 'bg-green-500'
|
? 'bg-green-500'
|
||||||
: 'bg-gray-600'
|
: 'bg-gray-600'
|
||||||
}`}
|
}`}
|
||||||
@ -155,8 +146,8 @@ export function WalletWizard({
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Step Content - Fixed height container */}
|
{/* Step Content - Flexible height container */}
|
||||||
<div className="h-[400px] flex flex-col">
|
<div className="min-h-[400px] flex flex-col">
|
||||||
{currentStep === 1 && (
|
{currentStep === 1 && (
|
||||||
<WalletConnectionStep
|
<WalletConnectionStep
|
||||||
onComplete={() => handleStepComplete(1)}
|
onComplete={() => handleStepComplete(1)}
|
||||||
@ -185,7 +176,7 @@ export function WalletWizard({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Footer */}
|
{/* Footer */}
|
||||||
<div className="flex justify-between items-center pt-4 border-t border-neutral-700">
|
<div className="flex justify-between items-center pt-6 mt-4 border-t border-neutral-700">
|
||||||
<p className="text-xs text-neutral-500">Step {currentStep} of 3</p>
|
<p className="text-xs text-neutral-500">Step {currentStep} of 3</p>
|
||||||
{currentStep > 1 && (
|
{currentStep > 1 && (
|
||||||
<Button
|
<Button
|
||||||
@ -193,7 +184,7 @@ export function WalletWizard({
|
|||||||
size="sm"
|
size="sm"
|
||||||
onClick={() => setCurrentStep((currentStep - 1) as WizardStep)}
|
onClick={() => setCurrentStep((currentStep - 1) as WizardStep)}
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
className="text-neutral-400 hover:text-white"
|
className="text-neutral-400 hover:text-white hover:bg-neutral-800"
|
||||||
>
|
>
|
||||||
Back
|
Back
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@ -118,13 +118,18 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
...user,
|
...user,
|
||||||
ensDetails: identity.ensName ? { ensName: identity.ensName } : undefined,
|
ensDetails: identity.ensName
|
||||||
|
? { ensName: identity.ensName }
|
||||||
|
: undefined,
|
||||||
ordinalDetails: identity.ordinalDetails,
|
ordinalDetails: identity.ordinalDetails,
|
||||||
verificationStatus: identity.verificationStatus,
|
verificationStatus: identity.verificationStatus,
|
||||||
lastChecked: Date.now(),
|
lastChecked: Date.now(),
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error verifying ownership via UserIdentityService:', error);
|
console.error(
|
||||||
|
'Error verifying ownership via UserIdentityService:',
|
||||||
|
error
|
||||||
|
);
|
||||||
return {
|
return {
|
||||||
...user,
|
...user,
|
||||||
ensDetails: undefined,
|
ensDetails: undefined,
|
||||||
@ -210,12 +215,15 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|||||||
EVerificationStatus.ENS_ORDINAL_VERIFIED
|
EVerificationStatus.ENS_ORDINAL_VERIFIED
|
||||||
);
|
);
|
||||||
await saveUser(updatedUser);
|
await saveUser(updatedUser);
|
||||||
await localDatabase.upsertUserIdentity(updatedUser.address, {
|
await localDatabase.upsertUserIdentity(
|
||||||
ensName: walletInfo.ensName,
|
updatedUser.address,
|
||||||
verificationStatus:
|
{
|
||||||
EVerificationStatus.ENS_ORDINAL_VERIFIED,
|
ensName: walletInfo.ensName,
|
||||||
lastUpdated: Date.now(),
|
verificationStatus:
|
||||||
});
|
EVerificationStatus.ENS_ORDINAL_VERIFIED,
|
||||||
|
lastUpdated: Date.now(),
|
||||||
|
}
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
setCurrentUser(newUser);
|
setCurrentUser(newUser);
|
||||||
setVerificationStatus(EVerificationStatus.WALLET_CONNECTED);
|
setVerificationStatus(EVerificationStatus.WALLET_CONNECTED);
|
||||||
|
|||||||
@ -121,7 +121,7 @@ export class LocalDatabase {
|
|||||||
public async clearAll(): Promise<void> {
|
public async clearAll(): Promise<void> {
|
||||||
// Clear in-memory cache
|
// Clear in-memory cache
|
||||||
this.clear();
|
this.clear();
|
||||||
|
|
||||||
// Clear all IndexedDB stores
|
// Clear all IndexedDB stores
|
||||||
if (!this.db) return;
|
if (!this.db) return;
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ export class LocalDatabase {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const tx = this.db.transaction(storeNames, 'readwrite');
|
const tx = this.db.transaction(storeNames, 'readwrite');
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
storeNames.map(storeName => {
|
storeNames.map(storeName => {
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
@ -632,7 +632,8 @@ export class LocalDatabase {
|
|||||||
record: Partial<UserIdentityCache[string]> & { lastUpdated?: number }
|
record: Partial<UserIdentityCache[string]> & { lastUpdated?: number }
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const existing: UserIdentityCache[string] =
|
const existing: UserIdentityCache[string] =
|
||||||
this.cache.userIdentities[address] || {
|
this.cache.userIdentities[address] ||
|
||||||
|
({
|
||||||
ensName: undefined,
|
ensName: undefined,
|
||||||
ordinalDetails: undefined,
|
ordinalDetails: undefined,
|
||||||
callSign: undefined,
|
callSign: undefined,
|
||||||
@ -644,12 +645,15 @@ export class LocalDatabase {
|
|||||||
// Casting below ensures the object satisfies the interface at compile time.
|
// Casting below ensures the object satisfies the interface at compile time.
|
||||||
lastUpdated: 0,
|
lastUpdated: 0,
|
||||||
verificationStatus: EVerificationStatus.WALLET_UNCONNECTED,
|
verificationStatus: EVerificationStatus.WALLET_UNCONNECTED,
|
||||||
} as unknown as UserIdentityCache[string];
|
} as unknown as UserIdentityCache[string]);
|
||||||
|
|
||||||
const merged: UserIdentityCache[string] = {
|
const merged: UserIdentityCache[string] = {
|
||||||
...existing,
|
...existing,
|
||||||
...record,
|
...record,
|
||||||
lastUpdated: Math.max(existing.lastUpdated ?? 0, record.lastUpdated ?? Date.now()),
|
lastUpdated: Math.max(
|
||||||
|
existing.lastUpdated ?? 0,
|
||||||
|
record.lastUpdated ?? Date.now()
|
||||||
|
),
|
||||||
} as UserIdentityCache[string];
|
} as UserIdentityCache[string];
|
||||||
|
|
||||||
this.cache.userIdentities[address] = merged;
|
this.cache.userIdentities[address] = merged;
|
||||||
|
|||||||
@ -1,36 +1,47 @@
|
|||||||
import {Ordiscan, Inscription} from 'ordiscan'
|
import { Ordiscan, Inscription } from 'ordiscan';
|
||||||
const API_KEY = import.meta.env.VITE_ORDISCAN_API;
|
const API_KEY = import.meta.env.VITE_ORDISCAN_API;
|
||||||
|
|
||||||
class Ordinals {
|
class Ordinals {
|
||||||
private static instance: Ordinals | null = null;
|
private static instance: Ordinals | null = null;
|
||||||
private ordiscan: Ordiscan;
|
private ordiscan: Ordiscan;
|
||||||
private readonly PARENT_INSCRIPTION_ID = "add60add0325f7c82e80d4852a8b8d5c46dbde4317e76fe4def2e718dd84b87ci0"
|
private readonly PARENT_INSCRIPTION_ID =
|
||||||
|
'add60add0325f7c82e80d4852a8b8d5c46dbde4317e76fe4def2e718dd84b87ci0';
|
||||||
|
|
||||||
private constructor(ordiscan: Ordiscan) {
|
private constructor(ordiscan: Ordiscan) {
|
||||||
this.ordiscan = ordiscan;
|
this.ordiscan = ordiscan;
|
||||||
}
|
}
|
||||||
|
|
||||||
static getInstance(): Ordinals {
|
static getInstance(): Ordinals {
|
||||||
if (!Ordinals.instance) {
|
if (!Ordinals.instance) {
|
||||||
Ordinals.instance = new Ordinals(new Ordiscan(API_KEY));
|
Ordinals.instance = new Ordinals(new Ordiscan(API_KEY));
|
||||||
}
|
|
||||||
return Ordinals.instance;
|
|
||||||
}
|
}
|
||||||
|
return Ordinals.instance;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Ordinal details for a Bitcoin address
|
* Get Ordinal details for a Bitcoin address
|
||||||
*/
|
*/
|
||||||
async getOrdinalDetails(address: string): Promise<Inscription[] | null> {
|
async getOrdinalDetails(address: string): Promise<Inscription[] | null> {
|
||||||
const inscriptions = await this.ordiscan.address.getInscriptions({address})
|
const inscriptions = await this.ordiscan.address.getInscriptions({
|
||||||
if (inscriptions.length > 0) {
|
address,
|
||||||
if (inscriptions.some(inscription => inscription.parent_inscription_id === this.PARENT_INSCRIPTION_ID)) {
|
});
|
||||||
return inscriptions.filter(inscription => inscription.parent_inscription_id === this.PARENT_INSCRIPTION_ID)
|
if (inscriptions.length > 0) {
|
||||||
} else {
|
if (
|
||||||
return null
|
inscriptions.some(
|
||||||
}
|
inscription =>
|
||||||
}
|
inscription.parent_inscription_id === this.PARENT_INSCRIPTION_ID
|
||||||
return null
|
)
|
||||||
|
) {
|
||||||
|
return inscriptions.filter(
|
||||||
|
inscription =>
|
||||||
|
inscription.parent_inscription_id === this.PARENT_INSCRIPTION_ID
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ordinals = Ordinals.getInstance();
|
export const ordinals = Ordinals.getInstance();
|
||||||
|
|||||||
@ -100,7 +100,9 @@ export class WalletManager {
|
|||||||
/**
|
/**
|
||||||
* Resolve Ordinal details for a Bitcoin address
|
* Resolve Ordinal details for a Bitcoin address
|
||||||
*/
|
*/
|
||||||
static async resolveOperatorOrdinals(address: string): Promise<Inscription[] | null> {
|
static async resolveOperatorOrdinals(
|
||||||
|
address: string
|
||||||
|
): Promise<Inscription[] | null> {
|
||||||
try {
|
try {
|
||||||
return await ordinals.getOrdinalDetails(address);
|
return await ordinals.getOrdinalDetails(address);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@ -15,7 +15,9 @@ export default function DebugPage() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Subscribe to inbound messages from reliable channel
|
// Subscribe to inbound messages from reliable channel
|
||||||
unsubscribeRef.current = messageManager.onMessageReceived(msg => {
|
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 () => {
|
return () => {
|
||||||
@ -47,7 +49,9 @@ export default function DebugPage() {
|
|||||||
Total received: {messages.length}
|
Total received: {messages.length}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ marginTop: 12, display: 'flex', gap: 12, flexWrap: 'wrap' }}>
|
<div
|
||||||
|
style={{ marginTop: 12, display: 'flex', gap: 12, flexWrap: 'wrap' }}
|
||||||
|
>
|
||||||
{Object.values(MessageType).map(t => (
|
{Object.values(MessageType).map(t => (
|
||||||
<div
|
<div
|
||||||
key={t}
|
key={t}
|
||||||
@ -59,13 +63,22 @@ export default function DebugPage() {
|
|||||||
background: 'rgba(51,65,85,0.2)',
|
background: 'rgba(51,65,85,0.2)',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<strong style={{ textTransform: 'capitalize' }}>{t}</strong>: {typeCounts[t] || 0}
|
<strong style={{ textTransform: 'capitalize' }}>{t}</strong>:{' '}
|
||||||
|
{typeCounts[t] || 0}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ marginTop: 16, borderTop: '1px solid #334155', paddingTop: 12 }}>
|
<div
|
||||||
<div style={{ fontSize: 14, fontWeight: 700, marginBottom: 8 }}>Recent messages</div>
|
style={{
|
||||||
|
marginTop: 16,
|
||||||
|
borderTop: '1px solid #334155',
|
||||||
|
paddingTop: 12,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{ fontSize: 14, fontWeight: 700, marginBottom: 8 }}>
|
||||||
|
Recent messages
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: 'grid',
|
display: 'grid',
|
||||||
@ -79,9 +92,11 @@ export default function DebugPage() {
|
|||||||
<div style={{ fontWeight: 700, color: '#cbd5e1' }}>ID / Author</div>
|
<div style={{ fontWeight: 700, color: '#cbd5e1' }}>ID / Author</div>
|
||||||
<div style={{ fontWeight: 700, color: '#cbd5e1' }}>Msg Timestamp</div>
|
<div style={{ fontWeight: 700, color: '#cbd5e1' }}>Msg Timestamp</div>
|
||||||
{messages.map(m => (
|
{messages.map(m => (
|
||||||
<Fragment key={`${m.message.id}:${m.receivedAt}`}>
|
<Fragment key={`${m.message.id}:${m.receivedAt}`}>
|
||||||
<div style={{ color: '#e5e7eb' }}>{formatTs(m.receivedAt)}</div>
|
<div style={{ color: '#e5e7eb' }}>{formatTs(m.receivedAt)}</div>
|
||||||
<div style={{ textTransform: 'capitalize', color: '#e5e7eb' }}>{m.message.type}</div>
|
<div style={{ textTransform: 'capitalize', color: '#e5e7eb' }}>
|
||||||
|
{m.message.type}
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
@ -91,9 +106,12 @@ export default function DebugPage() {
|
|||||||
}}
|
}}
|
||||||
title={`${m.message.id} — ${m.message.author}`}
|
title={`${m.message.id} — ${m.message.author}`}
|
||||||
>
|
>
|
||||||
{m.message.id} — <span style={{ color: '#94a3b8' }}>{m.message.author}</span>
|
{m.message.id} —{' '}
|
||||||
|
<span style={{ color: '#94a3b8' }}>{m.message.author}</span>
|
||||||
|
</div>
|
||||||
|
<div style={{ color: '#e5e7eb' }}>
|
||||||
|
{formatTs(m.message.timestamp)}
|
||||||
</div>
|
</div>
|
||||||
<div style={{ color: '#e5e7eb' }}>{formatTs(m.message.timestamp)}</div>
|
|
||||||
</Fragment>
|
</Fragment>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user