mirror of
https://github.com/vrcx-team/VRCX.git
synced 2026-04-06 00:32:02 +02:00
Adding keyboard shortcut for direct access + Fixes for Linux clipboard reading (#1479)
* feat: add ctrl+d keyboard shortcut to open direct access * fix: make sure direct access promt only get shown once * fix: linux clipboard acess on non x11 systems xclip not present on all linux machines: using the electron mechanism instead
This commit is contained in:
@@ -11,6 +11,7 @@ const {
|
||||
nativeImage
|
||||
} = require('electron');
|
||||
const { spawn, spawnSync } = require('child_process');
|
||||
const { clipboard } = require('electron');
|
||||
const fs = require('fs');
|
||||
const https = require('https');
|
||||
|
||||
@@ -262,6 +263,9 @@ ipcMain.handle(
|
||||
ipcMain.handle('app:getArch', () => {
|
||||
return process.arch.toString();
|
||||
});
|
||||
ipcMain.handle('app:getClipboardText', () => {
|
||||
return clipboard.readText();
|
||||
});
|
||||
|
||||
ipcMain.handle('app:getNoUpdater', () => {
|
||||
return noUpdater;
|
||||
|
||||
@@ -23,6 +23,7 @@ const validChannels = ['launch-command'];
|
||||
|
||||
contextBridge.exposeInMainWorld('electron', {
|
||||
getArch: () => ipcRenderer.invoke('app:getArch'),
|
||||
getClipboardText: () => ipcRenderer.invoke('app:getClipboardText'),
|
||||
getNoUpdater: () => ipcRenderer.invoke('app:getNoUpdater'),
|
||||
setTrayIconNotification: (notify) =>
|
||||
ipcRenderer.invoke('app:setTrayIconNotification', notify),
|
||||
|
||||
@@ -198,7 +198,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRouter } from 'vue-router';
|
||||
@@ -374,6 +374,13 @@
|
||||
openExternalLink('https://github.com/vrcx-team/VRCX');
|
||||
};
|
||||
|
||||
function handleKeydown(e) {
|
||||
if (e.ctrlKey && e.key === 'd') {
|
||||
e.preventDefault();
|
||||
directAccessPaste();
|
||||
}
|
||||
}
|
||||
|
||||
const supportLinks = {
|
||||
wiki: 'https://github.com/vrcx-team/VRCX/wiki',
|
||||
github: 'https://github.com/vrcx-team/VRCX',
|
||||
@@ -451,6 +458,11 @@
|
||||
if (!sentryErrorReporting.value) return;
|
||||
const feedback = Sentry.getFeedback();
|
||||
feedback?.attachTo(document.getElementById('feedback'));
|
||||
window.addEventListener('keydown', handleKeydown);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('keydown', handleKeydown);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@ export const useSearchStore = defineStore('Search', () => {
|
||||
const quickSearchItems = ref([]);
|
||||
const friendsListSearch = ref('');
|
||||
|
||||
const directAccessPrompt = ref(null);
|
||||
|
||||
const stringComparer = computed(() =>
|
||||
Intl.Collator(appearanceSettingsStore.appLanguage.replace('_', '-'), {
|
||||
usage: 'search',
|
||||
@@ -217,12 +219,21 @@ export const useSearchStore = defineStore('Search', () => {
|
||||
return results;
|
||||
}
|
||||
|
||||
function directAccessPaste() {
|
||||
AppApi.GetClipboard().then((clipboard) => {
|
||||
if (!directAccessParse(clipboard.trim())) {
|
||||
promptOmniDirectDialog();
|
||||
}
|
||||
});
|
||||
async function directAccessPaste() {
|
||||
let cbText = '';
|
||||
if (LINUX) {
|
||||
cbText = await window.electron.getClipboardText();
|
||||
} else {
|
||||
cbText = await AppApi.GetClipboard().catch((e) => {
|
||||
console.log(e);
|
||||
return '';
|
||||
});
|
||||
}
|
||||
|
||||
let trimemd = cbText.trim();
|
||||
if (!directAccessParse(trimemd)) {
|
||||
promptOmniDirectDialog();
|
||||
}
|
||||
}
|
||||
|
||||
function directAccessParse(input) {
|
||||
@@ -335,8 +346,10 @@ export const useSearchStore = defineStore('Search', () => {
|
||||
return false;
|
||||
}
|
||||
|
||||
function promptOmniDirectDialog() {
|
||||
ElMessageBox.prompt(
|
||||
async function promptOmniDirectDialog() {
|
||||
if (directAccessPrompt.value) return;
|
||||
|
||||
directAccessPrompt.value = ElMessageBox.prompt(
|
||||
t('prompt.direct_access_omni.description'),
|
||||
t('prompt.direct_access_omni.header'),
|
||||
{
|
||||
@@ -346,21 +359,24 @@ export const useSearchStore = defineStore('Search', () => {
|
||||
inputPattern: /\S+/,
|
||||
inputErrorMessage: t('prompt.direct_access_omni.input_error')
|
||||
}
|
||||
)
|
||||
.then(({ value, action }) => {
|
||||
if (action === 'confirm' && value) {
|
||||
const input = value.trim();
|
||||
if (!directAccessParse(input)) {
|
||||
ElMessage({
|
||||
message: t(
|
||||
'prompt.direct_access_omni.message.error'
|
||||
),
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
try {
|
||||
const { value, action } = await directAccessPrompt.value;
|
||||
|
||||
if (action === 'confirm' && value) {
|
||||
const input = value.trim();
|
||||
if (!directAccessParse(input)) {
|
||||
ElMessage({
|
||||
message: t('prompt.direct_access_omni.message.error'),
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
} catch {
|
||||
} finally {
|
||||
directAccessPrompt.value = null;
|
||||
}
|
||||
}
|
||||
|
||||
function showGroupDialogShortCode(shortCode) {
|
||||
|
||||
1
src/types/globals.d.ts
vendored
1
src/types/globals.d.ts
vendored
@@ -36,6 +36,7 @@ declare global {
|
||||
};
|
||||
electron: {
|
||||
getArch: () => Promise<string>;
|
||||
getClipboardText: () => Promise<string>;
|
||||
getNoUpdater: () => Promise<boolean>;
|
||||
setTrayIconNotification: (notify: boolean) => Promise<void>;
|
||||
openFileDialog: () => Promise<string>;
|
||||
|
||||
Reference in New Issue
Block a user