feat: improve column management

This commit is contained in:
2024-03-22 11:28:54 +07:00
parent dd7155a3a6
commit ec0f3fabc0
18 changed files with 194 additions and 130 deletions

View File

@@ -1,4 +1,4 @@
import { useEffect, useMemo, useRef, useState } from "react"; import { useEffect, useMemo, useRef } from "react";
import { getCurrent } from "@tauri-apps/api/window"; import { getCurrent } from "@tauri-apps/api/window";
import { LumeColumn } from "@lume/types"; import { LumeColumn } from "@lume/types";
import { invoke } from "@tauri-apps/api/core"; import { invoke } from "@tauri-apps/api/core";
@@ -13,39 +13,39 @@ export function Col({
isScroll: boolean; isScroll: boolean;
}) { }) {
const window = useMemo(() => getCurrent(), []); const window = useMemo(() => getCurrent(), []);
const webview = useRef<string>(null);
const container = useRef<HTMLDivElement>(null); const container = useRef<HTMLDivElement>(null);
const [webview, setWebview] = useState<string>(null);
const createWebview = async () => { const createWebview = async () => {
const rect = container.current.getBoundingClientRect(); const rect = container.current.getBoundingClientRect();
const name = `column-${column.name.toLowerCase().replace(/\W/g, "")}`; const label = `column-${column.id}`;
const url = column.content + `?account=${account}&name=${column.name}`; const url =
column.content +
`?account=${account}&id=${column.id}&name=${column.name}`;
// create new webview // create new webview
const label: string = await invoke("create_column", { webview.current = await invoke("create_column", {
label: name, label,
x: rect.x, x: rect.x,
y: rect.y, y: rect.y,
width: rect.width, width: rect.width,
height: rect.height, height: rect.height,
url, url,
}); });
setWebview(label);
}; };
const closeWebview = async () => { const closeWebview = async () => {
if (!webview) return; const close = await invoke("close_column", {
await invoke("close_column", { label: webview.current,
label: webview,
}); });
if (close) webview.current = null;
}; };
const repositionWebview = async () => { const repositionWebview = async () => {
if (!webview.current) return;
const newRect = container.current.getBoundingClientRect(); const newRect = container.current.getBoundingClientRect();
await invoke("reposition_column", { await invoke("reposition_column", {
label: webview, label: webview.current,
x: newRect.x, x: newRect.x,
y: newRect.y, y: newRect.y,
}); });
@@ -60,13 +60,14 @@ export function Col({
useEffect(() => { useEffect(() => {
if (!window) return; if (!window) return;
if (!container.current) return; if (!container.current) return;
if (webview.current) return;
// create webview for current column // create webview for current column
createWebview(); createWebview();
// close webview when unmounted // close webview when unmounted
return () => { return () => {
closeWebview(); if (webview.current) closeWebview();
}; };
}, []); }, []);

View File

@@ -1,6 +1,6 @@
import { Col } from "@/components/col"; import { Col } from "@/components/col";
import { Toolbar } from "@/components/toolbar"; import { Toolbar } from "@/components/toolbar";
import { LoaderIcon, PlusIcon } from "@lume/icons"; import { LoaderIcon } from "@lume/icons";
import { EventColumns, LumeColumn } from "@lume/types"; import { EventColumns, LumeColumn } from "@lume/types";
import { createFileRoute } from "@tanstack/react-router"; import { createFileRoute } from "@tanstack/react-router";
import { UnlistenFn } from "@tauri-apps/api/event"; import { UnlistenFn } from "@tauri-apps/api/event";
@@ -14,13 +14,14 @@ export const Route = createFileRoute("/$account/home")({
}); });
const DEFAULT_COLUMNS: LumeColumn[] = [ const DEFAULT_COLUMNS: LumeColumn[] = [
{ id: 1, name: "Newsfeed", content: "/newsfeed" }, { id: 10001, name: "Newsfeed", content: "/newsfeed" },
{ id: 10002, name: "For You", content: "/foryou" },
{ id: 10000, name: "Open Lume Store", content: "/open" },
]; ];
function Screen() { function Screen() {
const search = Route.useSearch(); const search = Route.useSearch();
const vlistRef = useRef<VListHandle>(null); const vlistRef = useRef<VListHandle>(null);
const unlisten = useRef<UnlistenFn>(null);
const [columns, setColumns] = useState(DEFAULT_COLUMNS); const [columns, setColumns] = useState(DEFAULT_COLUMNS);
const [selectedIndex, setSelectedIndex] = useState(-1); const [selectedIndex, setSelectedIndex] = useState(-1);
@@ -43,27 +44,51 @@ function Screen() {
}; };
const add = (column: LumeColumn) => { const add = (column: LumeColumn) => {
const col = columns.find((item) => item.id === column.id); const existed = columns.find((item) => item.id === column.id);
if (!col) { if (!existed) {
setColumns((prev) => [...prev, column]); let lastColIndex: number;
const openColIndex = columns.findIndex((item) => item.id === 10000);
const storeColIndex = columns.findIndex((item) => item.id === 9999);
if (storeColIndex) {
lastColIndex = storeColIndex;
} else {
lastColIndex = openColIndex;
}
const newColumns = [
...columns.slice(0, lastColIndex),
column,
...columns.slice(lastColIndex),
];
// update state & scroll to new column
setColumns(newColumns);
setSelectedIndex(newColumns.length - 1);
vlistRef.current.scrollToIndex(newColumns.length - 1, {
align: "center",
});
} }
}; };
const remove = (id: number) => { const remove = (id: number) => {
setColumns((prev) => prev.filter((t) => t.id !== id)); setColumns((prev) => prev.filter((t) => t.id !== id));
setSelectedIndex(columns.length);
vlistRef.current.scrollToIndex(columns.length, {
align: "center",
});
}; };
useEffect(() => { useEffect(() => {
let unlisten: UnlistenFn = undefined;
const listenColumnEvent = async () => { const listenColumnEvent = async () => {
const mainWindow = getCurrent(); const mainWindow = getCurrent();
if (!unlisten) { if (!unlisten) {
unlisten.current = await mainWindow.listen<EventColumns>( unlisten = await mainWindow.listen<EventColumns>("columns", (data) => {
"columns",
(data) => {
if (data.payload.type === "add") add(data.payload.column); if (data.payload.type === "add") add(data.payload.column);
if (data.payload.type === "remove") remove(data.payload.id); if (data.payload.type === "remove") remove(data.payload.id);
}, });
);
} }
}; };
@@ -71,7 +96,12 @@ function Screen() {
listenColumnEvent(); listenColumnEvent();
// clean up // clean up
return () => unlisten.current?.(); return () => {
if (unlisten) {
unlisten();
unlisten = null;
}
};
}, []); }, []);
return ( return (
@@ -106,9 +136,9 @@ function Screen() {
}} }}
className="scrollbar-none h-full w-full overflow-x-auto focus:outline-none" className="scrollbar-none h-full w-full overflow-x-auto focus:outline-none"
> >
{columns.map((column, index) => ( {columns.map((column) => (
<Col <Col
key={column.id + index} key={column.id}
column={column} column={column}
// @ts-ignore, yolo !!! // @ts-ignore, yolo !!!
account={search.acccount} account={search.acccount}

View File

@@ -15,7 +15,7 @@ export const Route = createLazyFileRoute("/antenas")({
export function Screen() { export function Screen() {
// @ts-ignore, just work!!! // @ts-ignore, just work!!!
const { name, account } = Route.useSearch(); const { id, name, account } = Route.useSearch();
const { t } = useTranslation(); const { t } = useTranslation();
const { const {
data, data,
@@ -38,7 +38,7 @@ export function Screen() {
return ( return (
<Column.Root> <Column.Root>
<Column.Header name={name} /> <Column.Header id={id} name={name} />
<Column.Content> <Column.Content>
{isLoading || isRefetching ? ( {isLoading || isRefetching ? (
<div className="flex h-20 w-full flex-col items-center justify-center gap-1"> <div className="flex h-20 w-full flex-col items-center justify-center gap-1">

View File

@@ -15,7 +15,7 @@ export const Route = createLazyFileRoute("/foryou")({
export function Screen() { export function Screen() {
// @ts-ignore, just work!!! // @ts-ignore, just work!!!
const { name, account } = Route.useSearch(); const { id, name, account } = Route.useSearch();
const { t } = useTranslation(); const { t } = useTranslation();
const { const {
data, data,
@@ -38,7 +38,7 @@ export function Screen() {
return ( return (
<Column.Root> <Column.Root>
<Column.Header name={name} /> <Column.Header id={id} name={name} />
<Column.Content> <Column.Content>
{isLoading || isRefetching ? ( {isLoading || isRefetching ? (
<div className="flex h-20 w-full flex-col items-center justify-center gap-1"> <div className="flex h-20 w-full flex-col items-center justify-center gap-1">

View File

@@ -15,7 +15,7 @@ export const Route = createLazyFileRoute("/global")({
export function Screen() { export function Screen() {
// @ts-ignore, just work!!! // @ts-ignore, just work!!!
const { name, account } = Route.useSearch(); const { id, name, account } = Route.useSearch();
const { t } = useTranslation(); const { t } = useTranslation();
const { const {
data, data,
@@ -38,7 +38,7 @@ export function Screen() {
return ( return (
<Column.Root> <Column.Root>
<Column.Header name={name} /> <Column.Header id={id} name={name} />
<Column.Content> <Column.Content>
{isLoading || isRefetching ? ( {isLoading || isRefetching ? (
<div className="flex h-20 w-full flex-col items-center justify-center gap-1"> <div className="flex h-20 w-full flex-col items-center justify-center gap-1">

View File

@@ -15,7 +15,7 @@ export const Route = createLazyFileRoute("/group")({
export function Screen() { export function Screen() {
// @ts-ignore, just work!!! // @ts-ignore, just work!!!
const { name, account } = Route.useSearch(); const { id, name, account } = Route.useSearch();
const { t } = useTranslation(); const { t } = useTranslation();
const { const {
data, data,
@@ -38,7 +38,7 @@ export function Screen() {
return ( return (
<Column.Root> <Column.Root>
<Column.Header name={name} /> <Column.Header id={id} name={name} />
<Column.Content> <Column.Content>
{isLoading || isRefetching ? ( {isLoading || isRefetching ? (
<div className="flex h-20 w-full flex-col items-center justify-center gap-1"> <div className="flex h-20 w-full flex-col items-center justify-center gap-1">

View File

@@ -15,7 +15,7 @@ export const Route = createLazyFileRoute("/newsfeed")({
export function Screen() { export function Screen() {
// @ts-ignore, just work!!! // @ts-ignore, just work!!!
const { name, account } = Route.useSearch(); const { id, name, account } = Route.useSearch();
const { t } = useTranslation(); const { t } = useTranslation();
const { const {
data, data,
@@ -38,7 +38,7 @@ export function Screen() {
return ( return (
<Column.Root> <Column.Root>
<Column.Header name={name} /> <Column.Header id={id} name={name} />
<Column.Content> <Column.Content>
{isLoading || isRefetching ? ( {isLoading || isRefetching ? (
<div className="flex h-20 w-full flex-col items-center justify-center gap-1"> <div className="flex h-20 w-full flex-col items-center justify-center gap-1">
@@ -61,11 +61,13 @@ export function Screen() {
</Virtualizer> </Virtualizer>
)} )}
<div className="flex h-20 items-center justify-center"> <div className="flex h-20 items-center justify-center">
{hasNextPage ? ( {!isLoading && hasNextPage ? (
<button <button
type="button" type="button"
onClick={() => fetchNextPage()} onClick={() => fetchNextPage()}
disabled={!hasNextPage || isFetchingNextPage} disabled={
!hasNextPage || isFetchingNextPage || isFetchingNextPage
}
className="inline-flex h-12 w-36 items-center justify-center gap-2 rounded-full bg-neutral-100 px-3 font-medium hover:bg-neutral-200 focus:outline-none dark:bg-neutral-900 dark:hover:bg-neutral-800" className="inline-flex h-12 w-36 items-center justify-center gap-2 rounded-full bg-neutral-100 px-3 font-medium hover:bg-neutral-200 focus:outline-none dark:bg-neutral-900 dark:hover:bg-neutral-800"
> >
{isFetchingNextPage ? ( {isFetchingNextPage ? (

View File

@@ -0,0 +1,36 @@
import { PlusIcon } from "@lume/icons";
import { LumeColumn } from "@lume/types";
import { Column } from "@lume/ui";
import { createLazyRoute } from "@tanstack/react-router";
import { getCurrent } from "@tauri-apps/api/window";
export const Route = createLazyRoute("/open")({
component: Screen,
});
function Screen() {
const install = async (column: LumeColumn) => {
const mainWindow = getCurrent();
await mainWindow.emit("columns", { type: "add", column });
};
return (
<Column.Root shadow={false} background={false}>
<Column.Content className="flex h-full w-full items-center justify-center">
<button
type="button"
onClick={() =>
install({
id: 9999,
name: "Lume Store",
content: "/store/official",
})
}
className="inline-flex size-14 items-center justify-center rounded-full bg-black/10 backdrop-blur-lg hover:bg-black/20 dark:bg-white/10 dark:hover:bg-white/20"
>
<PlusIcon className="size-8" />
</button>
</Column.Content>
</Column.Root>
);
}

View File

@@ -7,7 +7,7 @@ export const Route = createFileRoute("/store/official")({
loader: () => { loader: () => {
const columns: LumeColumn[] = [ const columns: LumeColumn[] = [
{ {
id: 10000, id: 10002,
name: "For you", name: "For you",
content: "/foryou", content: "/foryou",
logo: "", logo: "",
@@ -17,7 +17,7 @@ export const Route = createFileRoute("/store/official")({
description: "Keep up to date with content based on your interests.", description: "Keep up to date with content based on your interests.",
}, },
{ {
id: 10001, id: 10003,
name: "Group Feeds", name: "Group Feeds",
content: "/group", content: "/group",
logo: "", logo: "",
@@ -27,7 +27,7 @@ export const Route = createFileRoute("/store/official")({
description: "Collective of people you're interested in.", description: "Collective of people you're interested in.",
}, },
{ {
id: 10002, id: 10004,
name: "Antenas", name: "Antenas",
content: "/antenas", content: "/antenas",
logo: "", logo: "",
@@ -37,7 +37,7 @@ export const Route = createFileRoute("/store/official")({
description: "Keep track to specific content.", description: "Keep track to specific content.",
}, },
{ {
id: 10003, id: 10005,
name: "Trending", name: "Trending",
content: "/trending", content: "/trending",
logo: "", logo: "",
@@ -47,7 +47,7 @@ export const Route = createFileRoute("/store/official")({
description: "What is trending on Nostr?.", description: "What is trending on Nostr?.",
}, },
{ {
id: 10004, id: 10006,
name: "Global", name: "Global",
content: "/global", content: "/global",
logo: "", logo: "",
@@ -56,16 +56,6 @@ export const Route = createFileRoute("/store/official")({
author: "Lume", author: "Lume",
description: "All events from connected relays.", description: "All events from connected relays.",
}, },
{
id: 10005,
name: "Waifu",
content: "/waifu",
logo: "",
cover: "/waifu.png",
coverRetina: "/waifu@2x.png",
author: "Lume",
description: "Show a random waifu image to boost your morale.",
},
]; ];
return columns; return columns;
}, },

View File

@@ -1,18 +1,28 @@
import { GlobalIcon, LaurelIcon } from "@lume/icons"; import { CancelIcon, GlobalIcon, LaurelIcon } from "@lume/icons";
import { Column } from "@lume/ui"; import { Column } from "@lume/ui";
import { cn } from "@lume/utils"; import { cn } from "@lume/utils";
import { Link } from "@tanstack/react-router"; import { Link } from "@tanstack/react-router";
import { Outlet, createFileRoute } from "@tanstack/react-router"; import { Outlet, createFileRoute } from "@tanstack/react-router";
import { getCurrent } from "@tauri-apps/api/window";
export const Route = createFileRoute("/store")({ export const Route = createFileRoute("/store")({
component: Screen, component: Screen,
}); });
function Screen() { function Screen() {
// @ts-ignore, just work!!!
const { id } = Route.useSearch();
const close = async () => {
const mainWindow = getCurrent();
await mainWindow.emit("columns", { type: "remove", id });
};
return ( return (
<Column.Root> <Column.Root>
<Column.Content> <Column.Content>
<div className="flex h-14 shrink-0 items-center gap-2 border-b border-neutral-100 px-3 dark:border-neutral-900"> <div className="flex h-14 shrink-0 items-center justify-between border-b border-neutral-100 px-3 dark:border-neutral-900">
<div className="inline-flex h-full w-full items-center gap-2">
<Link to="/store/official"> <Link to="/store/official">
{({ isActive }) => ( {({ isActive }) => (
<div <div
@@ -44,6 +54,10 @@ function Screen() {
)} )}
</Link> </Link>
</div> </div>
<button type="button" onClick={close}>
<CancelIcon className="size-4 text-neutral-700 dark:text-neutral-300" />
</button>
</div>
<Outlet /> <Outlet />
</Column.Content> </Column.Content>
</Column.Root> </Column.Root>

View File

@@ -15,7 +15,7 @@ export const Route = createLazyFileRoute("/trending")({
export function Screen() { export function Screen() {
// @ts-ignore, just work!!! // @ts-ignore, just work!!!
const { name, account } = Route.useSearch(); const { id, name, account } = Route.useSearch();
const { t } = useTranslation(); const { t } = useTranslation();
const { const {
data, data,
@@ -38,7 +38,7 @@ export function Screen() {
return ( return (
<Column.Root> <Column.Root>
<Column.Header name={name} /> <Column.Header id={id} name={name} />
<Column.Content> <Column.Content>
{isLoading || isRefetching ? ( {isLoading || isRefetching ? (
<div className="flex h-20 w-full flex-col items-center justify-center gap-1"> <div className="flex h-20 w-full flex-col items-center justify-center gap-1">

View File

@@ -1,18 +0,0 @@
import { Column } from "@lume/ui";
import { createLazyFileRoute } from "@tanstack/react-router";
export const Route = createLazyFileRoute("/waifu")({
component: Screen,
});
function Screen() {
// @ts-ignore, just work!!!
const { name } = Route.useSearch();
return (
<Column.Root>
<Column.Header name={name} />
<Column.Content>waifu</Column.Content>
</Column.Root>
);
}

View File

@@ -4,8 +4,8 @@ export function CancelIcon(props: JSX.IntrinsicElements["svg"]) {
<path <path
stroke="currentColor" stroke="currentColor"
strokeLinecap="round" strokeLinecap="round"
strokeWidth="2" strokeWidth="1.5"
d="m5 5 14 14m0-14L5 19" d="m4.75 4.75 14.5 14.5m0-14.5-14.5 14.5"
/> />
</svg> </svg>
); );

View File

@@ -1,18 +1,10 @@
export function TrashIcon(props: JSX.IntrinsicElements['svg']) { export function TrashIcon(props: JSX.IntrinsicElements["svg"]) {
return ( return (
<svg <svg width="24" height="24" fill="none" viewBox="0 0 24 24" {...props}>
{...props} <path
xmlns="http://www.w3.org/2000/svg" fill="currentColor"
viewBox="0 0 24 24" d="m5.63 19.379.748-.049-.749.049Zm12.74 0-.748-.049.749.049ZM2.75 5a.75.75 0 0 0 0 1.5V5Zm18.5 1.5a.75.75 0 0 0 0-1.5v1.5Zm-6.102-.563a.75.75 0 1 0 1.452-.374l-1.452.374ZM4.002 5.798l.879 13.63 1.497-.098-.88-13.628-1.496.096ZM7.625 22h8.75v-1.5h-8.75V22Zm11.494-2.573L20 5.798l-1.497-.096-.88 13.629 1.497.096ZM19.25 5H4.75v1.5h14.5V5ZM2.75 6.5h2V5h-2v1.5Zm16.5 0h2V5h-2v1.5ZM16.375 22a2.75 2.75 0 0 0 2.744-2.573l-1.497-.096a1.25 1.25 0 0 1-1.247 1.169V22ZM4.88 19.427A2.75 2.75 0 0 0 7.625 22v-1.5a1.25 1.25 0 0 1-1.247-1.17l-1.497.097ZM12 3.5a3.252 3.252 0 0 1 3.148 2.437l1.452-.374A4.752 4.752 0 0 0 12 2v1.5ZM8.852 5.937A3.252 3.252 0 0 1 12 3.5V2a4.752 4.752 0 0 0-4.6 3.563l1.452.374Z"
width="24" />
height="24"
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
>
<path d="m16 6-1.106-2.211a3.236 3.236 0 0 0-5.788 0L8 6M4 6h16m-10 5v5m4-5v5M6 6h12v9c0 1.864 0 2.796-.305 3.53a4 4 0 0 1-2.164 2.165C14.796 21 13.864 21 12 21s-2.796 0-3.53-.305a4 4 0 0 1-2.166-2.164C6 17.796 6 16.864 6 15V6Z" />
</svg> </svg>
); );
} }

View File

@@ -1,11 +1,14 @@
import { ChevronDownIcon, RefreshIcon } from "@lume/icons"; import { ChevronDownIcon, RefreshIcon, TrashIcon } from "@lume/icons";
import { cn } from "@lume/utils"; import { cn } from "@lume/utils";
import * as DropdownMenu from "@radix-ui/react-dropdown-menu"; import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
import { getCurrent } from "@tauri-apps/api/window";
export function ColumnHeader({ export function ColumnHeader({
id,
name, name,
className, className,
}: { }: {
id: number;
name: string; name: string;
className?: string; className?: string;
}) { }) {
@@ -13,6 +16,11 @@ export function ColumnHeader({
window.location.reload(); window.location.reload();
}; };
const close = async () => {
const mainWindow = getCurrent();
await mainWindow.emit("columns", { type: "remove", id });
};
return ( return (
<DropdownMenu.Root> <DropdownMenu.Root>
<div <div
@@ -35,11 +43,18 @@ export function ColumnHeader({
> >
<DropdownMenu.Item <DropdownMenu.Item
onClick={reload} onClick={reload}
className="inline-flex h-9 items-center gap-3 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" 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"
> >
<RefreshIcon className="size-4" /> <RefreshIcon className="size-4" />
Reload Reload
</DropdownMenu.Item> </DropdownMenu.Item>
<DropdownMenu.Item
onClick={close}
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"
>
<TrashIcon className="size-4" />
Close
</DropdownMenu.Item>
<DropdownMenu.Arrow className="fill-black dark:fill-white" /> <DropdownMenu.Arrow className="fill-black dark:fill-white" />
</DropdownMenu.Content> </DropdownMenu.Content>
</DropdownMenu.Portal> </DropdownMenu.Portal>

View File

@@ -4,18 +4,21 @@ import { ReactNode } from "react";
export function ColumnRoot({ export function ColumnRoot({
children, children,
shadow = true, shadow = true,
background = true,
className, className,
}: { }: {
children: ReactNode; children: ReactNode;
shadow?: boolean; shadow?: boolean;
background?: boolean;
className?: string; className?: string;
}) { }) {
return ( return (
<div className="h-full w-full p-2"> <div className="h-full w-full p-2">
<div <div
className={cn( className={cn(
"relative flex h-full w-full flex-col rounded-xl bg-white dark:bg-black", "relative flex h-full w-full flex-col rounded-xl",
shadow ? "shadow-primary" : "", shadow ? "shadow-primary" : "",
background ? "bg-white dark:bg-black" : "",
className, className,
)} )}
> >

View File

@@ -23,7 +23,7 @@ export function UserNip05({ className }: { className?: string }) {
<p className={cn("text-sm", className)}> <p className={cn("text-sm", className)}>
{!user.profile?.nip05 {!user.profile?.nip05
? displayNpub(user.pubkey, 16) ? displayNpub(user.pubkey, 16)
: user.profile?.nip05.length > 16 : user.profile?.nip05.length > 50
? displayLongHandle(user.profile?.nip05) ? displayLongHandle(user.profile?.nip05)
: user.profile.nip05?.replace("_@", "")} : user.profile.nip05?.replace("_@", "")}
</p> </p>

View File

@@ -18,7 +18,6 @@ pub fn create_column(
let path = PathBuf::from(url); let path = PathBuf::from(url);
let webview_url = WebviewUrl::App(path); let webview_url = WebviewUrl::App(path);
let builder = tauri::webview::WebviewBuilder::new(label, webview_url) let builder = tauri::webview::WebviewBuilder::new(label, webview_url)
.auto_resize()
.user_agent("Lume/4.0") .user_agent("Lume/4.0")
.transparent(true); .transparent(true);
match main_window.add_child( match main_window.add_child(