feat: add option to toggle window transparent
This commit is contained in:
@@ -17,7 +17,7 @@ export const Conversation = memo(function Conversation({
|
|||||||
<Note.Provider event={event}>
|
<Note.Provider event={event}>
|
||||||
<Note.Root
|
<Note.Root
|
||||||
className={cn(
|
className={cn(
|
||||||
"bg-white dark:bg-black/20 backdrop-blur-lg rounded-xl flex flex-col gap-3 shadow-primary dark:ring-1 ring-neutral-800/50",
|
"bg-white dark:bg-black/20 rounded-xl flex flex-col gap-3 shadow-primary dark:ring-1 ring-neutral-800/50",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ export function NoteContent({
|
|||||||
return (
|
return (
|
||||||
<div className="relative flex flex-col gap-2">
|
<div className="relative flex flex-col gap-2">
|
||||||
{blurred ? (
|
{blurred ? (
|
||||||
<div className="absolute inset-0 z-10 flex items-center justify-center w-full h-full bg-black/80 backdrop-blur-xl">
|
<div className="absolute inset-0 z-10 flex items-center justify-center w-full h-full bg-black/80 backdrop-blur-lg">
|
||||||
<div className="flex flex-col items-center justify-center gap-2 text-center">
|
<div className="flex flex-col items-center justify-center gap-2 text-center">
|
||||||
<p className="text-sm text-white/60">
|
<p className="text-sm text-white/60">
|
||||||
The content is hidden because the author
|
The content is hidden because the author
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { Carousel, CarouselItem } from "@lume/ui";
|
|
||||||
|
|
||||||
export function Videos({ urls }: { urls: string[] }) {
|
export function Videos({ urls }: { urls: string[] }) {
|
||||||
if (urls.length === 1) {
|
|
||||||
return (
|
return (
|
||||||
<div className="group px-3">
|
<div className="group px-3">
|
||||||
|
{urls.map((url) => (
|
||||||
<video
|
<video
|
||||||
|
key={url}
|
||||||
className="max-h-[400px] w-auto object-cover rounded-lg outline outline-1 -outline-offset-1 outline-black/15"
|
className="max-h-[400px] w-auto object-cover rounded-lg outline outline-1 -outline-offset-1 outline-black/15"
|
||||||
preload="metadata"
|
preload="metadata"
|
||||||
controls
|
controls
|
||||||
@@ -13,26 +12,7 @@ export function Videos({ urls }: { urls: string[] }) {
|
|||||||
<source src={`${urls[0]}#t=0.1`} type="video/mp4" />
|
<source src={`${urls[0]}#t=0.1`} type="video/mp4" />
|
||||||
Your browser does not support the video tag.
|
Your browser does not support the video tag.
|
||||||
</video>
|
</video>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Carousel
|
|
||||||
items={urls}
|
|
||||||
renderItem={({ item, isSnapPoint }) => (
|
|
||||||
<CarouselItem key={item} isSnapPoint={isSnapPoint}>
|
|
||||||
<video
|
|
||||||
className="w-full h-full object-cover rounded-lg outline outline-1 -outline-offset-1 outline-black/15"
|
|
||||||
preload="metadata"
|
|
||||||
controls={false}
|
|
||||||
muted
|
|
||||||
>
|
|
||||||
<source src={`${item}#t=0.1`} type="video/mp4" />
|
|
||||||
Your browser does not support the video tag.
|
|
||||||
</video>
|
|
||||||
</CarouselItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export const Quote = memo(function Quote({
|
|||||||
<Note.Provider event={event}>
|
<Note.Provider event={event}>
|
||||||
<Note.Root
|
<Note.Root
|
||||||
className={cn(
|
className={cn(
|
||||||
"bg-white dark:bg-black/20 backdrop-blur-lg rounded-xl flex flex-col gap-3 shadow-primary dark:ring-1 ring-neutral-800/50",
|
"bg-white dark:bg-black/20 rounded-xl flex flex-col gap-3 shadow-primary dark:ring-1 ring-neutral-800/50",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export const RepostNote = memo(function RepostNote({
|
|||||||
return (
|
return (
|
||||||
<Note.Root
|
<Note.Root
|
||||||
className={cn(
|
className={cn(
|
||||||
"bg-white dark:bg-black/20 backdrop-blur-lg rounded-xl shadow-primary dark:ring-1 ring-neutral-800/50",
|
"bg-white dark:bg-black/20 rounded-xl shadow-primary dark:ring-1 ring-neutral-800/50",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export const TextNote = memo(function TextNote({
|
|||||||
<Note.Provider event={event}>
|
<Note.Provider event={event}>
|
||||||
<Note.Root
|
<Note.Root
|
||||||
className={cn(
|
className={cn(
|
||||||
"bg-white dark:bg-black/20 backdrop-blur rounded-xl shadow-primary dark:ring-1 dark:ring-white/5",
|
"bg-white dark:bg-black/20 rounded-xl shadow-primary dark:ring-1 dark:ring-white/5",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
PlusIcon,
|
PlusIcon,
|
||||||
SearchIcon,
|
SearchIcon,
|
||||||
} from "@lume/icons";
|
} from "@lume/icons";
|
||||||
import { LumeWindow, NostrAccount } from "@lume/system";
|
import { LumeWindow, NostrAccount, NostrQuery } from "@lume/system";
|
||||||
import { cn } from "@lume/utils";
|
import { cn } from "@lume/utils";
|
||||||
import { Outlet, createFileRoute } from "@tanstack/react-router";
|
import { Outlet, createFileRoute } from "@tanstack/react-router";
|
||||||
import { Menu, MenuItem, PredefinedMenuItem } from "@tauri-apps/api/menu";
|
import { Menu, MenuItem, PredefinedMenuItem } from "@tauri-apps/api/menu";
|
||||||
@@ -15,18 +15,19 @@ import { memo, useCallback, useState } from "react";
|
|||||||
|
|
||||||
export const Route = createFileRoute("/$account")({
|
export const Route = createFileRoute("/$account")({
|
||||||
beforeLoad: async ({ params }) => {
|
beforeLoad: async ({ params }) => {
|
||||||
|
const settings = await NostrQuery.getUserSettings();
|
||||||
const accounts = await NostrAccount.getAccounts();
|
const accounts = await NostrAccount.getAccounts();
|
||||||
const otherAccounts = accounts.filter(
|
const otherAccounts = accounts.filter(
|
||||||
(account) => account !== params.account,
|
(account) => account !== params.account,
|
||||||
);
|
);
|
||||||
|
|
||||||
return { otherAccounts };
|
return { otherAccounts, settings };
|
||||||
},
|
},
|
||||||
component: Screen,
|
component: Screen,
|
||||||
});
|
});
|
||||||
|
|
||||||
function Screen() {
|
function Screen() {
|
||||||
const { platform } = Route.useRouteContext();
|
const { settings, platform } = Route.useRouteContext();
|
||||||
|
|
||||||
const openLumeStore = async () => {
|
const openLumeStore = async () => {
|
||||||
await getCurrent().emit("columns", {
|
await getCurrent().emit("columns", {
|
||||||
@@ -80,7 +81,14 @@ function Screen() {
|
|||||||
<Accounts />
|
<Accounts />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1">
|
<div
|
||||||
|
className={cn(
|
||||||
|
"flex-1",
|
||||||
|
settings.vibrancy
|
||||||
|
? ""
|
||||||
|
: "bg-white dark:bg-black border-t border-black/20 dark:border-white/20",
|
||||||
|
)}
|
||||||
|
>
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -28,6 +28,13 @@ function Screen() {
|
|||||||
|
|
||||||
const onSubmit = async (data: { url: string; purpose: string }) => {
|
const onSubmit = async (data: { url: string; purpose: string }) => {
|
||||||
try {
|
try {
|
||||||
|
if (!data.url.startsWith("wss://") || !data.url.startsWith("ws://")) {
|
||||||
|
return await message("Relay must be starts with wss:// or ws://", {
|
||||||
|
title: "Bootstrap Relays",
|
||||||
|
kind: "info",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const relay: Relay = { url: data.url, purpose: data.purpose };
|
const relay: Relay = { url: data.url, purpose: data.purpose };
|
||||||
setRelays((prev) => [...prev, relay]);
|
setRelays((prev) => [...prev, relay]);
|
||||||
reset();
|
reset();
|
||||||
@@ -50,12 +57,21 @@ function Screen() {
|
|||||||
}, [bootstrapRelays]);
|
}, [bootstrapRelays]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center justify-center w-screen h-screen">
|
<div
|
||||||
<div className="w-full max-w-sm mx-auto lg:max-w-lg">
|
data-tauri-drag-region
|
||||||
<div className="text-center h-11">
|
className="relative flex flex-col items-center justify-between w-full h-full"
|
||||||
<h1 className="font-semibold">Customize Bootstrap Relays</h1>
|
>
|
||||||
|
<div
|
||||||
|
data-tauri-drag-region
|
||||||
|
className="absolute top-0 left-0 h-14 w-full"
|
||||||
|
/>
|
||||||
|
<div className="flex items-end justify-center flex-1 w-full px-4 pb-10">
|
||||||
|
<div className="text-center">
|
||||||
|
<h2 className="text-2xl font-semibold">Customize Bootstrap Relays</h2>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col w-full px-2 bg-white rounded-xl shadow-primary backdrop-blur-lg dark:bg-white/20 dark:ring-1 ring-neutral-800/50">
|
</div>
|
||||||
|
<div className="flex flex-col items-center flex-1 w-full">
|
||||||
|
<div className="flex flex-col w-full max-w-sm mx-auto p-3 overflow-hidden bg-white divide-y divide-neutral-100 dark:divide-white/5 rounded-xl shadow-primary dark:bg-white/10 dark:ring-1 ring-white/15">
|
||||||
{relays.map((relay) => (
|
{relays.map((relay) => (
|
||||||
<div
|
<div
|
||||||
key={relay.url}
|
key={relay.url}
|
||||||
@@ -117,15 +133,18 @@ function Screen() {
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="w-full max-w-sm mx-auto">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => save()}
|
onClick={() => save()}
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
className="inline-flex items-center justify-center w-full h-10 mt-4 text-sm font-semibold text-white bg-blue-500 rounded-lg shrink-0 hover:bg-blue-600 disabled:opacity-50"
|
className="inline-flex items-center justify-center w-full h-9 mt-4 text-sm font-semibold text-white bg-blue-500 rounded-lg shrink-0 hover:bg-blue-600 disabled:opacity-50"
|
||||||
>
|
>
|
||||||
{isLoading ? <Spinner /> : "Save & Relaunch"}
|
{isLoading ? <Spinner /> : "Save & Relaunch"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex-1" />
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ function Screen() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col items-center w-full gap-3">
|
<div className="flex flex-col items-center w-full gap-3">
|
||||||
<div className="overflow-y-auto scrollbar-none p-2 w-full h-[450px] flex flex-col gap-3 bg-black/5 dark:bg-white/5 backdrop-blur-lg rounded-xl">
|
<div className="overflow-y-auto scrollbar-none p-2 w-full h-[450px] flex flex-col gap-3 bg-black/5 dark:bg-white/5 rounded-xl">
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<input
|
<input
|
||||||
name="npub"
|
name="npub"
|
||||||
@@ -122,7 +122,7 @@ function Screen() {
|
|||||||
key={item}
|
key={item}
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => toggleUser(item)}
|
onClick={() => toggleUser(item)}
|
||||||
className="inline-flex items-center justify-between px-3 py-2 bg-white rounded-lg dark:bg-black/20 backdrop-blur-lg shadow-primary dark:ring-1 ring-neutral-800/50"
|
className="inline-flex items-center justify-between px-3 py-2 bg-white rounded-lg dark:bg-black/20 shadow-primary dark:ring-1 ring-neutral-800/50"
|
||||||
>
|
>
|
||||||
<User.Provider pubkey={item}>
|
<User.Provider pubkey={item}>
|
||||||
<User.Root className="flex items-center gap-2.5">
|
<User.Root className="flex items-center gap-2.5">
|
||||||
@@ -153,7 +153,7 @@ function Screen() {
|
|||||||
key={item}
|
key={item}
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => toggleUser(item)}
|
onClick={() => toggleUser(item)}
|
||||||
className="inline-flex items-center justify-between px-3 py-2 bg-white rounded-lg dark:bg-black/20 backdrop-blur-lg shadow-primary dark:ring-1 ring-neutral-800/50"
|
className="inline-flex items-center justify-between px-3 py-2 bg-white rounded-lg dark:bg-black/20 shadow-primary dark:ring-1 ring-neutral-800/50"
|
||||||
>
|
>
|
||||||
<User.Provider pubkey={item}>
|
<User.Provider pubkey={item}>
|
||||||
<User.Root className="flex items-center gap-2.5">
|
<User.Root className="flex items-center gap-2.5">
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ function Screen() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="overflow-y-auto scrollbar-none p-2 shrink-0 h-[450px] bg-white dark:bg-white/20 backdrop-blur-lg rounded-xl shadow-primary dark:ring-1 ring-neutral-800/50">
|
<div className="overflow-y-auto scrollbar-none p-2 shrink-0 h-[450px] bg-white dark:bg-white/20 rounded-xl shadow-primary dark:ring-1 ring-neutral-800/50">
|
||||||
<div className="flex flex-col justify-between h-full">
|
<div className="flex flex-col justify-between h-full">
|
||||||
<div className="flex-1 flex flex-col gap-1.5 justify-center px-5">
|
<div className="flex-1 flex flex-col gap-1.5 justify-center px-5">
|
||||||
<p className="font-semibold text-neutral-500">
|
<p className="font-semibold text-neutral-500">
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ function Screen() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center w-full gap-3">
|
<div className="flex flex-col items-center w-full gap-3">
|
||||||
<div className="overflow-y-auto scrollbar-none p-2 w-full h-[450px] bg-black/5 dark:bg-white/5 backdrop-blur-lg rounded-xl">
|
<div className="overflow-y-auto scrollbar-none p-2 w-full h-[450px] bg-black/5 dark:bg-white/5 rounded-xl">
|
||||||
<Suspense
|
<Suspense
|
||||||
fallback={
|
fallback={
|
||||||
<div className="flex flex-col items-center justify-center w-full h-20 gap-1">
|
<div className="flex flex-col items-center justify-center w-full h-20 gap-1">
|
||||||
@@ -88,7 +88,7 @@ function Screen() {
|
|||||||
users.profiles.map((item: { pubkey: string }) => (
|
users.profiles.map((item: { pubkey: string }) => (
|
||||||
<div
|
<div
|
||||||
key={item.pubkey}
|
key={item.pubkey}
|
||||||
className="w-full p-2 mb-2 overflow-hidden bg-white rounded-lg h-max dark:bg-black/20 backdrop-blur-lg shadow-primary dark:ring-1 ring-neutral-800/50"
|
className="w-full p-2 mb-2 overflow-hidden bg-white rounded-lg h-max dark:bg-black/20shadow-primary dark:ring-1 ring-neutral-800/50"
|
||||||
>
|
>
|
||||||
<User.Provider pubkey={item.pubkey}>
|
<User.Provider pubkey={item.pubkey}>
|
||||||
<User.Root>
|
<User.Root>
|
||||||
|
|||||||
@@ -75,14 +75,14 @@ function Screen() {
|
|||||||
<span className="text-sm font-medium">Added: {topics.length}</span>
|
<span className="text-sm font-medium">Added: {topics.length}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col items-center w-full gap-3">
|
<div className="flex flex-col items-center w-full gap-3">
|
||||||
<div className="overflow-y-auto scrollbar-none p-2 w-full h-[450px] bg-black/5 dark:bg-white/5 backdrop-blur-lg rounded-xl">
|
<div className="overflow-y-auto scrollbar-none p-2 w-full h-[450px] bg-black/5 dark:bg-white/5 rounded-xl">
|
||||||
<div className="flex flex-col gap-3">
|
<div className="flex flex-col gap-3">
|
||||||
{TOPICS.map((topic) => (
|
{TOPICS.map((topic) => (
|
||||||
<button
|
<button
|
||||||
key={topic.title}
|
key={topic.title}
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => toggleTopic(topic)}
|
onClick={() => toggleTopic(topic)}
|
||||||
className="flex items-center justify-between px-3 bg-white border border-transparent rounded-lg h-11 dark:bg-black/20 backdrop-blur-lg hover:border-blue-500 shadow-primary dark:ring-1 ring-neutral-800/50"
|
className="flex items-center justify-between px-3 bg-white border border-transparent rounded-lg h-11 dark:bg-black/20 hover:border-blue-500 shadow-primary dark:ring-1 ring-neutral-800/50"
|
||||||
>
|
>
|
||||||
<div className="inline-flex items-center gap-1">
|
<div className="inline-flex items-center gap-1">
|
||||||
<div>{topic.icon}</div>
|
<div>{topic.icon}</div>
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { Note } from "@/components/note";
|
import { Note } from "@/components/note";
|
||||||
import { LumeEvent, NostrQuery } from "@lume/system";
|
import { LumeEvent, NostrQuery } from "@lume/system";
|
||||||
|
import type { Meta } from "@lume/types";
|
||||||
|
import * as ScrollArea from "@radix-ui/react-scroll-area";
|
||||||
import { createFileRoute } from "@tanstack/react-router";
|
import { createFileRoute } from "@tanstack/react-router";
|
||||||
|
import { getCurrent } from "@tauri-apps/api/window";
|
||||||
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { Virtualizer } from "virtua";
|
import { Virtualizer } from "virtua";
|
||||||
import NoteParent from "./-components/parent";
|
import NoteParent from "./-components/parent";
|
||||||
import * as ScrollArea from "@radix-ui/react-scroll-area";
|
|
||||||
import { useEffect, useRef, useState } from "react";
|
|
||||||
import { getCurrent } from "@tauri-apps/api/window";
|
|
||||||
import type { Meta } from "@lume/types";
|
|
||||||
|
|
||||||
type Payload = {
|
type Payload = {
|
||||||
raw: string;
|
raw: string;
|
||||||
@@ -62,7 +62,7 @@ function RootEvent() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Note.Provider event={event}>
|
<Note.Provider event={event}>
|
||||||
<Note.Root className="bg-white dark:bg-black/10 backdrop-blur rounded-xl shadow-primary dark:ring-1 dark:ring-white/5">
|
<Note.Root className="bg-white dark:bg-black/10 rounded-xl shadow-primary dark:ring-1 dark:ring-white/5">
|
||||||
<div className="flex items-center justify-between px-3 h-14">
|
<div className="flex items-center justify-between px-3 h-14">
|
||||||
<Note.User />
|
<Note.User />
|
||||||
<Note.Menu />
|
<Note.Menu />
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ export function Screen() {
|
|||||||
<ScrollArea.Viewport ref={ref} className="h-full px-3 pb-3">
|
<ScrollArea.Viewport ref={ref} className="h-full px-3 pb-3">
|
||||||
<Virtualizer scrollRef={ref}>
|
<Virtualizer scrollRef={ref}>
|
||||||
{isFetching && !isLoading && !isFetchingNextPage ? (
|
{isFetching && !isLoading && !isFetchingNextPage ? (
|
||||||
<div className="flex items-center justify-center w-full mb-3 h-11 bg-black/10 dark:bg-white/10 backdrop-blur-lg rounded-xl shadow-primary dark:ring-1 ring-neutral-800/50">
|
<div className="flex items-center justify-center w-full mb-3 h-11 bg-black/10 dark:bg-white/10 rounded-xl shadow-primary dark:ring-1 ring-neutral-800/50">
|
||||||
<div className="flex items-center justify-center gap-2">
|
<div className="flex items-center justify-center gap-2">
|
||||||
<Spinner className="size-5" />
|
<Spinner className="size-5" />
|
||||||
<span className="text-sm font-medium">
|
<span className="text-sm font-medium">
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ export function Screen() {
|
|||||||
<ScrollArea.Viewport ref={ref} className="h-full px-3 pb-3">
|
<ScrollArea.Viewport ref={ref} className="h-full px-3 pb-3">
|
||||||
<Virtualizer scrollRef={ref}>
|
<Virtualizer scrollRef={ref}>
|
||||||
{isFetching && !isLoading && !isFetchingNextPage ? (
|
{isFetching && !isLoading && !isFetchingNextPage ? (
|
||||||
<div className="flex items-center justify-center w-full mb-3 h-11 bg-black/10 dark:bg-white/10 backdrop-blur-lg rounded-xl shadow-primary dark:ring-1 ring-neutral-800/50">
|
<div className="flex items-center justify-center w-full mb-3 h-11 bg-black/10 dark:bg-white/10 rounded-xl shadow-primary dark:ring-1 ring-neutral-800/50">
|
||||||
<div className="flex items-center justify-center gap-2">
|
<div className="flex items-center justify-center gap-2">
|
||||||
<Spinner className="size-5" />
|
<Spinner className="size-5" />
|
||||||
<span className="text-sm font-medium">
|
<span className="text-sm font-medium">
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ function Screen() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col items-center flex-1 w-full gap-3">
|
<div className="flex flex-col items-center flex-1 w-full gap-3">
|
||||||
<div className="flex flex-col w-full max-w-sm mx-auto overflow-hidden bg-white divide-y divide-neutral-100 dark:divide-white/5 rounded-xl shadow-primary backdrop-blur-lg dark:bg-white/10 dark:ring-1 ring-white/15">
|
<div className="flex flex-col w-full max-w-sm mx-auto overflow-hidden bg-white divide-y divide-neutral-100 dark:divide-white/5 rounded-xl shadow-primary dark:bg-white/10 dark:ring-1 ring-white/15">
|
||||||
{context.accounts.map((account) => (
|
{context.accounts.map((account) => (
|
||||||
<div
|
<div
|
||||||
key={account}
|
key={account}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ function Screen() {
|
|||||||
className="flex flex-col items-center justify-center w-screen h-screen"
|
className="flex flex-col items-center justify-center w-screen h-screen"
|
||||||
>
|
>
|
||||||
<div className="w-full max-w-xs mx-auto lg:max-w-md">
|
<div className="w-full max-w-xs mx-auto lg:max-w-md">
|
||||||
<div className="flex flex-col w-full gap-2 px-2 bg-white rounded-xl shadow-primary backdrop-blur-lg dark:bg-white/20 dark:ring-1 ring-neutral-800/50">
|
<div className="flex flex-col w-full gap-2 px-2 bg-white rounded-xl shadow-primary dark:bg-white/20 dark:ring-1 ring-neutral-800/50">
|
||||||
<div className="flex items-center h-20 border-b border-neutral-100 dark:border-white/5">
|
<div className="flex items-center h-20 border-b border-neutral-100 dark:border-white/5">
|
||||||
<Link
|
<Link
|
||||||
to="/auth/create-profile"
|
to="/auth/create-profile"
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ export function Screen() {
|
|||||||
<Listerner />
|
<Listerner />
|
||||||
<Virtualizer scrollRef={ref}>
|
<Virtualizer scrollRef={ref}>
|
||||||
{isFetching && !isLoading && !isFetchingNextPage ? (
|
{isFetching && !isLoading && !isFetchingNextPage ? (
|
||||||
<div className="flex items-center justify-center w-full mb-3 h-12 bg-black/10 dark:bg-white/10 backdrop-blur-lg rounded-xl shadow-primary dark:ring-1 ring-neutral-800/50">
|
<div className="flex items-center justify-center w-full mb-3 h-12 bg-black/10 dark:bg-white/10 rounded-xl shadow-primary dark:ring-1 ring-neutral-800/50">
|
||||||
<div className="flex items-center justify-center gap-2">
|
<div className="flex items-center justify-center gap-2">
|
||||||
<Spinner className="size-5" />
|
<Spinner className="size-5" />
|
||||||
<span className="text-sm font-medium">
|
<span className="text-sm font-medium">
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ function Screen() {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="px-3 flex flex-col gap-3">
|
<div className="px-3 flex flex-col gap-3">
|
||||||
<div className="relative flex flex-col items-center justify-center rounded-xl bg-black/10 dark:bg-white/10 backdrop-blur-lg">
|
<div className="relative flex flex-col items-center justify-center rounded-xl bg-black/10 dark:bg-white/10">
|
||||||
<div className="absolute top-2 left-3 text-2xl font-semibold font-serif text-neutral-600 dark:text-neutral-400">
|
<div className="absolute top-2 left-3 text-2xl font-semibold font-serif text-neutral-600 dark:text-neutral-400">
|
||||||
01.
|
01.
|
||||||
</div>
|
</div>
|
||||||
@@ -45,7 +45,7 @@ function Screen() {
|
|||||||
</video>
|
</video>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative flex flex-col items-center justify-center rounded-xl bg-black/10 dark:bg-white/10 backdrop-blur-lg">
|
<div className="relative flex flex-col items-center justify-center rounded-xl bg-black/10 dark:bg-white/10">
|
||||||
<div className="absolute top-2 left-3 text-2xl font-semibold font-serif text-neutral-600 dark:text-neutral-400">
|
<div className="absolute top-2 left-3 text-2xl font-semibold font-serif text-neutral-600 dark:text-neutral-400">
|
||||||
02.
|
02.
|
||||||
</div>
|
</div>
|
||||||
@@ -68,7 +68,7 @@ function Screen() {
|
|||||||
</video>
|
</video>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative flex flex-col items-center justify-center rounded-xl bg-black/10 dark:bg-white/10 backdrop-blur-lg">
|
<div className="relative flex flex-col items-center justify-center rounded-xl bg-black/10 dark:bg-white/10">
|
||||||
<div className="absolute top-2 left-3 text-2xl font-semibold font-serif text-neutral-600 dark:text-neutral-400">
|
<div className="absolute top-2 left-3 text-2xl font-semibold font-serif text-neutral-600 dark:text-neutral-400">
|
||||||
03.
|
03.
|
||||||
</div>
|
</div>
|
||||||
@@ -91,7 +91,7 @@ function Screen() {
|
|||||||
</video>
|
</video>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative flex flex-col items-center justify-center rounded-xl bg-black/10 dark:bg-white/10 backdrop-blur-lg">
|
<div className="relative flex flex-col items-center justify-center rounded-xl bg-black/10 dark:bg-white/10">
|
||||||
<div className="absolute top-2 left-3 text-2xl font-semibold font-serif text-neutral-600 dark:text-neutral-400">
|
<div className="absolute top-2 left-3 text-2xl font-semibold font-serif text-neutral-600 dark:text-neutral-400">
|
||||||
04.
|
04.
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ function Screen() {
|
|||||||
{[...data.reactions.entries()].map(([root, events]) => (
|
{[...data.reactions.entries()].map(([root, events]) => (
|
||||||
<div
|
<div
|
||||||
key={root}
|
key={root}
|
||||||
className="flex flex-col gap-1 p-2 mb-2 rounded-lg shrink-0 backdrop-blur-md bg-black/10 dark:bg-white/10"
|
className="flex flex-col gap-1 p-2 mb-2 rounded-lg shrink-0 bg-black/10 dark:bg-white/10"
|
||||||
>
|
>
|
||||||
<div className="flex flex-col flex-1 min-w-0 gap-2">
|
<div className="flex flex-col flex-1 min-w-0 gap-2">
|
||||||
<div className="flex items-center gap-2 pb-2 border-b border-black/5 dark:border-white/5">
|
<div className="flex items-center gap-2 pb-2 border-b border-black/5 dark:border-white/5">
|
||||||
@@ -197,7 +197,7 @@ function Screen() {
|
|||||||
<div className="flex flex-wrap items-center gap-3">
|
<div className="flex flex-wrap items-center gap-3">
|
||||||
{events.map((event) => (
|
{events.map((event) => (
|
||||||
<User.Provider key={event.id} pubkey={event.pubkey}>
|
<User.Provider key={event.id} pubkey={event.pubkey}>
|
||||||
<User.Root className="shrink-0 flex rounded-full h-8 bg-black/10 dark:bg-white/10 backdrop-blur-md p-[2px]">
|
<User.Root className="shrink-0 flex rounded-full h-8 bg-black/10 dark:bg-white/10 p-[2px]">
|
||||||
<User.Avatar className="flex-1 rounded-full size-7" />
|
<User.Avatar className="flex-1 rounded-full size-7" />
|
||||||
<div className="inline-flex items-center justify-center flex-1 text-xs truncate rounded-full size-7">
|
<div className="inline-flex items-center justify-center flex-1 text-xs truncate rounded-full size-7">
|
||||||
{event.kind === Kind.Reaction ? (
|
{event.kind === Kind.Reaction ? (
|
||||||
@@ -222,7 +222,7 @@ function Screen() {
|
|||||||
{[...data.zaps.entries()].map(([root, events]) => (
|
{[...data.zaps.entries()].map(([root, events]) => (
|
||||||
<div
|
<div
|
||||||
key={root}
|
key={root}
|
||||||
className="flex flex-col gap-1 p-2 mb-2 rounded-lg shrink-0 backdrop-blur-md bg-black/10 dark:bg-white/10"
|
className="flex flex-col gap-1 p-2 mb-2 rounded-lg shrink-0 bg-black/10 dark:bg-white/10"
|
||||||
>
|
>
|
||||||
<div className="flex flex-col flex-1 min-w-0 gap-2">
|
<div className="flex flex-col flex-1 min-w-0 gap-2">
|
||||||
<div className="flex items-center gap-2 pb-2 border-b border-black/5 dark:border-white/5">
|
<div className="flex items-center gap-2 pb-2 border-b border-black/5 dark:border-white/5">
|
||||||
@@ -234,7 +234,7 @@ function Screen() {
|
|||||||
key={event.id}
|
key={event.id}
|
||||||
pubkey={event.tags.find((tag) => tag[0] === "P")[1]}
|
pubkey={event.tags.find((tag) => tag[0] === "P")[1]}
|
||||||
>
|
>
|
||||||
<User.Root className="shrink-0 flex gap-1.5 rounded-full h-8 bg-black/10 dark:bg-white/10 backdrop-blur-md p-[2px]">
|
<User.Root className="shrink-0 flex gap-1.5 rounded-full h-8 bg-black/10 dark:bg-white/10 p-[2px]">
|
||||||
<User.Avatar className="rounded-full size-7" />
|
<User.Avatar className="rounded-full size-7" />
|
||||||
<div className="flex-1 h-7 w-max pr-1.5 rounded-full inline-flex items-center justify-center text-sm truncate">
|
<div className="flex-1 h-7 w-max pr-1.5 rounded-full inline-flex items-center justify-center text-sm truncate">
|
||||||
₿ {decodeZapInvoice(event.tags).bitcoinFormatted}
|
₿ {decodeZapInvoice(event.tags).bitcoinFormatted}
|
||||||
@@ -319,7 +319,7 @@ function TextNote({ event }: { event: LumeEvent }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Note.Provider event={event}>
|
<Note.Provider event={event}>
|
||||||
<Note.Root className="flex flex-col p-2 mb-2 rounded-lg shrink-0 backdrop-blur-md bg-black/10 dark:bg-white/10">
|
<Note.Root className="flex flex-col p-2 mb-2 rounded-lg shrink-0 bg-black/10 dark:bg-white/10">
|
||||||
<User.Provider pubkey={event.pubkey}>
|
<User.Provider pubkey={event.pubkey}>
|
||||||
<User.Root className="inline-flex items-center gap-2">
|
<User.Root className="inline-flex items-center gap-2">
|
||||||
<User.Avatar className="rounded-full size-9" />
|
<User.Avatar className="rounded-full size-9" />
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ function Screen() {
|
|||||||
data.map((item) => (
|
data.map((item) => (
|
||||||
<div
|
<div
|
||||||
key={item.pubkey}
|
key={item.pubkey}
|
||||||
className="w-full p-3 mb-2 overflow-hidden bg-white rounded-lg h-max dark:bg-black/20 backdrop-blur-lg shadow-primary dark:ring-1 ring-neutral-800/50"
|
className="w-full p-3 mb-2 overflow-hidden bg-white rounded-lg h-max dark:bg-black/20 shadow-primary dark:ring-1 ring-neutral-800/50"
|
||||||
>
|
>
|
||||||
<User.Provider pubkey={item.pubkey} embedProfile={item.profile}>
|
<User.Provider pubkey={item.pubkey} embedProfile={item.profile}>
|
||||||
<User.Root className="flex flex-col w-full h-full gap-2">
|
<User.Root className="flex flex-col w-full h-full gap-2">
|
||||||
|
|||||||
@@ -130,6 +130,28 @@ function Screen() {
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex items-start justify-between w-full gap-4 py-3">
|
||||||
|
<div className="flex-1">
|
||||||
|
<h3 className="font-medium">Vibrancy Effect</h3>
|
||||||
|
<p className="text-sm text-neutral-700 dark:text-neutral-300">
|
||||||
|
Make the window transparent.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-end w-36 shrink-0">
|
||||||
|
<Switch.Root
|
||||||
|
checked={settings.vibrancy}
|
||||||
|
onClick={() =>
|
||||||
|
setSettings((prev) => ({
|
||||||
|
...prev,
|
||||||
|
vibrancy: !prev.vibrancy,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
className="relative h-7 w-12 shrink-0 cursor-default rounded-full bg-black/10 outline-none data-[state=checked]:bg-blue-500 dark:bg-white/10"
|
||||||
|
>
|
||||||
|
<Switch.Thumb className="block size-6 translate-x-0.5 rounded-full bg-white transition-transform duration-100 will-change-transform data-[state=checked]:translate-x-[19px]" />
|
||||||
|
</Switch.Root>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div className="flex items-start justify-between w-full gap-4 py-3">
|
<div className="flex items-start justify-between w-full gap-4 py-3">
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<h3 className="font-medium">Zap Button</h3>
|
<h3 className="font-medium">Zap Button</h3>
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ function Screen() {
|
|||||||
className="absolute left-0 top-0 z-10 h-full w-full object-cover"
|
className="absolute left-0 top-0 z-10 h-full w-full object-cover"
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
<div className="absolute bottom-0 left-0 z-20 h-16 w-full bg-black/40 px-3 backdrop-blur-xl">
|
<div className="absolute bottom-0 left-0 z-20 h-16 w-full bg-black/40 px-3">
|
||||||
<div className="flex h-full items-center justify-between">
|
<div className="flex h-full items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="font-semibold text-white">{column.name}</h1>
|
<h1 className="font-semibold text-white">{column.name}</h1>
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ export function Screen() {
|
|||||||
<ScrollArea.Viewport ref={ref} className="h-full px-3 pb-3">
|
<ScrollArea.Viewport ref={ref} className="h-full px-3 pb-3">
|
||||||
<Virtualizer scrollRef={ref}>
|
<Virtualizer scrollRef={ref}>
|
||||||
{isFetching && !isLoading && !isFetchingNextPage ? (
|
{isFetching && !isLoading && !isFetchingNextPage ? (
|
||||||
<div className="flex items-center justify-center w-full mb-3 h-11 bg-black/10 dark:bg-white/10 backdrop-blur-lg rounded-xl shadow-primary dark:ring-1 ring-neutral-800/50">
|
<div className="flex items-center justify-center w-full mb-3 h-11 bg-black/10 dark:bg-white/10 rounded-xl shadow-primary dark:ring-1 ring-neutral-800/50">
|
||||||
<div className="flex items-center justify-center gap-2">
|
<div className="flex items-center justify-center gap-2">
|
||||||
<Spinner className="size-5" />
|
<Spinner className="size-5" />
|
||||||
<span className="text-sm font-medium">
|
<span className="text-sm font-medium">
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export function Screen() {
|
|||||||
users.profiles.map((item: { pubkey: string }) => (
|
users.profiles.map((item: { pubkey: string }) => (
|
||||||
<div
|
<div
|
||||||
key={item.pubkey}
|
key={item.pubkey}
|
||||||
className="h-max w-full overflow-hidden mb-3 p-2 bg-black/5 dark:bg-white/5 backdrop-blur-lg rounded-xl"
|
className="h-max w-full overflow-hidden mb-3 p-2 bg-black/5 dark:bg-white/5 rounded-xl"
|
||||||
>
|
>
|
||||||
<User.Provider pubkey={item.pubkey}>
|
<User.Provider pubkey={item.pubkey}>
|
||||||
<User.Root>
|
<User.Root>
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ function Screen() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Container withDrag>
|
<Container withDrag>
|
||||||
<Box className="px-0 scrollbar-none bg-black/5 dark:bg-white/5 backdrop-blur-sm">
|
<Box className="px-0 scrollbar-none bg-black/5 dark:bg-white/5">
|
||||||
<WindowVirtualizer>
|
<WindowVirtualizer>
|
||||||
<User.Provider pubkey={pubkey}>
|
<User.Provider pubkey={pubkey}>
|
||||||
<User.Root>
|
<User.Root>
|
||||||
|
|||||||
@@ -459,7 +459,7 @@ export type Column = { label: string; url: string; x: number; y: number; width:
|
|||||||
export type Meta = { content: string; images: string[]; videos: string[]; events: string[]; mentions: string[]; hashtags: string[] }
|
export type Meta = { content: string; images: string[]; videos: string[]; events: string[]; mentions: string[]; hashtags: string[] }
|
||||||
export type Relays = { connected: string[]; read: string[] | null; write: string[] | null; both: string[] | null }
|
export type Relays = { connected: string[]; read: string[] | null; write: string[] | null; both: string[] | null }
|
||||||
export type RichEvent = { raw: string; parsed: Meta | null }
|
export type RichEvent = { raw: string; parsed: Meta | null }
|
||||||
export type Settings = { proxy: string | null; image_resize_service: string | null; use_relay_hint: boolean; content_warning: boolean; display_avatar: boolean; display_zap_button: boolean; display_repost_button: boolean; display_media: boolean }
|
export type Settings = { proxy: string | null; image_resize_service: string | null; use_relay_hint: boolean; content_warning: boolean; display_avatar: boolean; display_zap_button: boolean; display_repost_button: boolean; display_media: boolean; vibrancy: boolean }
|
||||||
export type Window = { label: string; title: string; url: string; width: number; height: number; maximizable: boolean; minimizable: boolean; hidden_title: boolean }
|
export type Window = { label: string; title: string; url: string; width: number; height: number; maximizable: boolean; minimizable: boolean; hidden_title: boolean }
|
||||||
|
|
||||||
/** tauri-specta globals **/
|
/** tauri-specta globals **/
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
import { ArrowLeftIcon, ArrowRightIcon } from "@lume/icons";
|
|
||||||
import { cn } from "@lume/utils";
|
|
||||||
import { useSnapCarousel } from "react-snap-carousel";
|
|
||||||
|
|
||||||
interface CarouselProps<T> {
|
|
||||||
readonly items: T[];
|
|
||||||
readonly renderItem: (
|
|
||||||
props: CarouselRenderItemProps<T>,
|
|
||||||
) => React.ReactElement<CarouselItemProps>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CarouselRenderItemProps<T> {
|
|
||||||
readonly item: T;
|
|
||||||
readonly index: number;
|
|
||||||
readonly isSnapPoint: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Carousel = <T,>({ items, renderItem }: CarouselProps<T>) => {
|
|
||||||
const { scrollRef, pages, activePageIndex, prev, next, snapPointIndexes } =
|
|
||||||
useSnapCarousel();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="relative group">
|
|
||||||
<ul
|
|
||||||
ref={scrollRef}
|
|
||||||
className="relative flex overflow-auto snap-x scrollbar-none"
|
|
||||||
>
|
|
||||||
{items.map((item, index) =>
|
|
||||||
renderItem({
|
|
||||||
item,
|
|
||||||
index,
|
|
||||||
isSnapPoint: snapPointIndexes.has(index),
|
|
||||||
}),
|
|
||||||
)}
|
|
||||||
</ul>
|
|
||||||
<div
|
|
||||||
aria-hidden
|
|
||||||
className="absolute z-10 items-center justify-between hidden w-full px-5 transform -translate-x-1/2 -translate-y-1/2 group-hover:flex left-1/2 top-1/2"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={cn(
|
|
||||||
"size-11 rounded-full bg-black/50 backdrop-blur-sm flex items-center justify-center text-white",
|
|
||||||
activePageIndex <= 0 ? "opacity-50" : "",
|
|
||||||
)}
|
|
||||||
onClick={() => prev()}
|
|
||||||
>
|
|
||||||
<ArrowLeftIcon className="size-6" />
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={cn(
|
|
||||||
"size-11 rounded-full bg-black/50 backdrop-blur-sm flex items-center justify-center text-white",
|
|
||||||
activePageIndex <= 0 ? "opacity-50" : "",
|
|
||||||
)}
|
|
||||||
onClick={() => next()}
|
|
||||||
>
|
|
||||||
<ArrowRightIcon className="size-6" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div className="absolute flex items-center justify-center w-12 h-6 text-sm font-medium text-white bg-black rounded-full top-3 right-3 mix-blend-multiply bg-opacity-20 backdrop-blur-sm">
|
|
||||||
{activePageIndex + 1} / {pages.length}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
interface CarouselItemProps {
|
|
||||||
readonly isSnapPoint: boolean;
|
|
||||||
readonly children?: React.ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const CarouselItem = ({ isSnapPoint, children }: CarouselItemProps) => {
|
|
||||||
return (
|
|
||||||
<li
|
|
||||||
className={cn(
|
|
||||||
"w-[240px] h-[320px] shrink-0 pl-3 last:pr-2",
|
|
||||||
isSnapPoint ? "" : "snap-start",
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
export * from "./container";
|
export * from "./container";
|
||||||
export * from "./box";
|
export * from "./box";
|
||||||
export * from "./spinner";
|
export * from "./spinner";
|
||||||
export * from "./carousel";
|
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ pub struct Settings {
|
|||||||
display_zap_button: bool,
|
display_zap_button: bool,
|
||||||
display_repost_button: bool,
|
display_repost_button: bool,
|
||||||
display_media: bool,
|
display_media: bool,
|
||||||
|
vibrancy: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Settings {
|
impl Default for Settings {
|
||||||
@@ -56,6 +57,7 @@ impl Default for Settings {
|
|||||||
display_zap_button: true,
|
display_zap_button: true,
|
||||||
display_repost_button: true,
|
display_repost_button: true,
|
||||||
display_media: true,
|
display_media: true,
|
||||||
|
vibrancy: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user