mirror of
https://github.com/0PandaDEV/Qopy.git
synced 2025-04-21 13:14:04 +02:00
feat: add source and source_icon for all rows
This commit is contained in:
parent
8f0d53d355
commit
5c6853b02b
4 changed files with 86 additions and 26 deletions
|
@ -12,6 +12,7 @@ use regex::Regex;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use base64::{Engine, engine::general_purpose::STANDARD};
|
use base64::{Engine, engine::general_purpose::STANDARD};
|
||||||
|
|
||||||
|
use crate::utils::commands::get_app_info;
|
||||||
use crate::utils::favicon::fetch_favicon_as_base64;
|
use crate::utils::favicon::fetch_favicon_as_base64;
|
||||||
use crate::db;
|
use crate::db;
|
||||||
use crate::utils::types::{ContentType, HistoryItem};
|
use crate::utils::types::{ContentType, HistoryItem};
|
||||||
|
@ -97,6 +98,8 @@ pub fn setup<R: Runtime>(app: &AppHandle<R>) {
|
||||||
let clipboard = app.state::<Clipboard>();
|
let clipboard = app.state::<Clipboard>();
|
||||||
let available_types = clipboard.available_types().unwrap();
|
let available_types = clipboard.available_types().unwrap();
|
||||||
|
|
||||||
|
let (app_name, app_icon) = get_app_info();
|
||||||
|
|
||||||
match get_pool(&app).await {
|
match get_pool(&app).await {
|
||||||
Ok(pool) => {
|
Ok(pool) => {
|
||||||
if available_types.image {
|
if available_types.image {
|
||||||
|
@ -108,7 +111,7 @@ pub fn setup<R: Runtime>(app: &AppHandle<R>) {
|
||||||
.unwrap_or_else(|e| e);
|
.unwrap_or_else(|e| e);
|
||||||
let _ = db::history::add_history_item(
|
let _ = db::history::add_history_item(
|
||||||
pool,
|
pool,
|
||||||
HistoryItem::new(ContentType::Image, file_path, None),
|
HistoryItem::new(app_name, ContentType::Image, file_path, None, app_icon),
|
||||||
).await;
|
).await;
|
||||||
}
|
}
|
||||||
} else if available_types.files {
|
} else if available_types.files {
|
||||||
|
@ -117,7 +120,7 @@ pub fn setup<R: Runtime>(app: &AppHandle<R>) {
|
||||||
let files_str = files.join(", ");
|
let files_str = files.join(", ");
|
||||||
let _ = db::history::add_history_item(
|
let _ = db::history::add_history_item(
|
||||||
pool,
|
pool,
|
||||||
HistoryItem::new(ContentType::File, files_str, None),
|
HistoryItem::new(app_name, ContentType::File, files_str, None, app_icon),
|
||||||
).await;
|
).await;
|
||||||
}
|
}
|
||||||
} else if available_types.text {
|
} else if available_types.text {
|
||||||
|
@ -134,7 +137,7 @@ pub fn setup<R: Runtime>(app: &AppHandle<R>) {
|
||||||
|
|
||||||
let _ = db::history::add_history_item(
|
let _ = db::history::add_history_item(
|
||||||
pool,
|
pool,
|
||||||
HistoryItem::new(ContentType::Link, text, favicon)
|
HistoryItem::new(app_name, ContentType::Link, text, favicon, app_icon)
|
||||||
).await;
|
).await;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -143,7 +146,7 @@ pub fn setup<R: Runtime>(app: &AppHandle<R>) {
|
||||||
}
|
}
|
||||||
let _ = db::history::add_history_item(
|
let _ = db::history::add_history_item(
|
||||||
pool,
|
pool,
|
||||||
HistoryItem::new(ContentType::Text, text, None)
|
HistoryItem::new(app_name, ContentType::Text, text, None, app_icon)
|
||||||
).await;
|
).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,10 @@ pub async fn initialize_history(pool: &SqlitePool) -> Result<(), Box<dyn std::er
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
sqlx::query(
|
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(id)
|
||||||
|
.bind("System")
|
||||||
.bind("text")
|
.bind("text")
|
||||||
.bind("Welcome to your clipboard history!")
|
.bind("Welcome to your clipboard history!")
|
||||||
.execute(pool)
|
.execute(pool)
|
||||||
|
@ -27,7 +28,7 @@ pub async fn initialize_history(pool: &SqlitePool) -> Result<(), Box<dyn std::er
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn get_history(pool: tauri::State<'_, SqlitePool>) -> Result<Vec<HistoryItem>, String> {
|
pub async fn get_history(pool: tauri::State<'_, SqlitePool>) -> Result<Vec<HistoryItem>, String> {
|
||||||
let rows = sqlx::query(
|
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)
|
.fetch_all(&*pool)
|
||||||
.await
|
.await
|
||||||
|
@ -37,6 +38,8 @@ pub async fn get_history(pool: tauri::State<'_, SqlitePool>) -> Result<Vec<Histo
|
||||||
.iter()
|
.iter()
|
||||||
.map(|row| HistoryItem {
|
.map(|row| HistoryItem {
|
||||||
id: row.get("id"),
|
id: row.get("id"),
|
||||||
|
source: row.get("source"),
|
||||||
|
source_icon: row.get("source_icon"),
|
||||||
content_type: ContentType::from(row.get::<String, _>("content_type")),
|
content_type: ContentType::from(row.get::<String, _>("content_type")),
|
||||||
content: row.get("content"),
|
content: row.get("content"),
|
||||||
favicon: row.get("favicon"),
|
favicon: row.get("favicon"),
|
||||||
|
@ -52,7 +55,7 @@ pub async fn add_history_item(
|
||||||
pool: tauri::State<'_, SqlitePool>,
|
pool: tauri::State<'_, SqlitePool>,
|
||||||
item: HistoryItem,
|
item: HistoryItem,
|
||||||
) -> Result<(), String> {
|
) -> 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(
|
let last_content: Option<String> = sqlx::query_scalar(
|
||||||
"SELECT content FROM history WHERE content_type = ? ORDER BY timestamp DESC LIMIT 1",
|
"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(
|
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(id)
|
||||||
|
.bind(source)
|
||||||
|
.bind(source_icon)
|
||||||
.bind(content_type)
|
.bind(content_type)
|
||||||
.bind(content)
|
.bind(content)
|
||||||
.bind(favicon)
|
.bind(favicon)
|
||||||
|
@ -88,7 +93,7 @@ pub async fn search_history(
|
||||||
) -> Result<Vec<HistoryItem>, String> {
|
) -> Result<Vec<HistoryItem>, String> {
|
||||||
let query = format!("%{}%", query);
|
let query = format!("%{}%", query);
|
||||||
let rows = sqlx::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)
|
.bind(query)
|
||||||
.fetch_all(&*pool)
|
.fetch_all(&*pool)
|
||||||
|
@ -99,6 +104,8 @@ pub async fn search_history(
|
||||||
.iter()
|
.iter()
|
||||||
.map(|row| HistoryItem {
|
.map(|row| HistoryItem {
|
||||||
id: row.get("id"),
|
id: row.get("id"),
|
||||||
|
source: row.get("source"),
|
||||||
|
source_icon: row.get("source_icon"),
|
||||||
content_type: ContentType::from(row.get::<String, _>("content_type")),
|
content_type: ContentType::from(row.get::<String, _>("content_type")),
|
||||||
content: row.get("content"),
|
content: row.get("content"),
|
||||||
favicon: row.get("favicon"),
|
favicon: row.get("favicon"),
|
||||||
|
@ -116,7 +123,7 @@ pub async fn load_history_chunk(
|
||||||
limit: i64,
|
limit: i64,
|
||||||
) -> Result<Vec<HistoryItem>, String> {
|
) -> Result<Vec<HistoryItem>, String> {
|
||||||
let rows = sqlx::query(
|
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(limit)
|
||||||
.bind(offset)
|
.bind(offset)
|
||||||
|
@ -128,6 +135,8 @@ pub async fn load_history_chunk(
|
||||||
.iter()
|
.iter()
|
||||||
.map(|row| HistoryItem {
|
.map(|row| HistoryItem {
|
||||||
id: row.get("id"),
|
id: row.get("id"),
|
||||||
|
source: row.get("source"),
|
||||||
|
source_icon: row.get("source_icon"),
|
||||||
content_type: ContentType::from(row.get::<String, _>("content_type")),
|
content_type: ContentType::from(row.get::<String, _>("content_type")),
|
||||||
content: row.get("content"),
|
content: row.get("content"),
|
||||||
favicon: row.get("favicon"),
|
favicon: row.get("favicon"),
|
||||||
|
|
|
@ -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
|
|
||||||
);
|
|
|
@ -6,9 +6,10 @@ use uuid::Uuid;
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
|
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
|
||||||
pub struct HistoryItem {
|
pub struct HistoryItem {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
|
pub source: String,
|
||||||
|
pub source_icon: Option<String>,
|
||||||
pub content_type: ContentType,
|
pub content_type: ContentType,
|
||||||
pub content: String,
|
pub content: String,
|
||||||
#[serde(default)]
|
|
||||||
pub favicon: Option<String>,
|
pub favicon: Option<String>,
|
||||||
pub timestamp: DateTime<Utc>,
|
pub timestamp: DateTime<Utc>,
|
||||||
}
|
}
|
||||||
|
@ -24,6 +25,61 @@ pub enum ContentType {
|
||||||
Code,
|
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 {
|
impl fmt::Display for ContentType {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
@ -52,9 +108,11 @@ impl From<String> for ContentType {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HistoryItem {
|
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 {
|
Self {
|
||||||
id: Uuid::new_v4().to_string(),
|
id: Uuid::new_v4().to_string(),
|
||||||
|
source,
|
||||||
|
source_icon,
|
||||||
content_type,
|
content_type,
|
||||||
content,
|
content,
|
||||||
favicon,
|
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.id.clone(),
|
||||||
|
self.source.clone(),
|
||||||
|
self.source_icon.clone(),
|
||||||
self.content_type.to_string(),
|
self.content_type.to_string(),
|
||||||
self.content.clone(),
|
self.content.clone(),
|
||||||
self.favicon.clone(),
|
self.favicon.clone(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue