continue polish, prepare launch v1.0.0
This commit is contained in:
@@ -10,8 +10,8 @@ export function User({ pubkey }: { pubkey: string }) {
|
|||||||
return (
|
return (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<div className="relative h-11 w-11 shrink-0 rounded-md bg-zinc-800 animate-pulse" />
|
<div className="relative h-11 w-11 shrink-0 rounded-md bg-zinc-800 animate-pulse" />
|
||||||
<div className="flex w-full flex-1 flex-col items-start text-start">
|
<div className="flex w-full flex-1 flex-col items-start gap-1 text-start">
|
||||||
<span className="w-full h-3 rounded bg-zinc-800 animate-pulse" />
|
<span className="w-full h-4 rounded bg-zinc-800 animate-pulse" />
|
||||||
<span className="w-1/2 h-3 rounded bg-zinc-800 animate-pulse" />
|
<span className="w-1/2 h-3 rounded bg-zinc-800 animate-pulse" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { User } from "@app/auth/components/user";
|
import { User } from "@app/auth/components/user";
|
||||||
|
import { Button } from "@shared/button";
|
||||||
import { LoaderIcon } from "@shared/icons";
|
import { LoaderIcon } from "@shared/icons";
|
||||||
import { RelayContext } from "@shared/relayProvider";
|
import { RelayContext } from "@shared/relayProvider";
|
||||||
import { useActiveAccount } from "@stores/accounts";
|
import { useActiveAccount } from "@stores/accounts";
|
||||||
@@ -47,7 +48,7 @@ export function Page() {
|
|||||||
{loading ? "Creating..." : "Continue with"}
|
{loading ? "Creating..." : "Continue with"}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full rounded-lg border border-zinc-800 bg-zinc-900 p-4">
|
<div className="w-full rounded-xl border-t border-zinc-800/50 bg-zinc-900 p-4">
|
||||||
{!account ? (
|
{!account ? (
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
@@ -61,17 +62,13 @@ export function Page() {
|
|||||||
) : (
|
) : (
|
||||||
<div className="flex flex-col gap-3">
|
<div className="flex flex-col gap-3">
|
||||||
<User pubkey={account.pubkey} />
|
<User pubkey={account.pubkey} />
|
||||||
<button
|
<Button preset="large" onClick={() => submit()}>
|
||||||
type="button"
|
|
||||||
onClick={() => submit()}
|
|
||||||
className="inline-flex items-center justify-center h-11 w-full bg-fuchsia-500 rounded-md font-medium text-zinc-100 hover:bg-fuchsia-600"
|
|
||||||
>
|
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<LoaderIcon className="h-4 w-4 animate-spin text-black dark:text-zinc-100" />
|
<LoaderIcon className="h-4 w-4 animate-spin text-black dark:text-zinc-100" />
|
||||||
) : (
|
) : (
|
||||||
"Continue →"
|
"Continue →"
|
||||||
)}
|
)}
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { NDKEvent, NDKPrivateKeySigner } from "@nostr-dev-kit/ndk";
|
import { NDKEvent, NDKPrivateKeySigner } from "@nostr-dev-kit/ndk";
|
||||||
import { ArrowRightCircleIcon } from "@shared/icons/arrowRightCircle";
|
import { ArrowRightCircleIcon } from "@shared/icons/arrowRightCircle";
|
||||||
|
import { Link } from "@shared/link";
|
||||||
import { RelayContext } from "@shared/relayProvider";
|
import { RelayContext } from "@shared/relayProvider";
|
||||||
import { User } from "@shared/user";
|
import { User } from "@shared/user";
|
||||||
import { useActiveAccount } from "@stores/accounts";
|
import { useActiveAccount } from "@stores/accounts";
|
||||||
@@ -95,12 +96,12 @@ export function Page() {
|
|||||||
<span>Publish</span>
|
<span>Publish</span>
|
||||||
<ArrowRightCircleIcon className="w-5 h-5" />
|
<ArrowRightCircleIcon className="w-5 h-5" />
|
||||||
</button>
|
</button>
|
||||||
<a
|
<Link
|
||||||
href="/"
|
href="/"
|
||||||
className="inline-flex h-10 w-full items-center justify-center gap-2 rounded-lg px-6 text-sm font-medium text-zinc-200"
|
className="inline-flex h-10 w-full items-center justify-center gap-2 rounded-lg px-6 text-sm font-medium text-zinc-200"
|
||||||
>
|
>
|
||||||
Skip for now
|
Skip for now
|
||||||
</a>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Image } from "@shared/image";
|
import { Image } from "@shared/image";
|
||||||
|
import { NetworkStatusIndicator } from "@shared/networkStatusIndicator";
|
||||||
import { RelayContext } from "@shared/relayProvider";
|
import { RelayContext } from "@shared/relayProvider";
|
||||||
import { useActiveAccount } from "@stores/accounts";
|
import { useActiveAccount } from "@stores/accounts";
|
||||||
import { useChannels } from "@stores/channels";
|
import { useChannels } from "@stores/channels";
|
||||||
@@ -64,12 +65,13 @@ export function ActiveAccount({ data }: { data: any }) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button type="button" className="relative h-11 w-11 overflow-hidden">
|
<button type="button" className="relative inline-block h-9 w-9">
|
||||||
<Image
|
<Image
|
||||||
src={user?.image || DEFAULT_AVATAR}
|
src={user?.image || DEFAULT_AVATAR}
|
||||||
alt={data.npub}
|
alt={data.npub}
|
||||||
className="h-11 w-11 rounded-md object-cover"
|
className="h-9 w-9 rounded object-cover"
|
||||||
/>
|
/>
|
||||||
|
<NetworkStatusIndicator />
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Image } from "@shared/image";
|
import { Image } from "@shared/image";
|
||||||
|
|
||||||
import { DEFAULT_AVATAR } from "@stores/constants";
|
import { DEFAULT_AVATAR } from "@stores/constants";
|
||||||
import { useProfile } from "@utils/hooks/useProfile";
|
import { useProfile } from "@utils/hooks/useProfile";
|
||||||
|
|
||||||
@@ -7,11 +6,11 @@ export function InactiveAccount({ data }: { data: any }) {
|
|||||||
const { user } = useProfile(data.npub);
|
const { user } = useProfile(data.npub);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative h-11 w-11 shrink rounded-md">
|
<div className="relative h-9 w-9 shrink-0">
|
||||||
<Image
|
<Image
|
||||||
src={user?.image || DEFAULT_AVATAR}
|
src={user?.image || DEFAULT_AVATAR}
|
||||||
alt={data.npub}
|
alt={data.npub}
|
||||||
className="h-11 w-11 rounded-lg object-cover"
|
className="h-9 w-9 rounded object-cover"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,17 +1,6 @@
|
|||||||
import { ArrowLeftIcon, ArrowRightIcon } from "@shared/icons";
|
import { ArrowLeftIcon, ArrowRightIcon } from "@shared/icons";
|
||||||
import useSWR from "swr";
|
|
||||||
|
|
||||||
const fetcher = async () => {
|
|
||||||
const { platform } = await import("@tauri-apps/api/os");
|
|
||||||
return platform();
|
|
||||||
};
|
|
||||||
|
|
||||||
export function AppHeader() {
|
|
||||||
const { data: platform } = useSWR(
|
|
||||||
typeof window !== "undefined" ? "platform" : null,
|
|
||||||
fetcher,
|
|
||||||
);
|
|
||||||
|
|
||||||
|
export function AppHeader({ reverse }: { reverse?: boolean }) {
|
||||||
const goBack = () => {
|
const goBack = () => {
|
||||||
window.history.back();
|
window.history.back();
|
||||||
};
|
};
|
||||||
@@ -23,8 +12,8 @@ export function AppHeader() {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
data-tauri-drag-region
|
data-tauri-drag-region
|
||||||
className={`flex h-11 w-full px-3 border-b border-zinc-900 items-center ${
|
className={`shrink-0 flex h-11 w-full px-3 border-b border-zinc-900 items-center ${
|
||||||
platform === "darwin" ? "justify-end" : "justify-start"
|
reverse ? "justify-start" : "justify-end"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="flex gap-2.5">
|
<div className="flex gap-2.5">
|
||||||
|
|||||||
@@ -1,14 +1,8 @@
|
|||||||
import { DEFAULT_AVATAR } from "@stores/constants";
|
import { DEFAULT_AVATAR } from "@stores/constants";
|
||||||
import { ClassAttributes, ImgHTMLAttributes, JSX } from "react";
|
|
||||||
|
|
||||||
export function Image(
|
export function Image(props, fallback?) {
|
||||||
props: JSX.IntrinsicAttributes &
|
|
||||||
ClassAttributes<HTMLImageElement> &
|
|
||||||
ImgHTMLAttributes<HTMLImageElement>,
|
|
||||||
fallback = undefined,
|
|
||||||
) {
|
|
||||||
const addImageFallback = (event: { currentTarget: { src: string } }) => {
|
const addImageFallback = (event: { currentTarget: { src: string } }) => {
|
||||||
event.currentTarget.src = fallback ? fallback : DEFAULT_AVATAR;
|
event.currentTarget.src = fallback || DEFAULT_AVATAR;
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export function DefaultLayout({ children }: { children: React.ReactNode }) {
|
|||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="relative flex flex-row shrink-0">
|
<div className="relative flex flex-row shrink-0">
|
||||||
<Navigation />
|
<Navigation reverse={platform !== "darwin"} />
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full h-full">{children}</div>
|
<div className="w-full h-full">{children}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { getAccounts, getActiveAccount } from "@libs/storage";
|
|||||||
import { ActiveAccount } from "@shared/accounts/active";
|
import { ActiveAccount } from "@shared/accounts/active";
|
||||||
import { InactiveAccount } from "@shared/accounts/inactive";
|
import { InactiveAccount } from "@shared/accounts/inactive";
|
||||||
import { BellIcon, PlusIcon } from "@shared/icons";
|
import { BellIcon, PlusIcon } from "@shared/icons";
|
||||||
import { APP_VERSION } from "@stores/constants";
|
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
|
|
||||||
const allFetcher = () => getAccounts();
|
const allFetcher = () => getAccounts();
|
||||||
@@ -13,45 +12,22 @@ export function MultiAccounts() {
|
|||||||
const { data: activeAccount }: any = useSWR("activeAccount", fetcher);
|
const { data: activeAccount }: any = useSWR("activeAccount", fetcher);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex shrink-0 w-[68px] h-full flex-col items-center justify-between border-r border-zinc-900 pb-4 pt-11">
|
<div className="flex items-center gap-2 rounded-xl p-2 border-t border-zinc-800/50 bg-zinc-900/80 backdrop-blur-md">
|
||||||
<div className="flex flex-col items-center">
|
|
||||||
<div className="flex flex-col gap-2">
|
|
||||||
<>
|
|
||||||
{!activeAccount ? (
|
{!activeAccount ? (
|
||||||
<div className="group relative flex h-10 w-10 shrink animate-pulse items-center justify-center rounded-lg bg-zinc-900" />
|
<div className="group relative flex h-9 w-9 shrink animate-pulse items-center justify-center rounded-lg bg-zinc-900" />
|
||||||
) : (
|
) : (
|
||||||
<ActiveAccount data={activeAccount} />
|
<ActiveAccount data={activeAccount} />
|
||||||
)}
|
)}
|
||||||
</>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="group relative flex h-11 w-11 shrink items-center justify-center rounded-md bg-zinc-900 hover:bg-zinc-800"
|
|
||||||
>
|
|
||||||
<BellIcon
|
|
||||||
width={16}
|
|
||||||
height={16}
|
|
||||||
className="text-zinc-400 group-hover:text-zinc-100"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="my-2 h-px w-2/3 bg-zinc-800" />
|
|
||||||
<div className="flex flex-col gap-3">
|
|
||||||
<>
|
|
||||||
{!accounts ? (
|
{!accounts ? (
|
||||||
<div className="group relative flex h-10 w-10 shrink animate-pulse items-center justify-center rounded-lg bg-zinc-900" />
|
<div className="group relative flex h-9 w-9 shrink animate-pulse items-center justify-center rounded-lg bg-zinc-900" />
|
||||||
) : (
|
) : (
|
||||||
accounts.map(
|
accounts.map((account: { is_active: number; pubkey: string }) => (
|
||||||
(account: { is_active: number; pubkey: string }) => (
|
|
||||||
<InactiveAccount key={account.pubkey} data={account} />
|
<InactiveAccount key={account.pubkey} data={account} />
|
||||||
),
|
))
|
||||||
)
|
|
||||||
)}
|
)}
|
||||||
</>
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="group relative flex h-10 w-10 shrink items-center justify-center rounded-md border border-dashed border-transparent hover:border-zinc-600"
|
className="group relative flex h-9 w-9 shrink items-center justify-center rounded border border-dashed border-zinc-600 hover:border-zinc-400"
|
||||||
>
|
>
|
||||||
<PlusIcon
|
<PlusIcon
|
||||||
width={16}
|
width={16}
|
||||||
@@ -60,15 +36,5 @@ export function MultiAccounts() {
|
|||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div className="flex flex-col gap-0.5 text-center">
|
|
||||||
<span className="text-base font-black uppercase leading-tight text-zinc-600">
|
|
||||||
Lume
|
|
||||||
</span>
|
|
||||||
<span className="text-base font-medium text-zinc-700">
|
|
||||||
v{APP_VERSION}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,15 +5,17 @@ import { ActiveLink } from "@shared/activeLink";
|
|||||||
import { AppHeader } from "@shared/appHeader";
|
import { AppHeader } from "@shared/appHeader";
|
||||||
import { Composer } from "@shared/composer/modal";
|
import { Composer } from "@shared/composer/modal";
|
||||||
import { NavArrowDownIcon, SpaceIcon, TrendingIcon } from "@shared/icons";
|
import { NavArrowDownIcon, SpaceIcon, TrendingIcon } from "@shared/icons";
|
||||||
import { useComposer } from "@stores/composer";
|
import { MultiAccounts } from "@shared/multiAccounts";
|
||||||
|
|
||||||
export function Navigation() {
|
|
||||||
const toggle = useComposer((state: any) => state.toggleModal);
|
|
||||||
|
|
||||||
|
export function Navigation({ reverse }: { reverse?: boolean }) {
|
||||||
return (
|
return (
|
||||||
<div className="flex w-[232px] flex-col gap-3 border-r border-zinc-900">
|
<div
|
||||||
<AppHeader />
|
className={`relative flex w-[232px] flex-col gap-3 ${
|
||||||
<div className="flex flex-col gap-5 overflow-y-auto scrollbar-hide">
|
reverse ? "border-l" : "border-r"
|
||||||
|
} border-zinc-900`}
|
||||||
|
>
|
||||||
|
<AppHeader reverse={reverse} />
|
||||||
|
<div className="pb-20 flex flex-col gap-5 overflow-y-auto scrollbar-hide">
|
||||||
<div className="inlin-lflex h-8 px-3.5">
|
<div className="inlin-lflex h-8 px-3.5">
|
||||||
<Composer />
|
<Composer />
|
||||||
</div>
|
</div>
|
||||||
@@ -104,6 +106,9 @@ export function Navigation() {
|
|||||||
)}
|
)}
|
||||||
</Disclosure>
|
</Disclosure>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="absolute bottom-2 left-0 px-8 w-full">
|
||||||
|
<MultiAccounts />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,22 +4,10 @@ export function NetworkStatusIndicator() {
|
|||||||
const isOnline = useNetworkStatus();
|
const isOnline = useNetworkStatus();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="inline-flex items-center gap-1 rounded-md px-1.5 py-1 hover:bg-zinc-900">
|
|
||||||
<div className="relative flex h-1.5 w-1.5">
|
|
||||||
<span
|
<span
|
||||||
className={`absolute inline-flex h-full w-full animate-ping rounded-full opacity-75 ${
|
className={`absolute right-0 top-0 block h-2 w-2 -translate-y-1/2 translate-x-1/2 transform rounded-full ${
|
||||||
isOnline ? "bg-green-400" : "bg-red-400"
|
isOnline ? "bg-green-400" : "bg-red-400"
|
||||||
}`}
|
} ring-2 ring-zinc-900`}
|
||||||
/>
|
/>
|
||||||
<span
|
|
||||||
className={`relative inline-flex h-1.5 w-1.5 rounded-full ${
|
|
||||||
isOnline ? "bg-green-400" : "bg-amber-400"
|
|
||||||
}`}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<p className="text-base font-medium text-zinc-500">
|
|
||||||
{isOnline ? "Online" : "Offline"}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export function MentionUser({ pubkey }: { pubkey: string }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
href={`/user?pubkey=${pubkey}`}
|
href={`/app/user?pubkey=${pubkey}`}
|
||||||
className="text-fuchsia-500 hover:text-fuchsia-600 no-underline font-normal"
|
className="text-fuchsia-500 hover:text-fuchsia-600 no-underline font-normal"
|
||||||
>
|
>
|
||||||
@{user?.name || user?.displayName || shortenKey(pubkey)}
|
@{user?.name || user?.displayName || shortenKey(pubkey)}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export function LinkPreview({ urls }: { urls: string[] }) {
|
|||||||
src={data["og:image"]}
|
src={data["og:image"]}
|
||||||
alt={urls[0]}
|
alt={urls[0]}
|
||||||
className="w-full h-44 object-cover rounded-t-lg bg-white"
|
className="w-full h-44 object-cover rounded-t-lg bg-white"
|
||||||
|
fallback="https://void.cat/d/XTmrMkpid8DGLjv1AzdvcW"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<div className="flex flex-col gap-2 px-3 py-3">
|
<div className="flex flex-col gap-2 px-3 py-3">
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ export function User({
|
|||||||
src={user?.image || DEFAULT_AVATAR}
|
src={user?.image || DEFAULT_AVATAR}
|
||||||
alt={pubkey}
|
alt={pubkey}
|
||||||
className="h-11 w-11 shrink-0 rounded-lg object-cover"
|
className="h-11 w-11 shrink-0 rounded-lg object-cover"
|
||||||
|
fallback={DEFAULT_AVATAR}
|
||||||
/>
|
/>
|
||||||
<div className="flex-1 flex flex-col gap-2">
|
<div className="flex-1 flex flex-col gap-2">
|
||||||
<div className="inline-flex flex-col gap-1">
|
<div className="inline-flex flex-col gap-1">
|
||||||
|
|||||||
Reference in New Issue
Block a user