feat: side panel pager #46
This commit is contained in:
+44
-21
@@ -46,11 +46,19 @@
|
|||||||
li.dynamic {
|
li.dynamic {
|
||||||
flex: 1 1 0%;
|
flex: 1 1 0%;
|
||||||
}
|
}
|
||||||
|
li.separator {
|
||||||
|
height: 32px;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
li.separator:has(+ li.hidden) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
li.hidden {
|
li.hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
li.disabled {
|
li.disabled {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
button {
|
button {
|
||||||
@@ -62,12 +70,13 @@
|
|||||||
input {
|
input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
margin: 0 10px;
|
margin: 0 5px;
|
||||||
padding: 6px 10px;
|
padding: 6px 10px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
outline: none;
|
outline: none;
|
||||||
border: none;
|
border: none;
|
||||||
|
cursor: text;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
background-color: var(--border-color);
|
background-color: var(--border-color);
|
||||||
@@ -90,6 +99,17 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<button id="refresh">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||||
|
<title>refresh-circle</title>
|
||||||
|
<path
|
||||||
|
d="M12 2A10 10 0 1 0 22 12A10 10 0 0 0 12 2M18 11H13L14.81 9.19A3.94 3.94 0 0 0 12 8A4 4 0 1 0 15.86 13H17.91A6 6 0 1 1 12 6A5.91 5.91 0 0 1 16.22 7.78L18 6Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li class="separator"></li>
|
||||||
<li>
|
<li>
|
||||||
<button id="previous">
|
<button id="previous">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||||
@@ -110,9 +130,32 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="separator"></li>
|
||||||
<li class="dynamic">
|
<li class="dynamic">
|
||||||
<input id="url" type="text" spellcheck="false" />
|
<input id="url" type="text" spellcheck="false" />
|
||||||
</li>
|
</li>
|
||||||
|
<li class="separator"></li>
|
||||||
|
<li>
|
||||||
|
<button id="backward">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||||
|
<title>history</title>
|
||||||
|
<path
|
||||||
|
d="M13.5,8H12V13L16.28,15.54L17,14.33L13.5,12.25V8M13,3A9,9 0 0,0 4,12H1L4.96,16.03L9,12H6A7,7 0 0,1 13,5A7,7 0 0,1 20,12A7,7 0 0,1 13,19C11.07,19 9.32,18.21 8.06,16.94L6.64,18.36C8.27,20 10.5,21 13,21A9,9 0 0,0 22,12A9,9 0 0,0 13,3"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button id="forward">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||||
|
<title>update</title>
|
||||||
|
<path
|
||||||
|
d="M21,10.12H14.22L16.96,7.3C14.23,4.6 9.81,4.5 7.08,7.2C4.35,9.91 4.35,14.28 7.08,17C9.81,19.7 14.23,19.7 16.96,17C18.32,15.65 19,14.08 19,12.1H21C21,14.08 20.12,16.65 18.36,18.39C14.85,21.87 9.15,21.87 5.64,18.39C2.14,14.92 2.11,9.28 5.62,5.81C9.13,2.34 14.76,2.34 18.27,5.81L21,3V10.12M12.5,8V12.25L16,14.33L15.28,15.54L11,13V8H12.5Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li class="separator"></li>
|
||||||
<li>
|
<li>
|
||||||
<button id="minus">
|
<button id="minus">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||||
@@ -133,26 +176,6 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
<button id="backward">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
||||||
<title>arrow-left-circle</title>
|
|
||||||
<path
|
|
||||||
d="M2,12A10,10 0 0,1 12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12M18,11H10L13.5,7.5L12.08,6.08L6.16,12L12.08,17.92L13.5,16.5L10,13H18V11Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<button id="forward">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
||||||
<title>arrow-right-circle</title>
|
|
||||||
<path
|
|
||||||
d="M22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2A10,10 0 0,1 22,12M6,13H14L10.5,16.5L11.92,17.92L17.84,12L11.92,6.08L10.5,7.5L14,11H6V13Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
</menu>
|
</menu>
|
||||||
<script>
|
<script>
|
||||||
const { ipcRenderer } = require("electron");
|
const { ipcRenderer } = require("electron");
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
[data-theme="hidden"] {
|
||||||
|
--primary-color: rgba(0, 0, 0, 0);
|
||||||
|
--border-color: rgba(0, 0, 0, 0);
|
||||||
|
--background-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
cursor: none;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
menu {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
list-style-type: none;
|
||||||
|
background: var(--background-color);
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
width: 100vw;
|
||||||
|
height: 50vh;
|
||||||
|
border: none;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
#previous {
|
||||||
|
cursor: w-resize;
|
||||||
|
}
|
||||||
|
#next {
|
||||||
|
cursor: e-resize;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<menu>
|
||||||
|
<li>
|
||||||
|
<button id="previous"></button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button id="next"></button>
|
||||||
|
</li>
|
||||||
|
</menu>
|
||||||
|
<script>
|
||||||
|
const { ipcRenderer } = require("electron");
|
||||||
|
|
||||||
|
const registerSendEvents = () => {
|
||||||
|
document.querySelectorAll("button").forEach((button) => {
|
||||||
|
button.addEventListener("click", (e) => {
|
||||||
|
ipcRenderer.send("button-click", { id: e.target.id });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const registerReceiveEvents = () => {
|
||||||
|
ipcRenderer.on("data-theme", (e, data) => {
|
||||||
|
document.documentElement.setAttribute("data-theme", data.theme);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
registerSendEvents();
|
||||||
|
registerReceiveEvents();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
+79
-18
@@ -43,6 +43,7 @@ const init = async () => {
|
|||||||
WEBVIEW.viewUrls = urls;
|
WEBVIEW.viewUrls = urls;
|
||||||
WEBVIEW.viewZoom = zoom;
|
WEBVIEW.viewZoom = zoom;
|
||||||
WEBVIEW.viewTheme = theme;
|
WEBVIEW.viewTheme = theme;
|
||||||
|
WEBVIEW.pagerEnabled = widget;
|
||||||
WEBVIEW.widgetTheme = theme;
|
WEBVIEW.widgetTheme = theme;
|
||||||
WEBVIEW.widgetEnabled = widget;
|
WEBVIEW.widgetEnabled = widget;
|
||||||
WEBVIEW.navigationTheme = theme;
|
WEBVIEW.navigationTheme = theme;
|
||||||
@@ -80,6 +81,18 @@ const init = async () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Init global pager
|
||||||
|
WEBVIEW.pager = new WebContentsView({
|
||||||
|
transparent: true,
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: true,
|
||||||
|
contextIsolation: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
WEBVIEW.pager.setBackgroundColor("#00000000");
|
||||||
|
WEBVIEW.window.contentView.addChildView(WEBVIEW.pager);
|
||||||
|
WEBVIEW.pager.webContents.loadFile(path.join(app.getAppPath(), "html", "pager.html"));
|
||||||
|
|
||||||
// Init global widget
|
// Init global widget
|
||||||
WEBVIEW.widget = new WebContentsView({
|
WEBVIEW.widget = new WebContentsView({
|
||||||
transparent: true,
|
transparent: true,
|
||||||
@@ -151,7 +164,11 @@ const updateView = () => {
|
|||||||
if (!WEBVIEW.viewActive) {
|
if (!WEBVIEW.viewActive) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const title = `TouchKio - ${new URL(WEBVIEW.viewUrls[WEBVIEW.viewActive]).host} (${WEBVIEW.viewActive})`;
|
const url = WEBVIEW.views[WEBVIEW.viewActive].webContents.getURL();
|
||||||
|
const host = url.startsWith("data:") ? "whoopsie" : new URL(url).host;
|
||||||
|
const title = `TouchKio - ${host} (${WEBVIEW.viewActive})`;
|
||||||
|
|
||||||
|
// Update window title
|
||||||
console.log(`Update View: ${title}`);
|
console.log(`Update View: ${title}`);
|
||||||
WEBVIEW.window.setTitle(title);
|
WEBVIEW.window.setTitle(title);
|
||||||
|
|
||||||
@@ -250,6 +267,11 @@ const toggleNavigation = () => {
|
|||||||
width: window.width,
|
width: window.width,
|
||||||
height: height,
|
height: height,
|
||||||
});
|
});
|
||||||
|
if (height > 0) {
|
||||||
|
WEBVIEW.navigation.webContents.focus();
|
||||||
|
} else {
|
||||||
|
WEBVIEW.views[WEBVIEW.viewActive].webContents.focus();
|
||||||
|
}
|
||||||
|
|
||||||
// Resize webview
|
// Resize webview
|
||||||
resizeView();
|
resizeView();
|
||||||
@@ -310,7 +332,30 @@ const nextView = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reloads the current or default url on the active webview.
|
* Reloads the default url and settings on the active webview.
|
||||||
|
*/
|
||||||
|
const homeView = () => {
|
||||||
|
const view = WEBVIEW.views[WEBVIEW.viewActive];
|
||||||
|
const defaultUrl = WEBVIEW.viewUrls[WEBVIEW.viewActive];
|
||||||
|
const currentUrl = view.webContents.getURL();
|
||||||
|
|
||||||
|
// Reload the default url or refresh the page
|
||||||
|
if (currentUrl != defaultUrl) {
|
||||||
|
view.webContents.loadURL(defaultUrl);
|
||||||
|
} else {
|
||||||
|
view.webContents.reloadIgnoringCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset page zoom and history
|
||||||
|
view.webContents.setZoomFactor(WEBVIEW.viewZoom);
|
||||||
|
setTimeout(() => {
|
||||||
|
view.webContents.navigationHistory.clear();
|
||||||
|
update();
|
||||||
|
}, 2000);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reloads the current url on the active webview.
|
||||||
*/
|
*/
|
||||||
const reloadView = () => {
|
const reloadView = () => {
|
||||||
const view = WEBVIEW.views[WEBVIEW.viewActive];
|
const view = WEBVIEW.views[WEBVIEW.viewActive];
|
||||||
@@ -318,7 +363,7 @@ const reloadView = () => {
|
|||||||
const currentUrl = view.webContents.getURL();
|
const currentUrl = view.webContents.getURL();
|
||||||
|
|
||||||
// Reload the default url or refresh the page
|
// Reload the default url or refresh the page
|
||||||
if (currentUrl != defaultUrl) {
|
if (currentUrl.startsWith("data:")) {
|
||||||
view.webContents.loadURL(defaultUrl);
|
view.webContents.loadURL(defaultUrl);
|
||||||
} else {
|
} else {
|
||||||
view.webContents.reloadIgnoringCache();
|
view.webContents.reloadIgnoringCache();
|
||||||
@@ -332,6 +377,7 @@ const reloadView = () => {
|
|||||||
const resizeView = () => {
|
const resizeView = () => {
|
||||||
const window = WEBVIEW.window.getBounds();
|
const window = WEBVIEW.window.getBounds();
|
||||||
const navigation = WEBVIEW.navigation.getBounds();
|
const navigation = WEBVIEW.navigation.getBounds();
|
||||||
|
const pager = { width: 20, height: window.height };
|
||||||
const widget = { width: 60, height: 200 };
|
const widget = { width: 60, height: 200 };
|
||||||
|
|
||||||
// Update view size
|
// Update view size
|
||||||
@@ -344,10 +390,21 @@ const resizeView = () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Update pager size
|
||||||
|
if (WEBVIEW.pagerEnabled) {
|
||||||
|
WEBVIEW.pager.setBounds({
|
||||||
|
x: window.width - pager.width,
|
||||||
|
y: 0,
|
||||||
|
width: pager.width,
|
||||||
|
height: pager.height,
|
||||||
|
});
|
||||||
|
WEBVIEW.pager.webContents.send("data-theme", { theme: "hidden" });
|
||||||
|
}
|
||||||
|
|
||||||
// Update widget size
|
// Update widget size
|
||||||
if (WEBVIEW.widgetEnabled) {
|
if (WEBVIEW.widgetEnabled) {
|
||||||
WEBVIEW.widget.setBounds({
|
WEBVIEW.widget.setBounds({
|
||||||
x: window.width - 15,
|
x: window.width - 20,
|
||||||
y: parseInt(window.height / 2 - widget.height / 2, 10),
|
y: parseInt(window.height / 2 - widget.height / 2, 10),
|
||||||
width: widget.width,
|
width: widget.width,
|
||||||
height: widget.height,
|
height: widget.height,
|
||||||
@@ -400,9 +457,6 @@ const windowEvents = () => {
|
|||||||
WEBVIEW.window.on("leave-full-screen", update);
|
WEBVIEW.window.on("leave-full-screen", update);
|
||||||
|
|
||||||
// Handle global shortcut events
|
// Handle global shortcut events
|
||||||
globalShortcut.register("F5", () => {
|
|
||||||
reloadView();
|
|
||||||
});
|
|
||||||
globalShortcut.register("Control+Left", () => {
|
globalShortcut.register("Control+Left", () => {
|
||||||
previousView();
|
previousView();
|
||||||
});
|
});
|
||||||
@@ -468,7 +522,7 @@ const widgetEvents = () => {
|
|||||||
|
|
||||||
// Hide widget
|
// Hide widget
|
||||||
WEBVIEW.widget.setBounds({
|
WEBVIEW.widget.setBounds({
|
||||||
x: window.width - 15,
|
x: window.width - 20,
|
||||||
y: widget.y,
|
y: widget.y,
|
||||||
width: widget.width,
|
width: widget.width,
|
||||||
height: widget.height,
|
height: widget.height,
|
||||||
@@ -481,7 +535,6 @@ const widgetEvents = () => {
|
|||||||
switch (button.id) {
|
switch (button.id) {
|
||||||
case "keyboard":
|
case "keyboard":
|
||||||
const toggle = hardware.getKeyboardVisibility() === "ON" ? "OFF" : "ON";
|
const toggle = hardware.getKeyboardVisibility() === "ON" ? "OFF" : "ON";
|
||||||
hardware.setKeyboardVisibility(toggle);
|
|
||||||
switch (toggle) {
|
switch (toggle) {
|
||||||
case "OFF":
|
case "OFF":
|
||||||
WEBVIEW.window.restore();
|
WEBVIEW.window.restore();
|
||||||
@@ -494,6 +547,9 @@ const widgetEvents = () => {
|
|||||||
WEBVIEW.window.maximize();
|
WEBVIEW.window.maximize();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
hardware.setKeyboardVisibility(toggle, () => {
|
||||||
|
WEBVIEW.views[WEBVIEW.viewActive].webContents.focus();
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case "fullscreen":
|
case "fullscreen":
|
||||||
if (WEBVIEW.window.isFullScreen()) {
|
if (WEBVIEW.window.isFullScreen()) {
|
||||||
@@ -505,7 +561,9 @@ const widgetEvents = () => {
|
|||||||
WEBVIEW.window.unmaximize();
|
WEBVIEW.window.unmaximize();
|
||||||
WEBVIEW.window.setFullScreen(true);
|
WEBVIEW.window.setFullScreen(true);
|
||||||
}
|
}
|
||||||
hardware.setKeyboardVisibility("OFF");
|
hardware.setKeyboardVisibility("OFF", () => {
|
||||||
|
WEBVIEW.views[WEBVIEW.viewActive].webContents.focus();
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case "minimize":
|
case "minimize":
|
||||||
WEBVIEW.window.restore();
|
WEBVIEW.window.restore();
|
||||||
@@ -583,6 +641,14 @@ const navigationEvents = () => {
|
|||||||
ipcMain.on("button-click", (e, button) => {
|
ipcMain.on("button-click", (e, button) => {
|
||||||
const view = WEBVIEW.views[WEBVIEW.viewActive];
|
const view = WEBVIEW.views[WEBVIEW.viewActive];
|
||||||
switch (button.id) {
|
switch (button.id) {
|
||||||
|
case "home":
|
||||||
|
homeView();
|
||||||
|
hardware.setKeyboardVisibility("OFF");
|
||||||
|
break;
|
||||||
|
case "refresh":
|
||||||
|
reloadView();
|
||||||
|
hardware.setKeyboardVisibility("OFF");
|
||||||
|
break;
|
||||||
case "previous":
|
case "previous":
|
||||||
previousView();
|
previousView();
|
||||||
hardware.setKeyboardVisibility("OFF");
|
hardware.setKeyboardVisibility("OFF");
|
||||||
@@ -591,10 +657,6 @@ const navigationEvents = () => {
|
|||||||
nextView();
|
nextView();
|
||||||
hardware.setKeyboardVisibility("OFF");
|
hardware.setKeyboardVisibility("OFF");
|
||||||
break;
|
break;
|
||||||
case "home":
|
|
||||||
reloadView();
|
|
||||||
hardware.setKeyboardVisibility("OFF");
|
|
||||||
break;
|
|
||||||
case "minus":
|
case "minus":
|
||||||
zoomMinus();
|
zoomMinus();
|
||||||
hardware.setKeyboardVisibility("OFF");
|
hardware.setKeyboardVisibility("OFF");
|
||||||
@@ -668,20 +730,19 @@ const viewEvents = () => {
|
|||||||
// Webview url changed
|
// Webview url changed
|
||||||
view.webContents.on("did-navigate-in-page", (e, url, mainframe) => {
|
view.webContents.on("did-navigate-in-page", (e, url, mainframe) => {
|
||||||
if (mainframe) {
|
if (mainframe) {
|
||||||
update();
|
updateView();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
view.webContents.on("did-navigate", () => {
|
view.webContents.on("did-navigate", () => {
|
||||||
update();
|
updateView();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle webview mouse events
|
// Handle webview mouse events
|
||||||
view.webContents.on("before-mouse-event", (event, mouse) => {
|
view.webContents.on("before-mouse-event", (e, mouse) => {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const then = WEBVIEW.pointer.time;
|
const then = WEBVIEW.pointer.time;
|
||||||
const delta = Math.abs(now - then) / 1000;
|
const delta = Math.abs(now - then) / 1000;
|
||||||
WEBVIEW.pointer.time = now;
|
WEBVIEW.pointer.time = now;
|
||||||
|
|
||||||
switch (mouse.type) {
|
switch (mouse.type) {
|
||||||
case "mouseMove":
|
case "mouseMove":
|
||||||
if (delta > 30) {
|
if (delta > 30) {
|
||||||
|
|||||||
Reference in New Issue
Block a user