wip: polish

This commit is contained in:
2023-10-18 08:43:31 +07:00
parent 7fa1e89dc8
commit 489ab6bd0b
17 changed files with 293 additions and 205 deletions

View File

@@ -1,11 +1,12 @@
import { NDKFilter, NDKKind } from '@nostr-dev-kit/ndk';
import * as Avatar from '@radix-ui/react-avatar';
import { minidenticon } from 'minidenticons';
import { useEffect } from 'react';
import { Link } from 'react-router-dom';
import { useStorage } from '@libs/storage/provider';
import { HorizontalDotsIcon } from '@shared/icons';
import { Image } from '@shared/image';
import { useActivities } from '@stores/activities';
@@ -19,6 +20,9 @@ export function ActiveAccount() {
const { sub } = useNostr();
const addActivity = useActivities((state) => state.addActivity);
const svgURI =
'data:image/svg+xml;utf8,' +
encodeURIComponent(minidenticon(db.account.pubkey, 90, 50));
useEffect(() => {
const filter: NDKFilter = {
@@ -57,12 +61,24 @@ export function ActiveAccount() {
return (
<div className="flex flex-col gap-1 rounded-lg bg-neutral-100 p-1 hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800">
<Link to={`/users/${db.account.pubkey}`} className="relative inline-block">
<Image
src={user?.picture || user?.image}
alt={db.account.npub}
className="aspect-square h-auto w-full rounded-md"
/>
<span className="absolute bottom-0 right-0 block h-2 w-2 rounded-full bg-emerald-500 ring-2 ring-neutral-100 dark:ring-neutral-900" />
<Avatar.Root>
<Avatar.Image
src={user?.picture || user?.image}
alt={db.account.pubkey}
loading="lazy"
decoding="async"
style={{ contentVisibility: 'auto' }}
className="aspect-square h-auto w-full rounded-md"
/>
<Avatar.Fallback delayMs={300}>
<img
src={svgURI}
alt={db.account.pubkeypubkey}
className="aspect-square h-auto w-full rounded-md bg-black dark:bg-white"
/>
</Avatar.Fallback>
</Avatar.Root>
<span className="absolute bottom-0 right-0 block h-2 w-2 rounded-full bg-teal-500 ring-2 ring-neutral-100 dark:ring-neutral-900" />
</Link>
<div className="inline-flex items-center justify-center rounded-md">
<HorizontalDotsIcon className="h-4 w-4" />

View File

@@ -25,7 +25,7 @@ export function AvatarUploader({
<button
type="button"
onClick={() => uploadAvatar()}
className="inline-flex items-center gap-1 rounded-lg border border-blue-200 bg-blue-100 px-1.5 py-1 text-sm font-medium text-blue-500 hover:bg-blue-200 dark:bg-blue-900 dark:text-blue-500 dark:hover:bg-blue-800"
className="inline-flex items-center gap-1 rounded-lg border border-blue-200 bg-blue-100 px-1.5 py-1 text-sm font-medium text-blue-500 hover:border-blue-300 hover:bg-blue-200 dark:bg-blue-900 dark:text-blue-500 dark:hover:border-blue-800 dark:hover:bg-blue-800"
>
{loading ? (
<LoaderIcon className="h-4 w-4 animate-spin" />

View File

@@ -28,7 +28,7 @@ export function ComposerModal() {
<Dialog.Trigger asChild>
<button
type="button"
className="flex aspect-square h-auto w-full items-center justify-center rounded-lg bg-neutral-300 text-black hover:bg-blue-600 hover:text-white dark:bg-neutral-700 dark:text-white dark:hover:bg-blue-600"
className="flex aspect-square h-auto w-full items-center justify-center rounded-lg bg-neutral-100 text-black hover:bg-blue-500 hover:text-white dark:bg-neutral-900 dark:text-white dark:hover:bg-blue-500"
>
<ComposeIcon className="h-5 w-5" />
</button>

View File

@@ -26,7 +26,7 @@ export function Navigation() {
>
<HomeIcon className="h-6 w-6" />
</div>
<div className="text-sm text-black dark:text-white">Home</div>
<div className="text-sm font-medium text-black dark:text-white">Home</div>
</>
)}
</NavLink>
@@ -47,7 +47,7 @@ export function Navigation() {
>
<ChatsIcon className="h-6 w-6" />
</div>
<div className="text-sm text-black dark:text-white">Chats</div>
<div className="text-sm font-medium text-black dark:text-white">Chats</div>
</>
)}
</NavLink>
@@ -68,7 +68,7 @@ export function Navigation() {
>
<RelayIcon className="h-6 w-6" />
</div>
<div className="text-sm text-black dark:text-white">Relays</div>
<div className="text-sm font-medium text-black dark:text-white">Relays</div>
</>
)}
</NavLink>
@@ -89,7 +89,9 @@ export function Navigation() {
>
<ExploreIcon className="h-6 w-6" />
</div>
<div className="text-sm text-black dark:text-white">Explore</div>
<div className="text-sm font-medium text-black dark:text-white">
Explore
</div>
</>
)}
</NavLink>
@@ -98,7 +100,7 @@ export function Navigation() {
<ComposerModal />
<Link
to="/nwc"
className="flex aspect-square h-auto w-full items-center justify-center rounded-lg bg-neutral-100 hover:bg-blue-600 hover:text-white dark:bg-neutral-900 dark:hover:bg-blue-600"
className="flex aspect-square h-auto w-full items-center justify-center rounded-lg bg-neutral-100 hover:bg-blue-500 hover:text-white dark:bg-neutral-900 dark:hover:bg-blue-500"
>
<NwcIcon className="h-5 w-5" />
</Link>

View File

@@ -1,20 +1,36 @@
import { useStorage } from '@libs/storage/provider';
import { CancelIcon } from '@shared/icons';
import { User } from '@shared/user';
import { useWidgets } from '@stores/widgets';
export function TitleBar({ id, title }: { id?: string; title: string }) {
export function TitleBar({ id, title }: { id?: string; title?: string }) {
const { db } = useStorage();
const remove = useWidgets((state) => state.removeWidget);
return (
<div className="flex h-11 w-full shrink-0 items-center justify-between overflow-hidden px-3">
<div className="w-6" />
<h3 className="text-sm font-medium tracking-wide text-neutral-900 dark:text-neutral-100">
{title}
</h3>
{id ? (
{id === '9999' ? (
<div className="isolate flex -space-x-2">
{db.account.circles
?.slice(0, 4)
.map((item) => <User key={item} pubkey={item} variant="ministacked" />)}
{db.account.circles?.length > 4 ? (
<div className="inline-flex h-6 w-6 items-center justify-center rounded-full bg-neutral-200 text-neutral-900 ring-1 ring-neutral-300 dark:bg-neutral-800 dark:text-neutral-100 dark:ring-neutral-700">
<span className="text-xs font-medium">
+{db.account.circles?.length - 4}
</span>
</div>
) : null}
</div>
) : (
<h3 className="text-sm font-medium tracking-wide text-neutral-900 dark:text-neutral-100">
{title}
</h3>
)}
{id !== '9999' ? (
<button
type="button"
onClick={() => remove(db, id)}

View File

@@ -33,7 +33,8 @@ export const User = memo(function User({
| 'large'
| 'thread'
| 'avatar'
| 'stacked';
| 'stacked'
| 'ministacked';
embedProfile?: string;
}) {
const { status, user } = useProfile(pubkey, embedProfile);
@@ -228,6 +229,28 @@ export const User = memo(function User({
);
}
if (variant === 'ministacked') {
return (
<Avatar.Root>
<Avatar.Image
src={user?.picture || user?.image}
alt={pubkey}
loading="lazy"
decoding="async"
style={{ contentVisibility: 'auto' }}
className="inline-block h-6 w-6 rounded-full ring-1 ring-white dark:ring-black"
/>
<Avatar.Fallback delayMs={300}>
<img
src={svgURI}
alt={pubkey}
className="inline-block h-6 w-6 rounded-full bg-black ring-1 ring-white dark:bg-white dark:ring-black"
/>
</Avatar.Fallback>
</Avatar.Root>
);
}
if (variant === 'repost') {
return (
<div className="flex gap-3">

View File

@@ -86,10 +86,10 @@ export function LocalNetworkWidget() {
// subscribe for new event
// sub will be managed by lru-cache
useEffect(() => {
if (db.account && db.account.network && dbEvents.length > 0) {
if (db.account && db.account.circles && dbEvents.length > 0) {
const filter: NDKFilter = {
kinds: [NDKKind.Text, NDKKind.Repost],
authors: db.account.network,
authors: db.account.circles,
since: Math.floor(Date.now() / 1000),
};
@@ -102,7 +102,7 @@ export function LocalNetworkWidget() {
return (
<WidgetWrapper>
<TitleBar title="Network" />
<TitleBar id="9999" />
<div className="flex-1">
{status === 'loading' ? (
<div className="px-3 py-1.5">

View File

@@ -57,7 +57,7 @@ export function XfeedsWidget({ params }: { params: Widget }) {
/>
</div>
<div className="flex h-[500px] w-full flex-col overflow-y-auto rounded-lg bg-neutral-200 py-2 scrollbar-none dark:bg-neutral-800">
{db.account.network.map((item: string) => (
{db.account.circles.map((item: string) => (
<button
key={item}
type="button"