feat: add ability change column name on the fly (#180)

Co-authored-by: reya <reya@lume.nu>
This commit is contained in:
Ren Amamiya 2024-04-22 14:33:14 +07:00 committed by GitHub
parent 17766d29d6
commit c755b8d137
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 70 additions and 9 deletions

View File

@ -2,6 +2,7 @@ import { useEffect, useRef, useState } from "react";
import { LumeColumn } from "@lume/types";
import { invoke } from "@tauri-apps/api/core";
import { Spinner } from "@lume/ui";
import { cn } from "@lume/utils";
export function Col({
column,
@ -83,7 +84,12 @@ export function Col({
return (
<div ref={container} className="h-full w-[440px] shrink-0 p-2">
{column.label !== "open" ? (
<div className="w-full h-full flex items-center justify-center rounded-xl flex-col bg-black/5 dark:bg-white/5 backdrop-blur-lg">
<div
className={cn(
"w-full h-full flex items-center justify-center rounded-xl flex-col",
!webview ? "bg-black/5 dark:bg-white/5 backdrop-blur-lg" : "",
)}
>
<button type="button" className="size-5" disabled>
<Spinner className="size-5" />
</button>

View File

@ -89,6 +89,18 @@ function Screen() {
});
}, 150);
const updateName = useDebouncedCallback((label: string, title: string) => {
const currentColIndex = columns.findIndex((col) => col.label === label);
const updatedCol = Object.assign({}, columns[currentColIndex]);
updatedCol.name = title;
const newCols = columns.slice();
newCols[currentColIndex] = updatedCol;
setColumns(newCols);
}, 150);
const startResize = useDebouncedCallback(
() => setIsResize((prev) => !prev),
150,
@ -111,6 +123,8 @@ function Screen() {
unlistenColEvent = await listen<EventColumns>("columns", (data) => {
if (data.payload.type === "add") add(data.payload.column);
if (data.payload.type === "remove") remove(data.payload.label);
if (data.payload.type === "set_title")
updateName(data.payload.label, data.payload.title);
});
unlistenWindowResize = await getCurrent().listen("tauri://resize", () => {

View File

@ -102,8 +102,9 @@ export interface LumeColumn {
}
export interface EventColumns {
type: "add" | "remove" | "update" | "left" | "right";
type: "add" | "remove" | "update" | "left" | "right" | "set_title";
label?: string;
title?: string;
column?: LumeColumn;
}

View File

@ -1,7 +1,8 @@
import { CancelIcon, ExpandIcon, RefreshIcon } from "@lume/icons";
import { CancelIcon, CheckIcon, RefreshIcon } from "@lume/icons";
import { cn } from "@lume/utils";
import { useSearch } from "@tanstack/react-router";
import { getCurrent } from "@tauri-apps/api/window";
import { ReactNode } from "react";
import { ReactNode, useEffect, useState } from "react";
export function ColumnHeader({
label,
@ -14,6 +15,23 @@ export function ColumnHeader({
className?: string;
children?: ReactNode;
}) {
const search = useSearch({ strict: false });
const [title, setTitle] = useState(name);
const [isChanged, setIsChanged] = useState(false);
const saveNewTitle = async () => {
const mainWindow = getCurrent();
await mainWindow.emit("columns", { type: "set_title", label, title });
// update search params
// @ts-ignore, hahaha
search.name = title;
// reset state
setIsChanged(false);
};
const reload = () => {
window.location.reload();
};
@ -23,6 +41,10 @@ export function ColumnHeader({
await mainWindow.emit("columns", { type: "remove", label });
};
useEffect(() => {
if (title.length !== name.length) setIsChanged(true);
}, [title]);
return (
<div
className={cn(
@ -30,11 +52,29 @@ export function ColumnHeader({
className,
)}
>
{!children ? (
<div className="text-[13px] font-medium">{name}</div>
) : (
children
)}
<div className="relative flex gap-2 items-center">
{!children ? (
<div
contentEditable
suppressContentEditableWarning={true}
onBlur={(e) => setTitle(e.currentTarget.textContent)}
className="text-[13px] font-medium focus:outline-none"
>
{name}
</div>
) : (
children
)}
{isChanged ? (
<button
type="button"
onClick={saveNewTitle}
className="text-teal-500 hover:text-teal-600"
>
<CheckIcon className="size-4" />
</button>
) : null}
</div>
<div className="inline-flex items-center gap-1">
<button
type="button"