Skip to content

Commit

Permalink
new day new cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
0-don committed Dec 20, 2024
1 parent 1e2db9d commit d88cb9c
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 60 deletions.
7 changes: 7 additions & 0 deletions src-tauri/common/src/types/orm_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ pub struct ClipboardWithRelations {
pub files: Vec<clipboard_file::Model>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ClipboardsResponse {
pub clipboards: Vec<ClipboardWithRelations>,
pub total: u64,
pub has_more: bool,
}

#[derive(Debug, Clone)]
pub struct ClipboardManager {
pub clipboard_model: entity::clipboard::ActiveModel,
Expand Down
21 changes: 16 additions & 5 deletions src-tauri/src/commands/clipboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ extern crate alloc;
extern crate image;
use crate::{
service::clipboard::{
clear_clipboards_db, copy_clipboard_from_id, delete_clipboard_db, get_clipboard_db,
get_clipboards_db, star_clipboard_db,
clear_clipboards_db, copy_clipboard_from_id, delete_clipboard_db, get_clipboard_count_db,
get_clipboard_db, get_clipboards_db, star_clipboard_db,
},
tauri_config::config::APP,
utils::hotkey_manager::unregister_hotkeys,
};
use common::types::{enums::ClipboardType, orm_query::ClipboardWithRelations, types::CommandError};
use common::types::{enums::ClipboardType, orm_query::ClipboardsResponse, types::CommandError};
use std::fs::File;
use tauri::Manager;

Expand All @@ -18,8 +18,19 @@ pub async fn get_clipboards(
search: Option<String>,
star: Option<bool>,
img: Option<bool>,
) -> Result<Vec<ClipboardWithRelations>, CommandError> {
Ok(get_clipboards_db(cursor, search, star, img).await?)
) -> Result<ClipboardsResponse, CommandError> {
let clipboards = get_clipboards_db(cursor, search, star, img).await?;
let total = get_clipboard_count_db().await?;

// Calculate if there are more items
let current_position = cursor.unwrap_or(0) + clipboards.len() as u64;
let has_more = current_position < total;

Ok(ClipboardsResponse {
clipboards,
total,
has_more,
})
}

#[tauri::command]
Expand Down
10 changes: 10 additions & 0 deletions src-tauri/src/service/clipboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ pub async fn load_clipboards_with_relations(
.collect()
}

pub async fn get_clipboard_count_db() -> Result<u64, DbErr> {
let db = connection::db().await?;

let count = clipboard::Entity::find().count(&db).await?;

Ok(count)
}

pub async fn insert_clipboard_db(model: ClipboardManager) -> Result<ClipboardWithRelations, DbErr> {
let db = connection::db().await?;
let clipboard = model.clipboard_model.insert(&db).await?;
Expand Down Expand Up @@ -112,6 +120,8 @@ pub async fn insert_clipboard_db(model: ClipboardManager) -> Result<ClipboardWit
})
}



