refactor: fix casing and spacing in settings.scss

refactor: improve keybind saving logic and error handling
fix: update keybind references to settings in app and tray setup
fix: back button not working on settings
This commit is contained in:
PandaDEV 2025-01-02 14:54:42 +10:00
parent b328b8fa9c
commit 25f7b116f6
No known key found for this signature in database
GPG key ID: 13EFF9BAF70EE75C
3 changed files with 237 additions and 74 deletions

33
app.vue
View file

@ -1,25 +1,28 @@
<template>
<div style="pointer-events: auto;">
<div style="pointer-events: auto">
<NuxtPage />
</div>
</template>
<script setup lang="ts">
import { listen } from '@tauri-apps/api/event'
import { app, window } from '@tauri-apps/api';
import { onMounted } from 'vue'
import { listen } from "@tauri-apps/api/event";
import { app, window } from "@tauri-apps/api";
import { onMounted } from "vue";
const keyboard = useKeyboard();
onMounted(async () => {
await listen('settings', async () => {
await navigateTo('/settings')
await listen("settings", async () => {
keyboard.unregisterAll();
await navigateTo("/settings");
await app.show();
await window.getCurrentWindow().show();
})
});
await listen('main_route', async () => {
await navigateTo('/')
})
})
await listen("main_route", async () => {
await navigateTo("/");
});
});
</script>
<style lang="scss">
@ -51,7 +54,7 @@ onMounted(async () => {
margin: 0;
padding: 0;
box-sizing: border-box;
color: #E5DFD5;
color: #e5dfd5;
text-decoration: none;
font-family: SFRoundedRegular;
scroll-behavior: smooth;
@ -60,9 +63,9 @@ onMounted(async () => {
position: relative;
z-index: 1;
--os-handle-bg: #ADA9A1;
--os-handle-bg-hover: #78756F;
--os-handle-bg-active: #78756F;
--os-handle-bg: #ada9a1;
--os-handle-bg-hover: #78756f;
--os-handle-bg-active: #78756f;
}
html,

View file

@ -65,10 +65,17 @@
</template>
<template v-else-if="hasFavicon(item.favicon ?? '')">
<img
:src="item.favicon ? getFaviconFromDb(item.favicon) : '../public/icons/Link.svg'"
:src="
item.favicon
? getFaviconFromDb(item.favicon)
: '../public/icons/Link.svg'
"
alt="Favicon"
class="favicon"
@error="($event.target as HTMLImageElement).src = '../public/icons/Link.svg'" />
@error="
($event.target as HTMLImageElement).src =
'../public/icons/Link.svg'
" />
</template>
<img
src="../public/icons/File.svg"
@ -121,8 +128,12 @@
:src="getYoutubeThumbnail(selectedItem.content)"
alt="YouTube Thumbnail" />
</div>
<div class="content" v-else-if="selectedItem?.content_type === ContentType.Link && pageOgImage">
<img :src="pageOgImage" alt="Image" class="image">
<div
class="content"
v-else-if="
selectedItem?.content_type === ContentType.Link && pageOgImage
">
<img :src="pageOgImage" alt="Image" class="image" />
</div>
<OverlayScrollbarsComponent v-else class="content">
<span>{{ selectedItem?.content || "" }}</span>
@ -135,9 +146,7 @@
<div class="info-content" v-if="selectedItem && getInfo">
<div class="info-row" v-for="(row, index) in infoRows" :key="index">
<p class="label">{{ row.label }}</p>
<span
:class="{ 'url-truncate': row.isUrl }"
:data-text="row.value">
<span :class="{ 'url-truncate': row.isUrl }" :data-text="row.value">
{{ row.value }}
</span>
</div>
@ -158,7 +167,15 @@ import { listen } from "@tauri-apps/api/event";
import { useNuxtApp } from "#app";
import { invoke } from "@tauri-apps/api/core";
import { HistoryItem, ContentType } from "~/types/types";
import type { InfoText, InfoImage, InfoFile, InfoLink, InfoColor, InfoCode } from "~/types/types";
import type {
InfoText,
InfoImage,
InfoFile,
InfoLink,
InfoColor,
InfoCode,
} from "~/types/types";
import { Key } from "wrdu-keyboard/key";
interface GroupedHistory {
label: string;
@ -188,8 +205,8 @@ const imageSizes = shallowRef<Record<string, string>>({});
const lastUpdateTime = ref<number>(Date.now());
const imageLoadError = ref<boolean>(false);
const imageLoading = ref<boolean>(false);
const pageTitle = ref<string>('');
const pageOgImage = ref<string>('');
const pageTitle = ref<string>("");
const pageOgImage = ref<string>("");
const keyboard = useKeyboard();
@ -583,41 +600,35 @@ const setupEventListeners = async (): Promise<void> => {
searchInput.value?.blur();
});
keyboard.down("ArrowDown", (event) => {
event.preventDefault();
keyboard.prevent.down([Key.DownArrow], (event) => {
selectNext();
});
keyboard.down("ArrowUp", (event) => {
event.preventDefault();
keyboard.prevent.down([Key.UpArrow], (event) => {
selectPrevious();
});
keyboard.down("Enter", (event) => {
event.preventDefault();
keyboard.prevent.down([Key.Enter], (event) => {
pasteSelectedItem();
});
keyboard.down("Escape", (event) => {
event.preventDefault();
keyboard.prevent.down([Key.Escape], (event) => {
hideApp();
});
keyboard.down("all", (event) => {
const isMacActionCombo =
os.value === "macos" &&
(event.code === "MetaLeft" || event.code === "MetaRight") &&
event.key === "k";
switch (os.value) {
case "macos":
keyboard.prevent.down([Key.LeftMeta, Key.K], (event) => {});
const isOtherOsActionCombo =
os.value !== "macos" &&
(event.code === "ControlLeft" || event.code === "ControlRight") &&
event.key === "k";
keyboard.prevent.down([Key.RightMeta, Key.K], (event) => {});
break;
if (isMacActionCombo || isOtherOsActionCombo) {
event.preventDefault();
}
});
case "linux" || "windows":
keyboard.prevent.down([Key.LeftControl, Key.K], (event) => {});
keyboard.prevent.down([Key.RightControl, Key.K], (event) => {});
break;
}
};
const hideApp = async (): Promise<void> => {
@ -646,7 +657,7 @@ watch(searchQuery, () => {
onMounted(async () => {
try {
os.value = await platform();
os.value = platform();
await loadHistoryChunk();
resultsContainer.value
@ -686,27 +697,33 @@ const formatFileSize = (bytes: number): string => {
const fetchPageMeta = async (url: string) => {
try {
const [title, ogImage] = await invoke('fetch_page_meta', { url }) as [string, string | null];
const [title, ogImage] = (await invoke("fetch_page_meta", { url })) as [
string,
string | null
];
pageTitle.value = title;
if (ogImage) {
pageOgImage.value = ogImage;
}
} catch (error) {
console.error('Error fetching page meta:', error);
pageTitle.value = 'Error loading title';
console.error("Error fetching page meta:", error);
pageTitle.value = "Error loading title";
}
};
watch(() => selectedItem.value, (newItem) => {
if (newItem?.content_type === ContentType.Link) {
pageTitle.value = 'Loading...';
pageOgImage.value = '';
fetchPageMeta(newItem.content);
} else {
pageTitle.value = '';
pageOgImage.value = '';
watch(
() => selectedItem.value,
(newItem) => {
if (newItem?.content_type === ContentType.Link) {
pageTitle.value = "Loading...";
pageOgImage.value = "";
fetchPageMeta(newItem.content);
} else {
pageTitle.value = "";
pageOgImage.value = "";
}
}
});
);
const getInfo = computed(() => {
if (!selectedItem.value) return null;
@ -716,7 +733,10 @@ const getInfo = computed(() => {
copied: selectedItem.value.timestamp,
};
const infoMap: Record<ContentType, () => InfoText | InfoImage | InfoFile | InfoLink | InfoColor | InfoCode> = {
const infoMap: Record<
ContentType,
() => InfoText | InfoImage | InfoFile | InfoLink | InfoColor | InfoCode
> = {
[ContentType.Text]: () => ({
...baseInfo,
content_type: ContentType.Text,
@ -754,7 +774,8 @@ const getInfo = computed(() => {
const max = Math.max(rNorm, gNorm, bNorm);
const min = Math.min(rNorm, gNorm, bNorm);
let h = 0, s = 0;
let h = 0,
s = 0;
const l = (max + min) / 2;
if (max !== min) {
@ -780,14 +801,16 @@ const getInfo = computed(() => {
content_type: ContentType.Color,
hex: hex,
rgb: `rgb(${r}, ${g}, ${b})`,
hsl: `hsl(${Math.round(h * 360)}, ${Math.round(s * 100)}%, ${Math.round(l * 100)}%)`,
hsl: `hsl(${Math.round(h * 360)}, ${Math.round(s * 100)}%, ${Math.round(
l * 100
)}%)`,
};
},
[ContentType.Code]: () => ({
...baseInfo,
content_type: ContentType.Code,
language: selectedItem.value!.language ?? "Unknown",
lines: selectedItem.value!.content.split('\n').length,
lines: selectedItem.value!.content.split("\n").length,
}),
};
@ -799,24 +822,37 @@ const infoRows = computed(() => {
const commonRows = [
{ label: "Source", value: getInfo.value.source, isUrl: false },
{ label: "Content Type", value: getInfo.value.content_type.charAt(0).toUpperCase() + getInfo.value.content_type.slice(1), isUrl: false },
{
label: "Content Type",
value:
getInfo.value.content_type.charAt(0).toUpperCase() +
getInfo.value.content_type.slice(1),
isUrl: false,
},
];
const typeSpecificRows: Record<ContentType, Array<{ label: string; value: string | number; isUrl?: boolean }>> = {
const typeSpecificRows: Record<
ContentType,
Array<{ label: string; value: string | number; isUrl?: boolean }>
> = {
[ContentType.Text]: [
{ label: "Characters", value: (getInfo.value as InfoText).characters },
{ label: "Words", value: (getInfo.value as InfoText).words },
],
[ContentType.Image]: [
{ label: "Dimensions", value: (getInfo.value as InfoImage).dimensions },
{ label: "Image size", value: formatFileSize((getInfo.value as InfoImage).size) },
{
label: "Image size",
value: formatFileSize((getInfo.value as InfoImage).size),
},
],
[ContentType.File]: [
{ label: "Path", value: (getInfo.value as InfoFile).path },
],
[ContentType.Link]: [
...((getInfo.value as InfoLink).title && (getInfo.value as InfoLink).title !== 'Loading...'
? [{ label: "Title", value: (getInfo.value as InfoLink).title || '' }]
...((getInfo.value as InfoLink).title &&
(getInfo.value as InfoLink).title !== "Loading..."
? [{ label: "Title", value: (getInfo.value as InfoLink).title || "" }]
: []),
{ label: "URL", value: (getInfo.value as InfoLink).url, isUrl: true },
{ label: "Characters", value: (getInfo.value as InfoLink).characters },
@ -832,8 +868,9 @@ const infoRows = computed(() => {
],
};
const specificRows = typeSpecificRows[getInfo.value.content_type]
.filter(row => row.value !== "");
const specificRows = typeSpecificRows[getInfo.value.content_type].filter(
(row) => row.value !== ""
);
return [
...commonRows,

View file

@ -0,0 +1,123 @@
diff --git a/node_modules/wrdu-keyboard/.DS_Store b/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..fabbd951c2d14c46fd10fa167b8836d116bc0db6
Binary files /dev/null and b/.DS_Store differ
diff --git a/dist/runtime/keyboard.d.ts b/dist/runtime/keyboard.d.ts
index aeae40f3d2bc3efd459cce04c29c21c43884154d..6131bab4895ebb3048a5225f366430d23c5f1f13 100644
--- a/dist/runtime/keyboard.d.ts
+++ b/dist/runtime/keyboard.d.ts
@@ -1,15 +1,16 @@
-import { Key } from './types/keys.js';
-import { type Plugin } from '#app';
+import { Key } from "./types/keys.js";
+import { type Plugin } from "#app";
type Handler = (event: KeyboardEvent) => void;
type Config = {
once?: boolean;
prevent?: boolean;
};
-type PublicConfig = Omit<Config, 'prevent'>;
+type PublicConfig = Omit<Config, "prevent">;
type New = (keys: Key[], handler: Handler, config?: PublicConfig) => void;
export interface Keyboard {
init: () => void;
stop: () => void;
+ unregisterAll: () => void;
down: New;
up: New;
prevent: {
diff --git a/dist/runtime/keyboard.js b/dist/runtime/keyboard.js
index e16f600258cee90d185ffc52777bed95c14bd93e..e4ce2678db649ec82e5a67fcdb74f5cdb37820aa 100644
--- a/dist/runtime/keyboard.js
+++ b/dist/runtime/keyboard.js
@@ -1,13 +1,14 @@
import { Key } from "./types/keys.js";
import { defineNuxtPlugin } from "#app";
-const getKeyString = (keys) => keys[0] == Key.All ? keys.sort().join("+") : "All";
+const getKeyString = (keys) => keys.includes(Key.All) ? "All" : keys.sort().join("+");
const handlers = {
down: {},
up: {}
};
const pressedKeys = /* @__PURE__ */ new Set();
const onKeydown = (event) => {
- pressedKeys.add(event.code);
+ const key = event.code;
+ pressedKeys.add(key);
const pressedArray = Array.from(pressedKeys);
const keyString = getKeyString(pressedArray);
if (handlers.down[keyString]) {
@@ -17,13 +18,16 @@ const onKeydown = (event) => {
}
eventHandler.handler(event);
if (eventHandler.once) {
- handlers.down[keyString] = handlers.down[keyString].filter((h) => h !== eventHandler);
+ handlers.down[keyString] = handlers.down[keyString].filter(
+ (h) => h !== eventHandler
+ );
}
});
}
};
const onKeyup = (event) => {
- pressedKeys.delete(event.code);
+ const key = event.code;
+ pressedKeys.delete(key);
const releasedArray = Array.from(pressedKeys);
const keyString = getKeyString(releasedArray);
if (handlers.up[keyString]) {
@@ -33,13 +37,16 @@ const onKeyup = (event) => {
}
eventHandler.handler(event);
if (eventHandler.once) {
- handlers.up[keyString] = handlers.up[keyString].filter((h) => h !== eventHandler);
+ handlers.up[keyString] = handlers.up[keyString].filter(
+ (h) => h !== eventHandler
+ );
}
});
}
};
const init = () => {
stop();
+ pressedKeys.clear();
window.addEventListener("keydown", onKeydown);
window.addEventListener("keyup", onKeyup);
};
@@ -47,6 +54,20 @@ const stop = () => {
window.removeEventListener("keydown", onKeydown);
window.removeEventListener("keyup", onKeyup);
};
+const unregisterAll = () => {
+ Object.keys(handlers.down).forEach((key) => {
+ handlers.down[key].forEach((handler) => {
+ console.log(`Unregistering ${key} ${handler.handler.toString()}`);
+ });
+ });
+ Object.keys(handlers.up).forEach((key) => {
+ handlers.up[key].forEach((handler) => {
+ console.log(`Unregistering ${key} ${handler.handler.toString()}`);
+ });
+ });
+ handlers.down = {};
+ handlers.up = {};
+};
const down = (keys, handler, config = {}) => {
if (keys.includes(Key.All)) {
keys = [Key.All];
@@ -59,6 +80,7 @@ const down = (keys, handler, config = {}) => {
handlers.down[key] = [];
}
const { once = false, prevent = false } = config;
+ console.log(key, handler.toString());
handlers.down[key].push({ handler, prevent, once });
};
const up = (keys, handler, config = {}) => {
@@ -84,6 +106,7 @@ const keyboard = defineNuxtPlugin((nuxtApp) => {
keyboard: {
init,
stop,
+ unregisterAll,
down: (keys, handler, config = {}) => down(keys, handler, config),
up: (keys, handler, config = {}) => up(keys, handler, config),
prevent: {