mirror of
https://github.com/0PandaDEV/Qopy.git
synced 2025-04-21 13:14:04 +02:00
feat: use wrdu-keyboard
This commit is contained in:
parent
5c6853b02b
commit
c078b631f6
5 changed files with 173 additions and 86 deletions
2
app.vue
2
app.vue
|
@ -12,7 +12,7 @@ import { onMounted } from 'vue'
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await listen('change_keybind', async () => {
|
await listen('change_keybind', async () => {
|
||||||
console.log("change_keybind");
|
console.log("change_keybind");
|
||||||
await navigateTo('/keybind')
|
await navigateTo('/settings')
|
||||||
await app.show();
|
await app.show();
|
||||||
await window.getCurrentWindow().show();
|
await window.getCurrentWindow().show();
|
||||||
})
|
})
|
||||||
|
|
|
@ -99,7 +99,7 @@ $mutedtext: #78756f;
|
||||||
top: 53px;
|
top: 53px;
|
||||||
left: 284px;
|
left: 284px;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
height: calc(100vh - 96px);
|
height: calc(100vh - 256px);
|
||||||
font-family: CommitMono Nerd Font !important;
|
font-family: CommitMono Nerd Font !important;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
letter-spacing: 1;
|
letter-spacing: 1;
|
||||||
|
@ -210,6 +210,23 @@ $mutedtext: #78756f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.information {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 40px;
|
||||||
|
left: 284px;
|
||||||
|
height: 160px;
|
||||||
|
width: calc(100vw - 286px);
|
||||||
|
border-top: 1px solid $divider;
|
||||||
|
background-color: $primary;
|
||||||
|
padding: 14px;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-family: SFRoundedSemiBold;
|
||||||
|
font-size: 12px;
|
||||||
|
letter-spacing: 0.6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.clothoid-corner {
|
.clothoid-corner {
|
||||||
clip-path: polygon(
|
clip-path: polygon(
|
||||||
13.890123px 0px,
|
13.890123px 0px,
|
||||||
|
|
170
pages/index.vue
170
pages/index.vue
|
@ -1,11 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div class="bg" tabindex="0">
|
||||||
class="bg"
|
|
||||||
@keydown.down.prevent="selectNext"
|
|
||||||
@keydown.up.prevent="selectPrevious"
|
|
||||||
@keydown.enter.prevent="pasteSelectedItem"
|
|
||||||
@keydown.esc="hideApp"
|
|
||||||
tabindex="0">
|
|
||||||
<input
|
<input
|
||||||
ref="searchInput"
|
ref="searchInput"
|
||||||
v-model="searchQuery"
|
v-model="searchQuery"
|
||||||
|
@ -55,7 +49,7 @@
|
||||||
]"
|
]"
|
||||||
@click="selectItem(groupIndex, index)"
|
@click="selectItem(groupIndex, index)"
|
||||||
:ref="
|
:ref="
|
||||||
(el) => {
|
(el: any) => {
|
||||||
if (isSelected(groupIndex, index))
|
if (isSelected(groupIndex, index))
|
||||||
selectedElement = el as HTMLElement;
|
selectedElement = el as HTMLElement;
|
||||||
}
|
}
|
||||||
|
@ -67,10 +61,7 @@
|
||||||
alt="Image"
|
alt="Image"
|
||||||
class="image"
|
class="image"
|
||||||
@error="onImageError" />
|
@error="onImageError" />
|
||||||
<img
|
<img v-else src="../public/icons/Image.svg" class="icon" />
|
||||||
v-else
|
|
||||||
src="../public/icons/Image.svg"
|
|
||||||
class="icon" />
|
|
||||||
</template>
|
</template>
|
||||||
<img
|
<img
|
||||||
v-else-if="hasFavicon(item.favicon ?? '')"
|
v-else-if="hasFavicon(item.favicon ?? '')"
|
||||||
|
@ -90,7 +81,7 @@
|
||||||
class="icon"
|
class="icon"
|
||||||
v-else-if="item.content_type === ContentType.Code" />
|
v-else-if="item.content_type === ContentType.Code" />
|
||||||
<span v-if="item.content_type === ContentType.Image">
|
<span v-if="item.content_type === ContentType.Image">
|
||||||
Image ({{ imageDimensions[item.id] || 'Loading...' }})
|
Image ({{ imageDimensions[item.id] || "Loading..." }})
|
||||||
</span>
|
</span>
|
||||||
<span v-else>{{ truncateContent(item.content) }}</span>
|
<span v-else>{{ truncateContent(item.content) }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -107,6 +98,9 @@
|
||||||
class="full-image" />
|
class="full-image" />
|
||||||
<span v-else>{{ selectedItem?.content || "" }}</span>
|
<span v-else>{{ selectedItem?.content || "" }}</span>
|
||||||
</OverlayScrollbarsComponent>
|
</OverlayScrollbarsComponent>
|
||||||
|
<div class="information">
|
||||||
|
<div class="title">Information</div>
|
||||||
|
</div>
|
||||||
<Noise />
|
<Noise />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -136,7 +130,9 @@ const history = shallowRef<HistoryItem[]>([]);
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
let isLoading = false;
|
let isLoading = false;
|
||||||
|
|
||||||
const resultsContainer = shallowRef<InstanceType<typeof OverlayScrollbarsComponent> | null>(null);
|
const resultsContainer = shallowRef<InstanceType<
|
||||||
|
typeof OverlayScrollbarsComponent
|
||||||
|
> | null>(null);
|
||||||
const searchQuery = ref("");
|
const searchQuery = ref("");
|
||||||
const selectedGroupIndex = ref(0);
|
const selectedGroupIndex = ref(0);
|
||||||
const selectedItemIndex = ref(0);
|
const selectedItemIndex = ref(0);
|
||||||
|
@ -149,15 +145,24 @@ const lastUpdateTime = ref<number>(Date.now());
|
||||||
const imageLoadError = ref<boolean>(false);
|
const imageLoadError = ref<boolean>(false);
|
||||||
const imageLoading = ref<boolean>(false);
|
const imageLoading = ref<boolean>(false);
|
||||||
|
|
||||||
|
const keyboard = useKeyboard();
|
||||||
|
|
||||||
const isSameDay = (date1: Date, date2: Date): boolean => {
|
const isSameDay = (date1: Date, date2: Date): boolean => {
|
||||||
return date1.getFullYear() === date2.getFullYear()
|
return (
|
||||||
&& date1.getMonth() === date2.getMonth()
|
date1.getFullYear() === date2.getFullYear() &&
|
||||||
&& date1.getDate() === date2.getDate();
|
date1.getMonth() === date2.getMonth() &&
|
||||||
|
date1.getDate() === date2.getDate()
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getWeekNumber = (date: Date): number => {
|
const getWeekNumber = (date: Date): number => {
|
||||||
const firstDayOfYear = new Date(date.getFullYear(), 0, 1);
|
const firstDayOfYear = new Date(date.getFullYear(), 0, 1);
|
||||||
return Math.ceil(((date.getTime() - firstDayOfYear.getTime()) / 86400000 + firstDayOfYear.getDay() + 1) / 7);
|
return Math.ceil(
|
||||||
|
((date.getTime() - firstDayOfYear.getTime()) / 86400000 +
|
||||||
|
firstDayOfYear.getDay() +
|
||||||
|
1) /
|
||||||
|
7
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const groupedHistory = computed<GroupedHistory[]>(() => {
|
const groupedHistory = computed<GroupedHistory[]>(() => {
|
||||||
|
@ -169,30 +174,33 @@ const groupedHistory = computed<GroupedHistory[]>(() => {
|
||||||
const groups: Record<string, HistoryItem[]> = {
|
const groups: Record<string, HistoryItem[]> = {
|
||||||
Today: [],
|
Today: [],
|
||||||
Yesterday: [],
|
Yesterday: [],
|
||||||
'This Week': [],
|
"This Week": [],
|
||||||
'Last Week': [],
|
"Last Week": [],
|
||||||
'This Year': [],
|
"This Year": [],
|
||||||
'Last Year': []
|
"Last Year": [],
|
||||||
};
|
};
|
||||||
|
|
||||||
const filteredItems = searchQuery.value
|
const filteredItems = searchQuery.value
|
||||||
? history.value.filter(item =>
|
? history.value.filter((item) =>
|
||||||
item.content.toLowerCase().includes(searchQuery.value.toLowerCase()))
|
item.content.toLowerCase().includes(searchQuery.value.toLowerCase())
|
||||||
|
)
|
||||||
: history.value;
|
: history.value;
|
||||||
|
|
||||||
const yesterday = new Date(today.getTime() - 86400000);
|
const yesterday = new Date(today.getTime() - 86400000);
|
||||||
|
|
||||||
filteredItems.forEach(item => {
|
filteredItems.forEach((item) => {
|
||||||
const itemDate = new Date(item.timestamp);
|
const itemDate = new Date(item.timestamp);
|
||||||
const itemWeek = getWeekNumber(itemDate);
|
const itemWeek = getWeekNumber(itemDate);
|
||||||
const itemYear = itemDate.getFullYear();
|
const itemYear = itemDate.getFullYear();
|
||||||
|
|
||||||
if (isSameDay(itemDate, today)) groups.Today.push(item);
|
if (isSameDay(itemDate, today)) groups.Today.push(item);
|
||||||
else if (isSameDay(itemDate, yesterday)) groups.Yesterday.push(item);
|
else if (isSameDay(itemDate, yesterday)) groups.Yesterday.push(item);
|
||||||
else if (itemYear === thisYear && itemWeek === thisWeek) groups['This Week'].push(item);
|
else if (itemYear === thisYear && itemWeek === thisWeek)
|
||||||
else if (itemYear === thisYear && itemWeek === thisWeek - 1) groups['Last Week'].push(item);
|
groups["This Week"].push(item);
|
||||||
else if (itemYear === thisYear) groups['This Year'].push(item);
|
else if (itemYear === thisYear && itemWeek === thisWeek - 1)
|
||||||
else groups['Last Year'].push(item);
|
groups["Last Week"].push(item);
|
||||||
|
else if (itemYear === thisYear) groups["This Year"].push(item);
|
||||||
|
else groups["Last Year"].push(item);
|
||||||
});
|
});
|
||||||
|
|
||||||
return Object.entries(groups)
|
return Object.entries(groups)
|
||||||
|
@ -217,21 +225,22 @@ const loadHistoryChunk = async (): Promise<void> => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const processedItems = await Promise.all(
|
const processedItems = await Promise.all(
|
||||||
results.map(async item => {
|
results.map(async (item) => {
|
||||||
const historyItem = new HistoryItem(
|
const historyItem = new HistoryItem(
|
||||||
item.content_type as ContentType,
|
item.source,
|
||||||
|
item.content_type,
|
||||||
item.content,
|
item.content,
|
||||||
item.favicon
|
item.favicon
|
||||||
);
|
);
|
||||||
Object.assign(historyItem, {
|
Object.assign(historyItem, {
|
||||||
id: item.id,
|
id: item.id,
|
||||||
timestamp: new Date(item.timestamp)
|
timestamp: new Date(item.timestamp),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (historyItem.content_type === ContentType.Image) {
|
if (historyItem.content_type === ContentType.Image) {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
getItemDimensions(historyItem),
|
getItemDimensions(historyItem),
|
||||||
loadImageUrl(historyItem)
|
loadImageUrl(historyItem),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
return historyItem;
|
return historyItem;
|
||||||
|
@ -290,10 +299,17 @@ const isSelected = (groupIndex: number, itemIndex: number): boolean => {
|
||||||
|
|
||||||
const searchHistory = async (): Promise<void> => {
|
const searchHistory = async (): Promise<void> => {
|
||||||
const results = await $history.searchHistory(searchQuery.value);
|
const results = await $history.searchHistory(searchQuery.value);
|
||||||
history.value = results.map(item => Object.assign(
|
history.value = results.map((item) =>
|
||||||
new HistoryItem(item.content_type as ContentType, item.content, item.favicon),
|
Object.assign(
|
||||||
|
new HistoryItem(
|
||||||
|
item.source,
|
||||||
|
item.content_type,
|
||||||
|
item.content,
|
||||||
|
item.favicon
|
||||||
|
),
|
||||||
{ id: item.id, timestamp: new Date(item.timestamp) }
|
{ id: item.id, timestamp: new Date(item.timestamp) }
|
||||||
));
|
)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectNext = (): void => {
|
const selectNext = (): void => {
|
||||||
|
@ -378,7 +394,9 @@ const getFaviconFromDb = (favicon: string): string => {
|
||||||
return `data:image/png;base64,${favicon}`;
|
return `data:image/png;base64,${favicon}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getImageData = async (item: HistoryItem): Promise<{ url: string; dimensions: string }> => {
|
const getImageData = async (
|
||||||
|
item: HistoryItem
|
||||||
|
): Promise<{ url: string; dimensions: string }> => {
|
||||||
try {
|
try {
|
||||||
const base64 = await $history.readImage({ filename: item.content });
|
const base64 = await $history.readImage({ filename: item.content });
|
||||||
const dataUrl = `data:image/png;base64,${base64}`;
|
const dataUrl = `data:image/png;base64,${base64}`;
|
||||||
|
@ -392,7 +410,7 @@ const getImageData = async (item: HistoryItem): Promise<{ url: string; dimension
|
||||||
|
|
||||||
return {
|
return {
|
||||||
url: dataUrl,
|
url: dataUrl,
|
||||||
dimensions: `${img.width}x${img.height}`
|
dimensions: `${img.width}x${img.height}`,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error processing image:", error);
|
console.error("Error processing image:", error);
|
||||||
|
@ -402,14 +420,15 @@ const getImageData = async (item: HistoryItem): Promise<{ url: string; dimension
|
||||||
|
|
||||||
const processHistoryItem = async (item: any): Promise<HistoryItem> => {
|
const processHistoryItem = async (item: any): Promise<HistoryItem> => {
|
||||||
const historyItem = new HistoryItem(
|
const historyItem = new HistoryItem(
|
||||||
item.content_type as ContentType,
|
item.content_type as string,
|
||||||
|
ContentType[item.content_type as keyof typeof ContentType],
|
||||||
item.content,
|
item.content,
|
||||||
item.favicon
|
item.favicon
|
||||||
);
|
);
|
||||||
|
|
||||||
Object.assign(historyItem, {
|
Object.assign(historyItem, {
|
||||||
id: item.id,
|
id: item.id,
|
||||||
timestamp: new Date(item.timestamp)
|
timestamp: new Date(item.timestamp),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (historyItem.content_type === ContentType.Image) {
|
if (historyItem.content_type === ContentType.Image) {
|
||||||
|
@ -426,21 +445,31 @@ const updateHistory = async (resetScroll: boolean = false): Promise<void> => {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
await loadHistoryChunk();
|
await loadHistoryChunk();
|
||||||
|
|
||||||
if (resetScroll && resultsContainer.value?.osInstance()?.elements().viewport) {
|
if (
|
||||||
|
resetScroll &&
|
||||||
|
resultsContainer.value?.osInstance()?.elements().viewport
|
||||||
|
) {
|
||||||
resultsContainer.value.osInstance()?.elements().viewport?.scrollTo({
|
resultsContainer.value.osInstance()?.elements().viewport?.scrollTo({
|
||||||
top: 0,
|
top: 0,
|
||||||
behavior: "smooth"
|
behavior: "smooth",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSelection = (groupIndex: number, itemIndex: number, shouldScroll: boolean = true): void => {
|
const handleSelection = (
|
||||||
|
groupIndex: number,
|
||||||
|
itemIndex: number,
|
||||||
|
shouldScroll: boolean = true
|
||||||
|
): void => {
|
||||||
selectedGroupIndex.value = groupIndex;
|
selectedGroupIndex.value = groupIndex;
|
||||||
selectedItemIndex.value = itemIndex;
|
selectedItemIndex.value = itemIndex;
|
||||||
if (shouldScroll) scrollToSelectedItem();
|
if (shouldScroll) scrollToSelectedItem();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMediaContent = async (content: string, type: string): Promise<string> => {
|
const handleMediaContent = async (
|
||||||
|
content: string,
|
||||||
|
type: string
|
||||||
|
): Promise<string> => {
|
||||||
if (type === "image") {
|
if (type === "image") {
|
||||||
return await $history.getImagePath(content);
|
return await $history.getImagePath(content);
|
||||||
}
|
}
|
||||||
|
@ -468,7 +497,9 @@ const setupEventListeners = async (): Promise<void> => {
|
||||||
const previousState = {
|
const previousState = {
|
||||||
groupIndex: selectedGroupIndex.value,
|
groupIndex: selectedGroupIndex.value,
|
||||||
itemIndex: selectedItemIndex.value,
|
itemIndex: selectedItemIndex.value,
|
||||||
scroll: resultsContainer.value?.osInstance()?.elements().viewport?.scrollTop || 0
|
scroll:
|
||||||
|
resultsContainer.value?.osInstance()?.elements().viewport
|
||||||
|
?.scrollTop || 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
await updateHistory();
|
await updateHistory();
|
||||||
|
@ -476,11 +507,13 @@ const setupEventListeners = async (): Promise<void> => {
|
||||||
handleSelection(previousState.groupIndex, previousState.itemIndex, false);
|
handleSelection(previousState.groupIndex, previousState.itemIndex, false);
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
const viewport = resultsContainer.value?.osInstance()?.elements().viewport;
|
const viewport = resultsContainer.value
|
||||||
|
?.osInstance()
|
||||||
|
?.elements().viewport;
|
||||||
if (viewport) {
|
if (viewport) {
|
||||||
viewport.scrollTo({
|
viewport.scrollTo({
|
||||||
top: previousState.scroll,
|
top: previousState.scroll,
|
||||||
behavior: "instant"
|
behavior: "instant",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -491,6 +524,43 @@ const setupEventListeners = async (): Promise<void> => {
|
||||||
await listen("tauri://blur", () => {
|
await listen("tauri://blur", () => {
|
||||||
searchInput.value?.blur();
|
searchInput.value?.blur();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
keyboard.down("ArrowDown", (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
selectNext();
|
||||||
|
});
|
||||||
|
|
||||||
|
keyboard.down("ArrowUp", (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
selectPrevious();
|
||||||
|
});
|
||||||
|
|
||||||
|
keyboard.down("Enter", (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
pasteSelectedItem();
|
||||||
|
});
|
||||||
|
|
||||||
|
keyboard.down("Escape", (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
hideApp();
|
||||||
|
});
|
||||||
|
|
||||||
|
keyboard.down("all", (event) => {
|
||||||
|
const isMacActionCombo =
|
||||||
|
os.value === "macos" &&
|
||||||
|
(event.code === "MetaLeft" || event.code === "MetaRight") &&
|
||||||
|
event.key === "k";
|
||||||
|
|
||||||
|
const isOtherOsActionCombo =
|
||||||
|
os.value !== "macos" &&
|
||||||
|
(event.code === "ControlLeft" || event.code === "ControlRight") &&
|
||||||
|
event.key === "k";
|
||||||
|
|
||||||
|
if (isMacActionCombo || isOtherOsActionCombo) {
|
||||||
|
event.preventDefault();
|
||||||
|
console.log("Actions shortcut triggered");
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const hideApp = async (): Promise<void> => {
|
const hideApp = async (): Promise<void> => {
|
||||||
|
@ -557,7 +627,7 @@ const getItemDimensions = async (item: HistoryItem) => {
|
||||||
imageDimensions.value[item.id] = "Error";
|
imageDimensions.value[item.id] = "Error";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return imageDimensions.value[item.id] || 'Loading...';
|
return imageDimensions.value[item.id] || "Loading...";
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadImageUrl = async (item: HistoryItem) => {
|
const loadImageUrl = async (item: HistoryItem) => {
|
||||||
|
@ -572,8 +642,8 @@ const loadImageUrl = async (item: HistoryItem) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const getComputedImageUrl = (item: HistoryItem | null): string => {
|
const getComputedImageUrl = (item: HistoryItem | null): string => {
|
||||||
if (!item) return '';
|
if (!item) return "";
|
||||||
return imageUrls.value[item.id] || '';
|
return imageUrls.value[item.id] || "";
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,8 @@ const lastBlurTime = ref(0);
|
||||||
const os = ref('');
|
const os = ref('');
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
const keyboard = useKeyboard();
|
||||||
|
|
||||||
const keyToDisplayMap: Record<string, string> = {
|
const keyToDisplayMap: Record<string, string> = {
|
||||||
' ': 'Space',
|
' ': 'Space',
|
||||||
Alt: 'Alt',
|
Alt: 'Alt',
|
||||||
|
@ -141,36 +143,34 @@ const saveKeybind = async () => {
|
||||||
await invoke('save_keybind', { keybind: keybind.value });
|
await invoke('save_keybind', { keybind: keybind.value });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleGlobalKeyDown = (event: KeyboardEvent) => {
|
onMounted(() => {
|
||||||
const now = Date.now();
|
os.value = platform();
|
||||||
if (
|
|
||||||
(os.value === 'macos'
|
keyboard.down('all', (event) => {
|
||||||
? (event.code === 'MetaLeft' || event.code === 'MetaRight') && event.key === 'Enter'
|
const isMacSaveCombo = os.value === 'macos' &&
|
||||||
: (event.code === 'ControlLeft' || event.code === 'ControlRight') && event.key === 'Enter') &&
|
(event.code === 'MetaLeft' || event.code === 'MetaRight') &&
|
||||||
!isKeybindInputFocused.value
|
event.key === 'Enter';
|
||||||
) {
|
|
||||||
|
const isOtherOsSaveCombo = os.value !== 'macos' &&
|
||||||
|
(event.code === 'ControlLeft' || event.code === 'ControlRight') &&
|
||||||
|
event.key === 'Enter';
|
||||||
|
|
||||||
|
if ((isMacSaveCombo || isOtherOsSaveCombo) && !isKeybindInputFocused.value) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
saveKeybind();
|
saveKeybind();
|
||||||
} else if (
|
}
|
||||||
event.key === 'Escape' &&
|
});
|
||||||
!isKeybindInputFocused.value &&
|
|
||||||
now - lastBlurTime.value > 100
|
keyboard.down('Escape', (event) => {
|
||||||
) {
|
const now = Date.now();
|
||||||
|
if (!isKeybindInputFocused.value && now - lastBlurTime.value > 100) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
router.push('/');
|
router.push('/');
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
os.value = platform();
|
|
||||||
window.addEventListener('keydown', handleGlobalKeyDown);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
window.removeEventListener('keydown', handleGlobalKeyDown);
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@use '~/assets/css/keybind.scss';
|
@use '~/assets/css/settings.scss';
|
||||||
</style>
|
</style>
|
Loading…
Add table
Add a link
Reference in a new issue