pub async fn get_clipboard_db(id: i32) -> Result<ClipboardWithRelations, DbErr> {
let db = connection::db().await?;
let clipboard = clipboard::Entity::find_by_id(id)
Expand Down
68 changes: 39 additions & 29 deletions src/components/pages/app/clipboard/base-clipboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,20 @@ interface BaseClipboardProps {
}

export const BaseClipboard: Component<BaseClipboardProps> = (props) => {
const { setClipboards } = ClipboardStore;
const { setClipboards, resetClipboards } = ClipboardStore;
const { clipboard } = props.data;

const handleDelete = async (id: number) => {
if (await invokeCommand(InvokeCommand.DeleteClipboard, { id })) {
setClipboards((prev) => prev.filter((o) => o.clipboard.id !== id));
setClipboards((prev) => {
const updated = prev.filter((o) => o.clipboard.id !== id);
console.log("updated", updated);
if (updated.length === 0) {
console.log("resetting clipboards");
resetClipboards();
}
return updated;
});
}
};

Expand Down Expand Up @@ -66,45 +74,47 @@ export const BaseClipboard: Component<BaseClipboardProps> = (props) => {
return (
<div class="group relative">
{/* Actions overlay */}
<div class="absolute bottom-0 right-0 top-0 z-10 flex flex-col items-end justify-between">
<div class="flex flex-col justify-between">
<VsStarFull
onClick={(e) => {
e.stopPropagation();
handleStar(clipboard);
}}
class={`${
clipboard.star ? "text-yellow-400 dark:text-yellow-300" : "hidden text-zinc-700"
} text-lg hover:text-yellow-400 group-hover:block dark:text-white dark:hover:text-yellow-300`}
<div class="absolute bottom-0 right-0 top-0 z-10 my-1 mr-0.5 flex flex-col items-end justify-between">
<VsStarFull
onClick={(e) => {
e.stopPropagation();
handleStar(clipboard);
}}
title="Star"
class={`${
clipboard.star ? "text-yellow-400 dark:text-yellow-300" : "hidden text-zinc-700"
} cursor-pointer text-lg hover:text-yellow-400 group-hover:block dark:text-white dark:hover:text-yellow-300`}
/>
{props.data.rtf && (
<BsJournalRichtext
onClick={handleRtfCopy}
title="Copy as RTF"
class="hidden cursor-pointer text-lg text-zinc-700 hover:text-blue-600 group-hover:block dark:text-white dark:hover:text-blue-400"
/>
)}
{props.data.html && (
<TbSourceCode
onClick={handleHtmlCopy}
title="Copy as HTML"
class="hidden cursor-pointer text-lg text-zinc-700 hover:text-green-600 group-hover:block dark:text-white dark:hover:text-green-400"
/>
{props.data.rtf && (
<BsJournalRichtext
onClick={handleRtfCopy}
title="Copy as RTF"
class="hidden text-lg text-zinc-700 hover:text-blue-600 group-hover:block dark:text-white dark:hover:text-blue-400"
/>
)}
{props.data.html && (
<TbSourceCode
onClick={handleHtmlCopy}
title="Copy as HTML"
class="hidden text-lg text-zinc-700 hover:text-green-600 group-hover:block dark:text-white dark:hover:text-green-400"
/>
)}
</div>
)}
<IoTrashOutline
onClick={(e) => {
e.stopPropagation();
handleDelete(clipboard.id);
}}
class="hidden text-lg text-zinc-700 hover:text-red-600 group-hover:block dark:text-white dark:hover:text-red-600"
title="Delete"
class="hidden cursor-pointer text-lg text-zinc-700 hover:text-red-600 group-hover:block dark:text-white dark:hover:text-red-600"
/>
</div>

{/* Content rendered by specific clipboard type */}
{clipboard.types.includes(ClipboardType.Image) && <ImageClipboard {...props} />}
{clipboard.types.includes(ClipboardType.File) && <FileClipboard {...props} />}
{clipboard.types.includes(ClipboardType.Text) && <TextClipboard {...props} />}
{(clipboard.types.includes(ClipboardType.Text) ||
clipboard.types.includes(ClipboardType.Html) ||
clipboard.types.includes(ClipboardType.Rtf)) && <TextClipboard {...props} />}
</div>
);
};
7 changes: 4 additions & 3 deletions src/components/pages/app/clipboard/clipboards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Component, For, Show, createSignal, onMount } from "solid-js";
import clippy from "../../../../assets/clippy.png";
import { ClipboardStore } from "../../../../store/clipboard-store";
import { HotkeyStore } from "../../../../store/hotkey-store";
import { HotkeyEvent } from "../../../../types/enums";
import { ListenEvent } from "../../../../types/tauri-listen";
import { listenEvent } from "../../../../utils/tauri";
import { BaseClipboard } from "./base-clipboard";
Expand All @@ -14,7 +15,7 @@ dayjs.extend(utc);
dayjs.extend(relativeTime);

export const Clipboards: Component = () => {
const { clipboards, setClipboards, getClipboards, setWhere, clipboardRef, setClipboardRef } = ClipboardStore;
const { clipboards, setClipboards, getClipboards, setWhere, clipboardRef, setClipboardRef, hasMore } = ClipboardStore;
const { globalHotkeyEvent, hotkeys } = HotkeyStore;
const [scrollToTop, setScrollToTop] = createSignal(false);

Expand All @@ -26,7 +27,7 @@ export const Clipboards: Component = () => {

clipboardRef()!.scrollTop !== 0 ? setScrollToTop(true) : setScrollToTop(false);

if (bottom) {
if (bottom && hasMore()) {
setWhere((prev) => ({ ...prev, cursor: clipboards().length }));
const newClipboards = await getClipboards();
setClipboards((prev) => [...prev, ...newClipboards]);
Expand Down Expand Up @@ -56,7 +57,7 @@ export const Clipboards: Component = () => {
<FiArrowUp class="text-xl !text-white dark:!text-white" />
<Show when={globalHotkeyEvent()}>
<div class="absolute left-0 top-0 -ml-3 -mt-3 rounded-sm bg-zinc-600 px-1 text-[12px] font-semibold">
{hotkeys().find((key) => key.event === "scroll_to_top")?.key}
{hotkeys().find((key) => key.event === HotkeyEvent.ScrollToTop)?.key}
</div>
</Show>
</div>
Expand Down
45 changes: 27 additions & 18 deletions src/components/pages/app/clipboard/text-clipboard.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,56 @@
import dayjs from "dayjs";
import { IoText } from "solid-icons/io";
import { Component } from "solid-js";
import { ClipboardWithRelations } from "../../../../types";
import { HotkeyNumber } from "../../../utils/hotkey-number";
import dayjs from "dayjs";
import { ClipboardType } from "../../../../types/enums";
import { InvokeCommand } from "../../../../types/tauri-invoke";
import { invokeCommand } from "../../../../utils/tauri";
import { HotkeyNumber } from "../../../utils/hotkey-number";

interface TextClipboardProps {
data: ClipboardWithRelations;
index: number;
}

export const TextClipboard: Component<TextClipboardProps> = (props) => {
let type = ClipboardType.Text;
let data = props.data.text?.data;

if (!props.data.text?.data && props.data.html?.data) {
type = ClipboardType.Html;
data = props.data.html.data;
}
if (!props.data.text?.data && props.data.rtf?.data) {
type = ClipboardType.Rtf;
data = props.data.rtf.data;
}

const handleClick = async (e: MouseEvent) => {
e.stopPropagation();
await invokeCommand(InvokeCommand.CopyClipboard, {
id: props.data.clipboard.id,
type: ClipboardType.Text,
type,
});
};

return (
<button
type="button"
onClick={handleClick}
class="group w-full cursor-pointer select-none px-3 hover:bg-zinc-200 dark:hover:bg-neutral-700"
class="group w-full cursor-pointer select-none hover:bg-zinc-200 dark:hover:bg-neutral-700"
>
<div class="px-0.5 py-3">
<div class="flex min-w-0">
<div class="flex items-center">
<div class="relative" title={props.data.clipboard.id.toString()}>
<IoText class="text-2xl text-zinc-700 dark:text-white" />
<HotkeyNumber index={props.index} />
</div>
</div>
<div class="mr-4 truncate px-4">
<div class="flex" title={props.data.text?.data || ""}>
<p class="text-sm">{props.data.text?.data || " "}</p>
</div>
</div>
<div class="mt-2 flex gap-2">
<div class="relative ml-3.5" title={props.data.clipboard.id.toString()}>
<IoText class="text-2xl text-zinc-700 dark:text-white" />
<HotkeyNumber index={props.index} />
</div>
<div class="pl-9 text-left text-xs text-zinc-400">{dayjs.utc(props.data.clipboard.created_date).fromNow()}</div>

<p class="truncate text-sm" title={data}>
{data}
</p>
</div>
<div class="mb-1 ml-10 text-left text-xs text-zinc-400">
{dayjs.utc(props.data.clipboard.created_date).fromNow()}
</div>
<hr class="border-zinc-400 dark:border-zinc-700" />
</button>
Expand Down
18 changes: 15 additions & 3 deletions src/store/clipboard-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ function createClipboardStore() {
const [clipboardRef, setClipboardRef] = createSignal<HTMLDivElement | undefined>();
const [clipboards, setClipboards] = createSignal<ClipboardWithRelations[]>([]);
const [where, setWhere] = createSignal<ClipboardWhere>(initialWhere);

const [hasMore, setHasMore] = createSignal(true);
const resetWhere = () => setWhere(initialWhere);

const getClipboards = async () => {
const clipboards = await invokeCommand(InvokeCommand.GetClipboards, where());
return clipboards;
const response = await invokeCommand(InvokeCommand.GetClipboards, where());
console.log(response);
setHasMore(response.has_more);
return response.clipboards;
};

const initClipboards = async () => {
Expand All @@ -28,11 +30,21 @@ function createClipboardStore() {
setClipboards(clipboards);
};

const resetClipboards = async () => {
setWhere(initialWhere);
setHasMore(true);
const clipboards = await getClipboards();
setClipboards(clipboards);
};

return {
clipboards,
setClipboards,
where,
setWhere,
hasMore,
setHasMore,
resetClipboards,
resetWhere,
getClipboards,
clipboardRef,
Expand Down
5 changes: 5 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ export interface ClipboardWithRelations {
rtf?: ClipboardRtfModel;
files?: ClipboardFileModel[];
}
export interface ClipboardResponse {
clipboards: ClipboardWithRelations[];
total: number;
has_more: boolean;
}

export type Hotkey = {
id: number;
Expand Down
4 changes: 2 additions & 2 deletions src/types/tauri-invoke.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ClipboardWhere, ClipboardWithRelations, DatabaseInfo, Hotkey, Settings } from ".";
import { ClipboardResponse, ClipboardWhere, DatabaseInfo, Hotkey, Settings } from ".";
import { ClipboardType, WebWindow } from "./enums";

export enum InvokeCommand {
Expand Down Expand Up @@ -36,7 +36,7 @@ export interface TauriInvokeCommands {
// Clipboard commands
[InvokeCommand.GetClipboards]: {
args: ClipboardWhere;
return: ClipboardWithRelations[];
return: ClipboardResponse;
};
[InvokeCommand.DeleteClipboard]: {
args: { id: number };
Expand Down

0 comments on commit d88cb9c

Please sign in to comment.