Add OS Level Shortcut Window for Quick Access to Khoj Desktop (#815)

* rough sketch of desktop shortcuts. many bugs to fix still

* working MVP of desktop shortcut khoj

* UI fixes

* UI improvements for editable shortcut message

* major rendering fix to prevent clipboard text from getting lost

* UI improvements and bug fixes

* UI upgrades: custom top bar, edit sent message and color matching

* removed debug javascript file

* font reverted to Noto Sans

* cleaning up the code and removing diffs

* UX fixes

* cleaning up unused methods from html

* front end for button to send user back to main window to continue conversation

* UX fix for window and continue conversation support added

* migrated common js functions into chatutils.js

* Fix window closing issue in macos by

1. Use a helper function to determine if the window is open by seeing if there's a browser window with shortcut.html loaded
2. Use the  event listener on the window to handle teardown

* removed extra comment and renamed continue convo button

---------

Co-authored-by: sabaimran <narmiabas@gmail.com>
This commit is contained in:
Raghav Tirumale
2024-06-27 10:20:13 -04:00
committed by GitHub
parent 870d9ecdbf
commit 24a0d8b073
5 changed files with 981 additions and 351 deletions

View File

@@ -431,6 +431,9 @@ function addCSPHeaderToSession () {
let firstRun = true;
let win = null;
let titleBarStyle = process.platform === 'win32' ? 'default' : 'hidden';
const {globalShortcut, clipboard} = require('electron'); // global shortcut and clipboard dependencies for shortcut window
const openShortcutWindowKeyBind = 'CommandOrControl+Shift+K'
const createWindow = (tab = 'chat.html') => {
win = new BrowserWindow({
width: 800,
@@ -506,6 +509,48 @@ const createWindow = (tab = 'chat.html') => {
}
}
const createShortcutWindow = (tab = 'shortcut.html') => {
var shortcutWin = new BrowserWindow({
width: 400,
height: 600,
show: false,
titleBarStyle: titleBarStyle,
autoHideMenuBar: true,
frame: false,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: true,
}
});
shortcutWin.setMenuBarVisibility(false);
shortcutWin.setResizable(false);
shortcutWin.setOpacity(0.95);
shortcutWin.setBackgroundColor('#f5f4f3');
shortcutWin.setHasShadow(true);
shortcutWin.setVibrancy('popover');
shortcutWin.loadFile(tab);
shortcutWin.once('ready-to-show', () => {
shortcutWin.show();
});
shortcutWin.on('closed', () => {
shortcutWin = null;
});
return shortcutWin;
};
function isShortcutWindowOpen() {
const windows = BrowserWindow.getAllWindows();
for (let i = 0; i < windows.length; i++) {
if (windows[i].webContents.getURL().endsWith('shortcut.html')) {
return true;
}
}
return false;
}
app.whenReady().then(() => {
addCSPHeaderToSession();
@@ -551,14 +596,13 @@ app.whenReady().then(() => {
});
ipcMain.handle('deleteAllFiles', deleteAllFiles);
createWindow();
const mainWindow = createWindow();
app.setAboutPanelOptions({
applicationName: "Khoj",
applicationVersion: khojPackage.version,
version: khojPackage.version,
authors: "Saba Imran, Debanjum Singh Solanky and contributors",
authors: "Khoj AI",
website: "https://khoj.dev",
copyright: "GPL v3",
iconPath: path.join(__dirname, 'assets', 'icons', 'favicon-128x128.png')
@@ -575,9 +619,43 @@ app.whenReady().then(() => {
console.warn("Desktop app update check failed:", e);
}
})
globalShortcut.register(openShortcutWindowKeyBind, () => {
console.log("Shortcut key pressed")
if(isShortcutWindowOpen()) return;
const shortcutWin = createShortcutWindow(); // Create a new shortcut window each time the shortcut is triggered
shortcutWin.setAlwaysOnTop(true, 'screen-saver', 1);
const clipboardText = clipboard.readText();
console.log('Sending clipboard text:', clipboardText); // Debug log
shortcutWin.webContents.once('dom-ready', () => {
shortcutWin.webContents.send('clip', clipboardText);
console.log('Message sent to window'); // Debug log
});
// Register a global shortcut for the Escape key for the shortcutWin
globalShortcut.register('Escape', () => {
if (shortcutWin) {
shortcutWin.close();
}
// Unregister the Escape key shortcut
globalShortcut.unregister('Escape');
});
shortcutWin.on('closed', () => {
// Unregister the Escape key shortcut
globalShortcut.unregister('Escape');
});
ipcMain.on('continue-conversation-button-clicked', () => {
openWindow('chat.html');
if (shortcutWin && !shortcutWin.isDestroyed()) {
shortcutWin.close();
}
// Unregister the Escape key shortcut
globalShortcut.unregister('Escape');
});
});
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})