chore: follow up

This commit is contained in:
reya 2024-03-19 15:36:20 +07:00
parent 7fabf949c6
commit 5d59040224
14 changed files with 145 additions and 155 deletions

View File

@ -1,12 +1,8 @@
import { useArk } from "@lume/ark";
import { Account } from "@lume/types";
import { User } from "@lume/ui";
import { useNavigate, useParams, useSearch } from "@tanstack/react-router";
import { useNavigate, useParams } from "@tanstack/react-router";
import { useEffect, useState } from "react";
import * as Popover from "@radix-ui/react-popover";
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
import { BackupDialog } from "./backup";
import { LoginDialog } from "./login";
export function Accounts() {
const ark = useArk();
@ -60,91 +56,11 @@ function Inactive({ pubkey }: { pubkey: string }) {
}
function Active({ pubkey }: { pubkey: string }) {
const ark = useArk();
const navigate = useNavigate();
// @ts-ignore, magic !!!
const { guest } = useSearch({ strict: false });
// @ts-ignore, magic !!!
const { account } = useParams({ strict: false });
if (guest) {
return (
<Popover.Root open={true}>
<Popover.Trigger asChild>
<button type="button">
<User.Provider pubkey={pubkey}>
<User.Root className="rounded-full ring-1 ring-teal-500 ring-offset-2 ring-offset-neutral-200 dark:ring-offset-neutral-950">
<User.Avatar className="aspect-square h-auto w-7 rounded-full object-cover" />
</User.Root>
</User.Provider>
</button>
</Popover.Trigger>
<Popover.Portal>
<Popover.Content
className="flex w-[280px] flex-col gap-4 rounded-xl bg-black p-5 text-neutral-100 focus:outline-none dark:bg-white dark:text-neutral-900 dark:shadow-none"
sideOffset={10}
side="bottom"
>
<div>
<h1 className="mb-1 font-semibold">
You're using random account
</h1>
<p className="text-sm text-neutral-500 dark:text-neutral-600">
You can continue by claim and backup this account, or you can
import your own account.
</p>
</div>
<div className="flex flex-col gap-2">
<BackupDialog />
<LoginDialog />
</div>
<Popover.Arrow className="fill-black dark:fill-white" />
</Popover.Content>
</Popover.Portal>
</Popover.Root>
);
}
return (
<DropdownMenu.Root>
<DropdownMenu.Trigger>
<User.Provider pubkey={pubkey}>
<User.Root className="rounded-full ring-1 ring-teal-500 ring-offset-2 ring-offset-neutral-200 dark:ring-offset-neutral-950">
<User.Avatar className="aspect-square h-auto w-7 rounded-full object-cover" />
</User.Root>
</User.Provider>
</DropdownMenu.Trigger>
<DropdownMenu.Portal>
<DropdownMenu.Content
className="flex w-[220px] flex-col rounded-xl bg-black p-2 text-neutral-100 focus:outline-none dark:bg-white dark:text-neutral-900 dark:shadow-none"
sideOffset={10}
side="bottom"
>
<DropdownMenu.Item className="group relative flex h-9 select-none items-center rounded-md px-3 text-sm font-medium leading-none outline-none hover:bg-neutral-900 dark:hover:bg-neutral-100">
Add account
</DropdownMenu.Item>
<DropdownMenu.Item
onClick={() => ark.open_profile(account)}
className="group relative flex h-9 select-none items-center rounded-md px-3 text-sm font-medium leading-none outline-none hover:bg-neutral-900 dark:hover:bg-neutral-100"
>
Profile
<div className="ml-auto pl-5 text-xs text-neutral-800 dark:text-neutral-200">
+Shift+P
</div>
</DropdownMenu.Item>
<DropdownMenu.Item
onClick={() => navigate({ to: "/", search: { manually: true } })}
className="group relative flex h-9 select-none items-center rounded-md px-3 text-sm font-medium leading-none outline-none hover:bg-neutral-900 dark:hover:bg-neutral-100"
>
Logout
<div className="ml-auto pl-5 text-xs text-neutral-800 dark:text-neutral-200">
+Shift+L
</div>
</DropdownMenu.Item>
<DropdownMenu.Arrow className="fill-black dark:fill-white" />
</DropdownMenu.Content>
</DropdownMenu.Portal>
</DropdownMenu.Root>
<User.Provider pubkey={pubkey}>
<User.Root className="rounded-full ring-1 ring-teal-500 ring-offset-2 ring-offset-neutral-200 dark:ring-offset-neutral-950">
<User.Avatar className="aspect-square h-auto w-7 rounded-full object-cover" />
</User.Root>
</User.Provider>
);
}

View File

@ -120,3 +120,5 @@ export * from "./src/local";
export * from "./src/global";
export * from "./src/infoCircle";
export * from "./src/cancelCircle";
export * from "./src/laurel";
export * from "./src/quote";

View File

@ -0,0 +1,13 @@
export function LaurelIcon(props: JSX.IntrinsicElements["svg"]) {
return (
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" {...props}>
<path
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="1.5"
d="M9.405 18.105c-1.573 1.336-3.136 1.17-4.712-.5 3.665-3.643 8.229 1.637 4.189 3.645m5.713-3.145c1.573 1.336 3.136 1.17 4.712-.5-3.665-3.643-8.229 1.637-4.189 3.645m-8.333-6.084c-.584-2.476-2.086-3.338-4.535-2.603.584 2.476 2.086 3.338 4.535 2.603Zm-1.21-3.464c.74-2.434-.127-3.927-2.617-4.508-.74 2.435.127 3.928 2.618 4.508ZM6.719 2.75c-2.141 1.393-2.442 3.09-.91 5.127 2.141-1.393 2.442-3.09.91-5.127Zm10.497 12.416c.584-2.476 2.086-3.338 4.535-2.603-.584 2.476-2.086 3.338-4.535 2.603Zm1.21-3.464c-.74-2.434.127-3.927 2.617-4.508.74 2.435-.127 3.928-2.618 4.508ZM17.281 2.75c2.141 1.393 2.442 3.09.91 5.127-2.141-1.393-2.442-3.09-.91-5.127Z"
/>
</svg>
);
}

View File

@ -1,16 +1,12 @@
import { SVGProps } from "react";
export function LinkIcon(
props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>,
) {
export function LinkIcon(props: JSX.IntrinsicElements["svg"]) {
return (
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" {...props}>
<path
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M9 6H7.2c-1.12 0-1.68 0-2.108.218a2 2 0 0 0-.874.874C4 7.52 4 8.08 4 9.2v7.6c0 1.12 0 1.68.218 2.108a2 2 0 0 0 .874.874C5.52 20 6.08 20 7.2 20h7.6c1.12 0 1.68 0 2.108-.218a2 2 0 0 0 .874-.874C18 18.48 18 17.92 18 16.8V15M14 4h6m0 0v6m0-6-9 9"
strokeWidth="1.5"
d="M9.25 3.75h-2.3c-1.12 0-1.68 0-2.108.218a2 2 0 0 0-.874.874c-.218.428-.218.988-.218 2.108v10.1c0 1.12 0 1.68.218 2.108a2 2 0 0 0 .874.874c.428.218.988.218 2.108.218h10.1c1.12 0 1.68 0 2.108-.218a2 2 0 0 0 .874-.874c.218-.428.218-.988.218-2.108v-2.3m-6.5-11h6.5m0 0v6.5m0-6.5L11 13"
/>
</svg>
);

View File

@ -0,0 +1,13 @@
export function QuoteIcon(props: JSX.IntrinsicElements["svg"]) {
return (
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" {...props}>
<path
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="1.5"
d="M11.855 21.25c-1.032-.26-3.16-.908-5.45-3.222C2.58 14.161 1.6 8.88 4.219 6.233 6.369 4.06 10.55 4.185 14 6.5m3.5 3.5c2.977 3.473 3.86 6.797 1.576 8.644-1.711 1.383-3.877-.217-5.14-1.45m-.748-3.944H10.75v-2.421a2 2 0 0 1 .586-1.415l5.499-5.499a2 2 0 0 1 2.83.001l.424.425a2 2 0 0 1 0 2.826l-5.485 5.496a2 2 0 0 1-1.416.587Z"
/>
</svg>
);
}

View File

@ -3,10 +3,9 @@ export function ReplyIcon(props: JSX.IntrinsicElements["svg"]) {
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" {...props}>
<path
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M12 21a9 9 0 1 0-9-9c0 1.354.3 2.639.835 3.791.102.219.133.465.076.7l-.778 3.191a1 1 0 0 0 1.191 1.213l3.33-.752c.224-.05.458-.02.667.073A8.969 8.969 0 0 0 12 21Z"
strokeWidth="1.5"
d="m21.76 11.45-8.146-7.535a.75.75 0 0 0-1.26.55V8a.51.51 0 0 1-.504.504C3.765 8.632 1.604 11.92 1.604 20.25c1.47-2.94 2.22-4.679 10.245-4.748a.501.501 0 0 1 .505.498v3.535a.75.75 0 0 0 1.26.55l8.145-7.535a.75.75 0 0 0 0-1.1Z"
/>
</svg>
);

View File

@ -5,8 +5,8 @@ export function RepostIcon(props: JSX.IntrinsicElements["svg"]) {
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="m17.25 21 2.47-2.47a.75.75 0 0 0 0-1.06L17.25 15M6.75 3 4.28 5.47a.75.75 0 0 0 0 1.06L6.75 9M5 6h13a2 2 0 0 1 2 2v3M4 13v3a2 2 0 0 0 2 2h13"
strokeWidth="1.5"
d="m17.5 21.25 2.47-2.47a.75.75 0 0 0 0-1.06l-2.47-2.47m-11-12.5L4.03 5.22a.75.75 0 0 0 0 1.06L6.5 8.75m-1.25-3h13a2 2 0 0 1 2 2v3m-16.5 3v2.5a2 2 0 0 0 2 2h13"
/>
</svg>
);

View File

@ -4,8 +4,8 @@ export function ZapIcon(props: JSX.IntrinsicElements["svg"]) {
<path
stroke="currentColor"
strokeLinejoin="round"
strokeWidth="2"
d="M19.566 9H13.5a.5.5 0 0 1-.5-.5V2.401a.5.5 0 0 0-.916-.277L4.018 14.223a.5.5 0 0 0 .416.777H10.5a.5.5 0 0 1 .5.5v6.099a.5.5 0 0 0 .916.277l8.066-12.099A.5.5 0 0 0 19.566 9Z"
strokeWidth="1.5"
d="M19.798 8.75H13.75a.5.5 0 0 1-.5-.5V2.356a.5.5 0 0 0-.912-.284L3.791 14.466a.5.5 0 0 0 .411.784h6.048a.5.5 0 0 1 .5.5v5.894a.5.5 0 0 0 .912.284l8.547-12.394a.5.5 0 0 0-.411-.784Z"
/>
</svg>
);

View File

@ -81,6 +81,7 @@ export interface RichContent {
}
export interface LumeColumn {
id: number;
content: string;
name: string;
description?: string;
@ -88,6 +89,12 @@ export interface LumeColumn {
logo?: string;
}
export interface EventColumns {
type: "add" | "remove" | "update" | "left" | "right";
id?: number;
column?: LumeColumn;
}
export interface Opengraph {
url: string;
title?: string;

View File

@ -1,9 +1,8 @@
import { LinkIcon, ReplyIcon } from "@lume/icons";
import { ReplyIcon } from "@lume/icons";
import * as Tooltip from "@radix-ui/react-tooltip";
import { useTranslation } from "react-i18next";
import { useNoteContext } from "../provider";
import { useArk } from "@lume/ark";
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
export function NoteReply() {
const ark = useArk();
@ -12,52 +11,24 @@ export function NoteReply() {
const { t } = useTranslation();
return (
<DropdownMenu.Root>
<Tooltip.Provider>
<Tooltip.Root delayDuration={150}>
<DropdownMenu.Trigger asChild>
<Tooltip.Trigger asChild>
<button
type="button"
className="group inline-flex size-7 items-center justify-center text-neutral-800 dark:text-neutral-200"
>
<ReplyIcon className="size-5 group-hover:text-blue-500" />
</button>
</Tooltip.Trigger>
</DropdownMenu.Trigger>
<Tooltip.Portal>
<Tooltip.Content className="data-[state=delayed-open]:data-[side=bottom]:animate-slideUpAndFade data-[state=delayed-open]:data-[side=left]:animate-slideRightAndFade data-[state=delayed-open]:data-[side=right]:animate-slideLeftAndFade data-[state=delayed-open]:data-[side=top]:animate-slideDownAndFade inline-flex h-7 select-none items-center justify-center rounded-md bg-neutral-950 px-3.5 text-sm text-neutral-50 will-change-[transform,opacity] dark:bg-neutral-50 dark:text-neutral-950">
{t("note.menu.viewThread")}
<Tooltip.Arrow className="fill-neutral-950 dark:fill-neutral-50" />
</Tooltip.Content>
</Tooltip.Portal>
</Tooltip.Root>
</Tooltip.Provider>
<DropdownMenu.Portal>
<DropdownMenu.Content className="flex w-[200px] flex-col overflow-hidden rounded-xl bg-black p-1 shadow-md shadow-neutral-500/20 focus:outline-none dark:bg-white">
<DropdownMenu.Item asChild>
<button
type="button"
onClick={() => ark.open_thread(event.id)}
className="inline-flex h-9 items-center gap-2 rounded-lg px-3 text-sm font-medium text-white hover:bg-neutral-900 focus:outline-none dark:text-black dark:hover:bg-neutral-100"
>
<LinkIcon className="size-4" />
{t("note.buttons.open")}
</button>
</DropdownMenu.Item>
<DropdownMenu.Item asChild>
<button
type="button"
onClick={() => ark.open_editor(event.id)}
className="inline-flex h-9 items-center gap-2 rounded-lg px-3 text-sm font-medium text-white hover:bg-neutral-900 focus:outline-none dark:text-black dark:hover:bg-neutral-100"
>
<ReplyIcon className="size-4" />
{t("note.buttons.reply")}
</button>
</DropdownMenu.Item>
<DropdownMenu.Arrow className="fill-black dark:fill-white" />
</DropdownMenu.Content>
</DropdownMenu.Portal>
</DropdownMenu.Root>
<Tooltip.Provider>
<Tooltip.Root delayDuration={150}>
<Tooltip.Trigger asChild>
<button
type="button"
onClick={() => ark.open_editor(event.id)}
className="group inline-flex size-7 items-center justify-center text-neutral-800 dark:text-neutral-200"
>
<ReplyIcon className="size-5 group-hover:text-blue-500" />
</button>
</Tooltip.Trigger>
<Tooltip.Portal>
<Tooltip.Content className="data-[state=delayed-open]:data-[side=bottom]:animate-slideUpAndFade data-[state=delayed-open]:data-[side=left]:animate-slideRightAndFade data-[state=delayed-open]:data-[side=right]:animate-slideLeftAndFade data-[state=delayed-open]:data-[side=top]:animate-slideDownAndFade inline-flex h-7 select-none items-center justify-center rounded-md bg-neutral-950 px-3.5 text-sm text-neutral-50 will-change-[transform,opacity] dark:bg-neutral-50 dark:text-neutral-950">
{t("note.menu.viewThread")}
<Tooltip.Arrow className="fill-neutral-950 dark:fill-neutral-50" />
</Tooltip.Content>
</Tooltip.Portal>
</Tooltip.Root>
</Tooltip.Provider>
);
}

View File

@ -1,4 +1,4 @@
import { LoaderIcon, ReplyIcon, RepostIcon } from "@lume/icons";
import { LoaderIcon, QuoteIcon, ReplyIcon, RepostIcon } from "@lume/icons";
import { cn } from "@lume/utils";
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
import * as Tooltip from "@radix-ui/react-tooltip";
@ -84,7 +84,7 @@ export function NoteRepost() {
onClick={() => ark.open_editor(event.id, true)}
className="inline-flex h-9 items-center gap-2 rounded-lg px-3 text-sm font-medium text-white hover:bg-neutral-900 focus:outline-none dark:text-black dark:hover:bg-neutral-100"
>
<ReplyIcon className="size-4" />
<QuoteIcon className="size-4" />
{t("note.buttons.quote")}
</button>
</DropdownMenu.Item>

View File

@ -1,2 +1,3 @@
pub mod folder;
pub mod opg;
pub mod window;

View File

@ -0,0 +1,69 @@
use std::path::PathBuf;
use tauri::{LogicalPosition, LogicalSize, Manager, WebviewUrl};
#[tauri::command]
pub fn create_column(
label: &str,
x: f32,
y: f32,
width: f32,
height: f32,
url: &str,
app_handle: tauri::AppHandle,
) -> Result<String, String> {
match app_handle.get_window("main") {
Some(main_window) => match app_handle.get_webview(label) {
Some(_) => Err("Webview is exist".into()),
None => {
let path = PathBuf::from(url);
let webview_url = WebviewUrl::App(path);
let builder = tauri::webview::WebviewBuilder::new(label, webview_url)
.auto_resize()
.user_agent("Lume/4.0")
.transparent(true);
match main_window.add_child(
builder,
LogicalPosition::new(x, y),
LogicalSize::new(width, height),
) {
Ok(webview) => Ok(webview.label().into()),
Err(_) => Err("Something is wrong".into()),
}
}
},
None => Err("Main window not found".into()),
}
}
#[tauri::command]
pub fn close_column(label: &str, app_handle: tauri::AppHandle) -> Result<bool, String> {
match app_handle.get_webview(label) {
Some(webview) => {
if let Ok(_) = webview.close() {
Ok(true)
} else {
Ok(false)
}
}
None => Err("Webview not found".into()),
}
}
#[tauri::command]
pub fn reposition_column(
label: &str,
x: f32,
y: f32,
app_handle: tauri::AppHandle,
) -> Result<(), String> {
match app_handle.get_webview(label) {
Some(webview) => {
if let Ok(_) = webview.set_position(LogicalPosition::new(x, y)) {
Ok(())
} else {
Err("Reposition column failed".into())
}
}
None => Err("Webview not found".into()),
}
}

View File

@ -117,6 +117,9 @@ fn main() {
commands::folder::show_in_folder,
commands::folder::get_accounts,
commands::opg::fetch_opg,
commands::window::create_column,
commands::window::close_column,
commands::window::reposition_column
])
.build(tauri::generate_context!())
.expect("error while running tauri application")