Skip to content

Commit

Permalink
feat: 完善剪切板记录功能
Browse files Browse the repository at this point in the history
  • Loading branch information
ayangweb committed Jun 8, 2024
1 parent 6313a89 commit 9fac156
Show file tree
Hide file tree
Showing 15 changed files with 284 additions and 82 deletions.
10 changes: 6 additions & 4 deletions src/database/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { TableName, TablePayload } from "@/types/database";
import { getName } from "@tauri-apps/api/app";
import { appConfigDir } from "@tauri-apps/api/path";
import { isBoolean, map } from "lodash-es";
import { isBoolean, isNil, map, omitBy } from "lodash-es";
import Database from "tauri-plugin-sql-api";

let db: Database;
Expand All @@ -15,7 +15,7 @@ export const initDatabase = async () => {

await executeSQL(
`
CREATE TABLE IF NOT EXISTS history (id INTEGER PRIMARY KEY AUTOINCREMENT, type TEXT, content TEXT, createTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP, isFavorite INTEGER DEFAULT 0);
CREATE TABLE IF NOT EXISTS history (id INTEGER PRIMARY KEY AUTOINCREMENT, type TEXT, [group] TEXT, content TEXT, createTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP, isFavorite INTEGER DEFAULT 0);
`,
);
};
Expand Down Expand Up @@ -115,9 +115,11 @@ export const deleteSQL = async (tableName: TableName, id?: number) => {
* @param payload 数据
*/
const handlePayload = (payload: TablePayload) => {
const keys = Object.keys(payload);
const omitPayload = omitBy(payload, isNil);

const keys = map(Object.keys(omitPayload), (key) => `[${key}]`);
const refs = map(keys, () => "?");
const values = map(Object.values(payload), (item) => {
const values = map(Object.values(omitPayload), (item) => {
return isBoolean(item) ? Number(item) : item;
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { HistoryContext } from "@/pages/Clipboard/History";
import type { HistoryGroup } from "@/types/database";
import { Flex, Tag } from "antd";
import { last } from "lodash-es";

interface TabItem {
label: string;
value?: HistoryGroup;
}

const tabList: TabItem[] = [
{
label: "全部",
},
{
label: "文本",
value: "text",
},
{
label: "图片",
value: "image",
},
{
label: "文件",
value: "files",
},
{
label: "收藏",
},
];

const Tab = () => {
const { state } = useContext(HistoryContext);

const [checked, setChecked] = useState(tabList[0].label);

return (
<Flex data-tauri-drag-region>
{tabList.map((item) => {
const { label, value } = item;

return (
<Tag.CheckableTag
key={label}
checked={checked === label}
onChange={() => {
setChecked(label);
state.group = value;
state.isFavorite = label === last(tabList)?.label || undefined;
}}
>
{label}
</Tag.CheckableTag>
);
})}
</Flex>
);
};

export default Tab;
48 changes: 48 additions & 0 deletions src/pages/Clipboard/History/components/Header/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import Icon from "@/components/Icon";
import { appWindow } from "@tauri-apps/api/window";
import { Flex } from "antd";
import clsx from "clsx";
import Tab from "./components/Tab";

interface State {
pin?: boolean;
}

const Header = () => {
const state = useReactive<State>({});

useMount(() => {
appWindow.onFocusChanged(({ payload }) => {
if (payload || state.pin) return;

hideWindow();
});
});

return (
<Flex
data-tauri-drag-region
align="center"
justify="space-between"
className="color-2 pb-12 text-18"
>
<Flex align="center" gap="small">
<Icon hoverable name="i-lucide:search" />

<Tab />
</Flex>

<Icon
hoverable
active={state.pin}
name="i-ri:pushpin-2-line"
className={clsx({ "rotate-45": state.pin })}
onMouseDown={() => {
state.pin = !state.pin;
}}
/>
</Flex>
);
};

export default Header;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { HistoryItem } from "@/types/database";
import type { FC } from "react";

const Files: FC<HistoryItem> = (props) => {
const { content = "" } = props;

const a: string[] = JSON.parse(content);

return <div>{a.join("\n")}</div>;
};

export default Files;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { HistoryItem } from "@/types/database";
import type { FC } from "react";

const Html: FC<HistoryItem> = (props) => {
const { content = "" } = props;

return <div dangerouslySetInnerHTML={{ __html: content }} />;
};

export default Html;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { HistoryItem } from "@/types/database";
import type { FC } from "react";

const Image: FC<HistoryItem> = (props) => {
const { content } = props;

return <img src={content} />;
};

export default Image;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { HistoryItem } from "@/types/database";
import type { FC } from "react";

const Rtf: FC<HistoryItem> = (props) => {
const { content } = props;

return content;
};

export default Rtf;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { HistoryItem } from "@/types/database";
import type { FC } from "react";

const Text: FC<HistoryItem> = (props) => {
const { content } = props;

return content;
};

export default Text;
65 changes: 65 additions & 0 deletions src/pages/Clipboard/History/components/Popup/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import type { HistoryItem } from "@/types/database";
import { Flex } from "antd";
import { FixedSizeList } from "react-window";
import { HistoryContext } from "../..";
import Files from "./components/Files";
import Html from "./components/Html";
import Image from "./components/Image";
import Rtf from "./components/Rtf";
import Text from "./components/Text";

const Popup = () => {
const { state } = useContext(HistoryContext);

const renderContent = (data: HistoryItem) => {
switch (data.type) {
case "rtf":
return <Rtf {...data} />;
case "html":
return <Html {...data} />;
case "image":
return <Image {...data} />;
case "files":
return <Files {...data} />;
default:
return <Text {...data} />;
}
};

return (
<FixedSizeList
width={336}
height={542}
itemData={state.historyList}
itemKey={(index, data) => data[index].id!}
itemCount={state.historyList.length}
itemSize={120}
>
{(item) => {
const { index, style, data } = item;
const { type, createTime } = data[index];

return (
<div
data-tauri-drag-region
style={style}
className="not-last-of-type:pb-12"
>
<div className="h-full overflow-hidden rounded-6 bg-white p-6 shadow">
<Flex justify="space-between" className="pb-6 text-12">
<span>{type}</span>
<span>{createTime}</span>
</Flex>

<div className="overflow-hidden">
{renderContent(data[index])}
</div>
</div>
</div>
);
}}
</FixedSizeList>
);
};

export default Popup;
Loading

0 comments on commit 9fac156

Please sign in to comment.