diff --git a/pages/index.vue b/pages/index.vue
index 4d7be6a..0426d08 100644
--- a/pages/index.vue
+++ b/pages/index.vue
@@ -63,11 +63,13 @@
@error="onImageError" />
-
+
+
+
+
-
Color
-
+
Hex Code
+
{{ selectedItem.content }}
-
Value
-
{{ selectedItem.content }}
+
RGB
+
{{
+ selectedItem.content.startsWith("#")
+ ? `rgb(${parseInt(
+ selectedItem.content.slice(1, 3),
+ 16
+ )}, ${parseInt(
+ selectedItem.content.slice(3, 5),
+ 16
+ )}, ${parseInt(selectedItem.content.slice(5, 7), 16)})`
+ : selectedItem.content
+ }}
+
+
+
HSL
+
{{
+ selectedItem.content.startsWith("#")
+ ? (() => {
+ const r =
+ parseInt(selectedItem.content.slice(1, 3), 16) / 255;
+ const g =
+ parseInt(selectedItem.content.slice(3, 5), 16) / 255;
+ const b =
+ parseInt(selectedItem.content.slice(5, 7), 16) / 255;
+ const max = Math.max(r, g, b);
+ const min = Math.min(r, g, b);
+ const l = (max + min) / 2;
+ const d = max - min;
+ const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+ let h = 0;
+ if (max === r) h = (g - b) / d + (g < b ? 6 : 0);
+ if (max === g) h = (b - r) / d + 2;
+ if (max === b) h = (r - g) / d + 4;
+ h = Math.round(h * 60);
+ return `hsl(${h}, ${Math.round(s * 100)}%, ${Math.round(
+ l * 100
+ )}%)`;
+ })()
+ : selectedItem.content
+ }}
@@ -600,10 +656,7 @@ const setupEventListeners = async (): Promise => {
await listen("clipboard-content-updated", async () => {
lastUpdateTime.value = Date.now();
await updateHistory(true);
- if (
- groupedHistory.value.length > 0 &&
- groupedHistory.value[0].items.length > 0
- ) {
+ if (groupedHistory.value[0]?.items.length > 0) {
handleSelection(0, 0, false);
}
});
@@ -623,17 +676,12 @@ const setupEventListeners = async (): Promise => {
lastUpdateTime.value = currentTime;
handleSelection(previousState.groupIndex, previousState.itemIndex, false);
- nextTick(() => {
- const viewport = resultsContainer.value
- ?.osInstance()
- ?.elements().viewport;
- if (viewport) {
- viewport.scrollTo({
- top: previousState.scroll,
- behavior: "instant",
- });
- }
- });
+ if (resultsContainer.value?.osInstance()?.elements().viewport?.scrollTo) {
+ resultsContainer.value.osInstance()?.elements().viewport?.scrollTo({
+ top: previousState.scroll,
+ behavior: "instant",
+ });
+ }
}
focusSearchInput();
});
@@ -749,7 +797,7 @@ const getFormattedDate = computed(() => {
if (!selectedItem.value?.timestamp) return "";
return new Intl.DateTimeFormat("en-US", {
dateStyle: "medium",
- timeStyle: "short",
+ timeStyle: "medium",
}).format(selectedItem.value.timestamp);
});
diff --git a/src-tauri/src/api/clipboard.rs b/src-tauri/src/api/clipboard.rs
index 927b70e..405ee12 100644
--- a/src-tauri/src/api/clipboard.rs
+++ b/src-tauri/src/api/clipboard.rs
@@ -164,6 +164,11 @@ pub fn setup(app: &AppHandle) {
pool,
HistoryItem::new(app_name, ContentType::Code, text, None, app_icon, Some(language))
).await;
+ } else if crate::utils::commands::detect_color(&text) {
+ let _ = db::history::add_history_item(
+ pool,
+ HistoryItem::new(app_name, ContentType::Color, text, None, app_icon, None)
+ ).await;
} else {
let _ = db::history::add_history_item(
pool,
diff --git a/src-tauri/src/utils/commands.rs b/src-tauri/src/utils/commands.rs
index 13a5d04..6ffa6c9 100644
--- a/src-tauri/src/utils/commands.rs
+++ b/src-tauri/src/utils/commands.rs
@@ -49,3 +49,49 @@ fn _process_icon_to_base64(path: &str) -> Result bool {
+ let color = color.trim().to_lowercase();
+
+ // hex
+ if color.starts_with('#') && color.len() == color.trim_end_matches(char::is_whitespace).len() {
+ let hex = &color[1..];
+ return match hex.len() {
+ 3 | 6 | 8 => hex.chars().all(|c| c.is_ascii_hexdigit()),
+ _ => false
+ };
+ }
+
+ // rgb/rgba
+ if (color.starts_with("rgb(") || color.starts_with("rgba(")) && color.ends_with(")") && !color[..color.len()-1].contains(")") {
+ let values = color
+ .trim_start_matches("rgba(")
+ .trim_start_matches("rgb(")
+ .trim_end_matches(')')
+ .split(',')
+ .collect::>();
+
+ return match values.len() {
+ 3 | 4 => values.iter().all(|v| v.trim().parse::().is_ok()),
+ _ => false
+ };
+ }
+
+ // hsl/hsla
+ if (color.starts_with("hsl(") || color.starts_with("hsla(")) && color.ends_with(")") && !color[..color.len()-1].contains(")") {
+ let values = color
+ .trim_start_matches("hsla(")
+ .trim_start_matches("hsl(")
+ .trim_end_matches(')')
+ .split(',')
+ .collect::>();
+
+ return match values.len() {
+ 3 | 4 => values.iter().all(|v| v.trim().parse::().is_ok()),
+ _ => false
+ };
+ }
+
+ false
+}
\ No newline at end of file