feat: add source and source_icon for all rows

This commit is contained in:
PandaDEV 2024-12-15 18:52:16 +10:00
parent 8f0d53d355
commit 5c6853b02b
No known key found for this signature in database
GPG key ID: 13EFF9BAF70EE75C
4 changed files with 86 additions and 26 deletions

View file

@ -12,6 +12,7 @@ use regex::Regex;
use url::Url;
use base64::{Engine, engine::general_purpose::STANDARD};
use crate::utils::commands::get_app_info;
use crate::utils::favicon::fetch_favicon_as_base64;
use crate::db;
use crate::utils::types::{ContentType, HistoryItem};
@ -97,6 +98,8 @@ pub fn setup<R: Runtime>(app: &AppHandle<R>) {
let clipboard = app.state::<Clipboard>();
let available_types = clipboard.available_types().unwrap();
let (app_name, app_icon) = get_app_info();
match get_pool(&app).await {
Ok(pool) => {
if available_types.image {
@ -108,7 +111,7 @@ pub fn setup<R: Runtime>(app: &AppHandle<R>) {
.unwrap_or_else(|e| e);
let _ = db::history::add_history_item(
pool,
HistoryItem::new(ContentType::Image, file_path, None),
HistoryItem::new(app_name, ContentType::Image, file_path, None, app_icon),
).await;
}
} else if available_types.files {
@ -117,7 +120,7 @@ pub fn setup<R: Runtime>(app: &AppHandle<R>) {
let files_str = files.join(", ");
let _ = db::history::add_history_item(
pool,
HistoryItem::new(ContentType::File, files_str, None),
HistoryItem::new(app_name, ContentType::File, files_str, None, app_icon),
).await;
}
} else if available_types.text {
@ -134,7 +137,7 @@ pub fn setup<R: Runtime>(app: &AppHandle<R>) {
let _ = db::history::add_history_item(
pool,
HistoryItem::new(ContentType::Link, text, favicon)
HistoryItem::new(app_name, ContentType::Link, text, favicon, app_icon)
).await;
}
} else {
@ -143,7 +146,7 @@ pub fn setup<R: Runtime>(app: &AppHandle<R>) {
}
let _ = db::history::add_history_item(
pool,
HistoryItem::new(ContentType::Text, text, None)
HistoryItem::new(app_name, ContentType::Text, text, None, app_icon)
).await;
}
}
@ -192,4 +195,4 @@ async fn save_image_to_file<R: Runtime>(app_handle: &AppHandle<R>, base64_data:
fs::write(&file_path, bytes)?;
Ok(file_path.to_string_lossy().into_owned())
}
}

View file

@ -13,9 +13,10 @@ pub async fn initialize_history(pool: &SqlitePool) -> Result<(), Box<dyn std::er
.collect();
sqlx::query(
"INSERT INTO history (id, content_type, content, timestamp) VALUES (?, ?, ?, CURRENT_TIMESTAMP)"
"INSERT INTO history (id, source, content_type, content, timestamp) VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP)"
)
.bind(id)
.bind("System")
.bind("text")
.bind("Welcome to your clipboard history!")
.execute(pool)
@ -27,7 +28,7 @@ pub async fn initialize_history(pool: &SqlitePool) -> Result<(), Box<dyn std::er
#[tauri::command]
pub async fn get_history(pool: tauri::State<'_, SqlitePool>) -> Result<Vec<HistoryItem>, String> {
let rows = sqlx::query(
"SELECT id, content_type, content, favicon, timestamp FROM history ORDER BY timestamp DESC",
"SELECT id, source, source_icon, content_type, content, favicon, timestamp FROM history ORDER BY timestamp DESC",
)
.fetch_all(&*pool)
.await
@ -37,6 +38,8 @@ pub async fn get_history(pool: tauri::State<'_, SqlitePool>) -> Result<Vec<Histo
.iter()
.map(|row| HistoryItem {
id: row.get("id"),
source: row.get("source"),
source_icon: row.get("source_icon"),
content_type: ContentType::from(row.get::<String, _>("content_type")),
content: row.get("content"),
favicon: row.get("favicon"),
@ -52,7 +55,7 @@ pub async fn add_history_item(
pool: tauri::State<'_, SqlitePool>,
item: HistoryItem,
) -> Result<(), String> {
let (id, content_type, content, favicon, timestamp) = item.to_row();
let (id, source, source_icon, content_type, content, favicon, timestamp) = item.to_row();
let last_content: Option<String> = sqlx::query_scalar(
"SELECT content FROM history WHERE content_type = ? ORDER BY timestamp DESC LIMIT 1",
@ -67,9 +70,11 @@ pub async fn add_history_item(
}
sqlx::query(
"INSERT INTO history (id, content_type, content, favicon, timestamp) VALUES (?, ?, ?, ?, ?)"
"INSERT INTO history (id, source, source_icon, content_type, content, favicon, timestamp) VALUES (?, ?, ?, ?, ?, ?, ?)"
)
.bind(id)
.bind(source)
.bind(source_icon)
.bind(content_type)
.bind(content)
.bind(favicon)
@ -88,7 +93,7 @@ pub async fn search_history(
) -> Result<Vec<HistoryItem>, String> {
let query = format!("%{}%", query);
let rows = sqlx::query(
"SELECT id, content_type, content, favicon, timestamp FROM history WHERE content LIKE ? ORDER BY timestamp DESC"
"SELECT id, source, source_icon, content_type, content, favicon, timestamp FROM history WHERE content LIKE ? ORDER BY timestamp DESC"
)
.bind(query)
.fetch_all(&*pool)
@ -99,6 +104,8 @@ pub async fn search_history(
.iter()
.map(|row| HistoryItem {
id: row.get("id"),
source: row.get("source"),
source_icon: row.get("source_icon"),
content_type: ContentType::from(row.get::<String, _>("content_type")),
content: row.get("content"),
favicon: row.get("favicon"),
@ -116,7 +123,7 @@ pub async fn load_history_chunk(
limit: i64,
) -> Result<Vec<HistoryItem>, String> {
let rows = sqlx::query(
"SELECT id, content_type, content, favicon, timestamp FROM history ORDER BY timestamp DESC LIMIT ? OFFSET ?"
"SELECT id, source, source_icon, content_type, content, favicon, timestamp FROM history ORDER BY timestamp DESC LIMIT ? OFFSET ?"
)
.bind(limit)
.bind(offset)
@ -128,6 +135,8 @@ pub async fn load_history_chunk(
.iter()
.map(|row| HistoryItem {
id: row.get("id"),
source: row.get("source"),
source_icon: row.get("source_icon"),
content_type: ContentType::from(row.get::<String, _>("content_type")),
content: row.get("content"),
favicon: row.get("favicon"),

View file

@ -1,12 +0,0 @@
CREATE TABLE IF NOT EXISTS settings (
key TEXT PRIMARY KEY,
value TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS history (
id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
content_type TEXT NOT NULL,
content TEXT NOT NULL,
favicon TEXT,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
);

View file

@ -6,9 +6,10 @@ use uuid::Uuid;
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
pub struct HistoryItem {
pub id: String,
pub source: String,
pub source_icon: Option<String>,
pub content_type: ContentType,
pub content: String,
#[serde(default)]
pub favicon: Option<String>,
pub timestamp: DateTime<Utc>,
}
@ -24,6 +25,61 @@ pub enum ContentType {
Code,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct Text {
pub source: String,
pub content_type: ContentType,
pub characters: i32,
pub words: i32,
pub copied: DateTime<Utc>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct Image {
pub source: String,
pub content_type: ContentType,
pub dimensions: String,
pub size: i64,
pub copied: DateTime<Utc>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct File {
pub source: String,
pub content_type: ContentType,
pub path: String,
pub filesize: i64,
pub copied: DateTime<Utc>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct Link {
pub source: String,
pub content_type: ContentType,
pub title: String,
pub link: String,
pub characters: i32,
pub copied: DateTime<Utc>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct Color {
pub source: String,
pub content_type: ContentType,
pub hexcode: String,
pub rgba: String,
pub copied: DateTime<Utc>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct Code {
pub source: String,
pub content_type: ContentType,
pub language: String,
pub lines: i32,
pub copied: DateTime<Utc>,
}
impl fmt::Display for ContentType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
@ -52,9 +108,11 @@ impl From<String> for ContentType {
}
impl HistoryItem {
pub fn new(content_type: ContentType, content: String, favicon: Option<String>) -> Self {
pub fn new(source: String, content_type: ContentType, content: String, favicon: Option<String>, source_icon: Option<String>) -> Self {
Self {
id: Uuid::new_v4().to_string(),
source,
source_icon,
content_type,
content,
favicon,
@ -62,9 +120,11 @@ impl HistoryItem {
}
}
pub fn to_row(&self) -> (String, String, String, Option<String>, DateTime<Utc>) {
pub fn to_row(&self) -> (String, String, Option<String>, String, String, Option<String>, DateTime<Utc>) {
(
self.id.clone(),
self.source.clone(),
self.source_icon.clone(),
self.content_type.to_string(),
self.content.clone(),
self.favicon.clone(),