mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-03-17 21:31:43 +01:00
add web manifest
fix formatting
This commit is contained in:
parent
f2f8c16297
commit
e0a1b2ed1b
@ -3,12 +3,10 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, user-scalable=0"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0" />
|
||||
<link rel="stylesheet" href="./src/styles.css" />
|
||||
<title>personal-nostr-client</title>
|
||||
<meta name="description" content="A simple web based nostr client i built myself." />
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
@ -22,7 +22,7 @@ export class NostrSubscription {
|
||||
seenEvents = new Set<string>();
|
||||
|
||||
constructor(relayUrls: string[], query?: NostrQuery, name?: string) {
|
||||
this.id = String(name||lastId++);
|
||||
this.id = String(name || lastId++);
|
||||
this.query = query;
|
||||
this.name = name;
|
||||
this.relayUrls = relayUrls;
|
||||
|
@ -1,14 +1,6 @@
|
||||
import React from "react";
|
||||
import {
|
||||
ErrorBoundary as ErrorBoundaryHelper,
|
||||
FallbackProps,
|
||||
} from "react-error-boundary";
|
||||
import {
|
||||
Alert,
|
||||
AlertIcon,
|
||||
AlertTitle,
|
||||
AlertDescription,
|
||||
} from "@chakra-ui/react";
|
||||
import { ErrorBoundary as ErrorBoundaryHelper, FallbackProps } from "react-error-boundary";
|
||||
import { Alert, AlertIcon, AlertTitle, AlertDescription } from "@chakra-ui/react";
|
||||
|
||||
export function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
|
||||
return (
|
||||
@ -20,12 +12,7 @@ export function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
|
||||
);
|
||||
}
|
||||
|
||||
export const ErrorBoundary = ({
|
||||
children,
|
||||
...props
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) => (
|
||||
export const ErrorBoundary = ({ children, ...props }: { children: React.ReactNode }) => (
|
||||
<ErrorBoundaryHelper FallbackComponent={ErrorFallback} {...props}>
|
||||
{children}
|
||||
</ErrorBoundaryHelper>
|
||||
|
@ -1,10 +1,4 @@
|
||||
import {
|
||||
Menu,
|
||||
MenuButton,
|
||||
MenuList,
|
||||
IconButton,
|
||||
MenuListProps,
|
||||
} from "@chakra-ui/react";
|
||||
import { Menu, MenuButton, MenuList, IconButton, MenuListProps } from "@chakra-ui/react";
|
||||
import { MoreIcon } from "./icons";
|
||||
|
||||
export type MenuIconButtonProps = {
|
||||
@ -13,13 +7,7 @@ export type MenuIconButtonProps = {
|
||||
|
||||
export const MenuIconButton = ({ children }: MenuIconButtonProps) => (
|
||||
<Menu isLazy>
|
||||
<MenuButton
|
||||
as={IconButton}
|
||||
icon={<MoreIcon />}
|
||||
aria-label="view raw"
|
||||
title="view raw"
|
||||
size="xs"
|
||||
/>
|
||||
<MenuButton as={IconButton} icon={<MoreIcon />} aria-label="view raw" title="view raw" size="xs" />
|
||||
<MenuList>{children}</MenuList>
|
||||
</Menu>
|
||||
);
|
||||
|
@ -15,17 +15,7 @@ export const ProfileButton = ({ to }: ProfileButtonProps) => {
|
||||
const metadata = useUserMetadata(pubkey);
|
||||
|
||||
return (
|
||||
<LinkBox
|
||||
as={Link}
|
||||
maxW="sm"
|
||||
p="2"
|
||||
borderWidth="1px"
|
||||
rounded="md"
|
||||
to={to}
|
||||
display="flex"
|
||||
gap="2"
|
||||
overflow="hidden"
|
||||
>
|
||||
<LinkBox as={Link} maxW="sm" p="2" borderWidth="1px" rounded="md" to={to} display="flex" gap="2" overflow="hidden">
|
||||
<UserAvatar pubkey={pubkey} />
|
||||
<Box>
|
||||
<Text fontWeight="bold">{metadata?.name}</Text>
|
||||
|
@ -6,19 +6,15 @@ import { useUserMetadata } from "../hooks/use-user-metadata";
|
||||
import { UserAvatar, UserAvatarProps } from "./user-avatar";
|
||||
import { getUserDisplayName } from "../helpers/user-metadata";
|
||||
|
||||
export const UserAvatarLink = React.memo(
|
||||
({ pubkey, ...props }: UserAvatarProps) => {
|
||||
const metadata = useUserMetadata(pubkey);
|
||||
const label = metadata
|
||||
? getUserDisplayName(metadata, pubkey)
|
||||
: "Loading...";
|
||||
export const UserAvatarLink = React.memo(({ pubkey, ...props }: UserAvatarProps) => {
|
||||
const metadata = useUserMetadata(pubkey);
|
||||
const label = metadata ? getUserDisplayName(metadata, pubkey) : "Loading...";
|
||||
|
||||
return (
|
||||
<Tooltip label={label}>
|
||||
<Link to={`/u/${normalizeToBech32(pubkey, Bech32Prefix.Pubkey)}`}>
|
||||
<UserAvatar pubkey={pubkey} {...props} />
|
||||
</Link>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
);
|
||||
return (
|
||||
<Tooltip label={label}>
|
||||
<Link to={`/u/${normalizeToBech32(pubkey, Bech32Prefix.Pubkey)}`}>
|
||||
<UserAvatar pubkey={pubkey} {...props} />
|
||||
</Link>
|
||||
</Tooltip>
|
||||
);
|
||||
});
|
||||
|
@ -1,10 +1,4 @@
|
||||
import {
|
||||
decode,
|
||||
Section,
|
||||
AmountSection,
|
||||
DescriptionSection,
|
||||
TimestampSection,
|
||||
} from "light-bolt11-decoder";
|
||||
import { decode, Section, AmountSection, DescriptionSection, TimestampSection } from "light-bolt11-decoder";
|
||||
import { convertTimestampToDate } from "./date";
|
||||
|
||||
export type ParsedInvoice = {
|
||||
|
@ -59,10 +59,7 @@ export function fromHexString(str: string) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
export function normalizeToBech32(
|
||||
key: string,
|
||||
prefix: Bech32Prefix = Bech32Prefix.Pubkey
|
||||
) {
|
||||
export function normalizeToBech32(key: string, prefix: Bech32Prefix = Bech32Prefix.Pubkey) {
|
||||
if (isHex(key)) return hexToBech32(key, prefix);
|
||||
if (isBech32Key(key)) return key;
|
||||
return null;
|
||||
|
@ -2,10 +2,7 @@ import { Kind0ParsedContent } from "../types/nostr-event";
|
||||
import { normalizeToBech32 } from "./nip-19";
|
||||
import { truncatedId } from "./nostr-event";
|
||||
|
||||
export function getUserDisplayName(
|
||||
metadata: Kind0ParsedContent | undefined,
|
||||
pubkey: string
|
||||
) {
|
||||
export function getUserDisplayName(metadata: Kind0ParsedContent | undefined, pubkey: string) {
|
||||
if (metadata?.display_name && metadata?.name) {
|
||||
return `${metadata.display_name} (${metadata.name})`;
|
||||
} else if (metadata?.name) {
|
||||
|
14
src/types/nostr-extensions.d.ts
vendored
14
src/types/nostr-extensions.d.ts
vendored
@ -6,18 +6,10 @@ declare global {
|
||||
enabled: boolean;
|
||||
getPublicKey: () => Promise<string> | string;
|
||||
signEvent: (event: NostrEvent) => Promise<NostrEvent> | NostrEvent;
|
||||
getRelays: () =>
|
||||
| Record<string, { read: boolean; write: boolean }>
|
||||
| string[];
|
||||
getRelays: () => Record<string, { read: boolean; write: boolean }> | string[];
|
||||
nip04?: {
|
||||
encrypt: (
|
||||
pubkey: string,
|
||||
plaintext: string
|
||||
) => Promise<string> | string;
|
||||
decrypt: (
|
||||
pubkey: string,
|
||||
ciphertext: string
|
||||
) => Promise<string> | string;
|
||||
encrypt: (pubkey: string, plaintext: string) => Promise<string> | string;
|
||||
decrypt: (pubkey: string, ciphertext: string) => Promise<string> | string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -4,10 +4,7 @@ export type NostrOutgoingEvent = ["EVENT", NostrEvent];
|
||||
export type NostrOutgoingRequest = ["REQ", string, NostrQuery];
|
||||
export type NostrOutgoingClose = ["CLOSE", string];
|
||||
|
||||
export type NostrOutgoingMessage =
|
||||
| NostrOutgoingEvent
|
||||
| NostrOutgoingRequest
|
||||
| NostrOutgoingClose;
|
||||
export type NostrOutgoingMessage = NostrOutgoingEvent | NostrOutgoingRequest | NostrOutgoingClose;
|
||||
|
||||
export type NostrQuery = {
|
||||
ids?: string[];
|
||||
|
@ -14,9 +14,7 @@ export const LoginView = () => {
|
||||
return (
|
||||
<Flex direction="column" alignItems="center" justifyContent="center">
|
||||
<Heading>Login</Heading>
|
||||
<Button onClick={() => identity.loginWithExtension()}>
|
||||
Use browser extension
|
||||
</Button>
|
||||
<Button onClick={() => identity.loginWithExtension()}>Use browser extension</Button>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
@ -1,13 +1,4 @@
|
||||
import {
|
||||
Avatar,
|
||||
Button,
|
||||
Flex,
|
||||
FormControl,
|
||||
FormLabel,
|
||||
Input,
|
||||
SkeletonText,
|
||||
Textarea,
|
||||
} from "@chakra-ui/react";
|
||||
import { Avatar, Button, Flex, FormControl, FormLabel, Input, SkeletonText, Textarea } from "@chakra-ui/react";
|
||||
import { useMemo } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
@ -55,12 +46,7 @@ const MetadataForm = ({ defaultValues, onSubmit }: MetadataFormProps) => {
|
||||
</Flex>
|
||||
<FormControl>
|
||||
<FormLabel>About</FormLabel>
|
||||
<Textarea
|
||||
placeholder="A short description"
|
||||
resize="vertical"
|
||||
rows={6}
|
||||
{...register("about")}
|
||||
/>
|
||||
<Textarea placeholder="A short description" resize="vertical" rows={6} {...register("about")} />
|
||||
</FormControl>
|
||||
<Flex alignSelf="flex-end" gap="2">
|
||||
<Button onClick={() => reset()}>Reset</Button>
|
||||
|
@ -24,7 +24,5 @@ export const RelayStatus = ({ url }: { url: string }) => {
|
||||
|
||||
useInterval(() => update(), 500);
|
||||
|
||||
return (
|
||||
<Badge colorScheme={getStatusColor(relay)}>{getStatusText(relay)}</Badge>
|
||||
);
|
||||
return <Badge colorScheme={getStatusColor(relay)}>{getStatusText(relay)}</Badge>;
|
||||
};
|
||||
|
@ -7,5 +7,17 @@ export default defineConfig({
|
||||
build: {
|
||||
target: ["chrome89", "edge89", "firefox89", "safari15"],
|
||||
},
|
||||
plugins: [react(), VitePWA({ registerType: "autoUpdate" })],
|
||||
plugins: [
|
||||
react(),
|
||||
VitePWA({
|
||||
registerType: "autoUpdate",
|
||||
manifest: {
|
||||
name: "Personal Nostr Client",
|
||||
description: "A simple PWA nostr client",
|
||||
orientation: "portrait",
|
||||
theme_color: "#c641c4",
|
||||
categories: ["nostr"],
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user