mirror of
https://github.com/imgfloat/client.git
synced 2026-02-05 03:59:26 +00:00
Add fake frame
This commit is contained in:
@@ -3,6 +3,10 @@
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--window-frame-height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
@@ -30,6 +34,65 @@ body {
|
|||||||
padding: clamp(24px, 4vw, 48px);
|
padding: clamp(24px, 4vw, 48px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.window-frame {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: var(--window-frame-height);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 12px;
|
||||||
|
background: rgba(15, 23, 42, 0.9);
|
||||||
|
border-bottom: 1px solid rgba(30, 41, 59, 0.7);
|
||||||
|
-webkit-app-region: drag;
|
||||||
|
}
|
||||||
|
|
||||||
|
.window-frame-title {
|
||||||
|
font-size: 12px;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
color: #cbd5f5;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.window-frame-controls {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
|
}
|
||||||
|
|
||||||
|
.window-control {
|
||||||
|
width: 30px;
|
||||||
|
height: 24px;
|
||||||
|
padding: 0;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: rgba(148, 163, 184, 0.2);
|
||||||
|
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||||
|
color: #e2e8f0;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.window-control:hover {
|
||||||
|
background: rgba(148, 163, 184, 0.35);
|
||||||
|
}
|
||||||
|
|
||||||
|
.window-control:active {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.window-control-close {
|
||||||
|
background: rgba(239, 68, 68, 0.3);
|
||||||
|
border-color: rgba(239, 68, 68, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.window-control-close:hover {
|
||||||
|
background: rgba(239, 68, 68, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
.channels-shell {
|
.channels-shell {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -6,6 +6,22 @@
|
|||||||
<link rel="stylesheet" href="./css/index.css" />
|
<link rel="stylesheet" href="./css/index.css" />
|
||||||
</head>
|
</head>
|
||||||
<body class="channels-body">
|
<body class="channels-body">
|
||||||
|
<div class="window-frame" role="presentation">
|
||||||
|
<div class="window-frame-title">Imgfloat</div>
|
||||||
|
<div class="window-frame-controls">
|
||||||
|
<button class="window-control" type="button" data-window-action="minimize" aria-label="Minimize">
|
||||||
|
−
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="window-control window-control-close"
|
||||||
|
type="button"
|
||||||
|
data-window-action="close"
|
||||||
|
aria-label="Close"
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="channels-shell">
|
<div class="channels-shell">
|
||||||
<header class="channels-header">
|
<header class="channels-header">
|
||||||
<div class="brand">
|
<div class="brand">
|
||||||
@@ -54,6 +70,7 @@
|
|||||||
const form = document.getElementById("channel-search-form");
|
const form = document.getElementById("channel-search-form");
|
||||||
const input = document.getElementById("channel-search");
|
const input = document.getElementById("channel-search");
|
||||||
const domainInput = document.getElementById("domain-input");
|
const domainInput = document.getElementById("domain-input");
|
||||||
|
const windowActionButtons = document.querySelectorAll("[data-window-action]");
|
||||||
|
|
||||||
window.store.loadBroadcaster().then((value) => {
|
window.store.loadBroadcaster().then((value) => {
|
||||||
if (value && input.value === "") {
|
if (value && input.value === "") {
|
||||||
@@ -82,13 +99,25 @@
|
|||||||
const fallbackDomain = domainInput.placeholder || "";
|
const fallbackDomain = domainInput.placeholder || "";
|
||||||
const domain = domainInput.value.trim() || fallbackDomain;
|
const domain = domainInput.value.trim() || fallbackDomain;
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
return
|
return;
|
||||||
};
|
}
|
||||||
|
|
||||||
const params = new URLSearchParams({ broadcaster: channel });
|
const params = new URLSearchParams({ broadcaster: channel });
|
||||||
window.store.saveDomain(domain);
|
window.store.saveDomain(domain);
|
||||||
window.location.href = `${domain}/view/${encodeURIComponent(channel)}/broadcast`;
|
window.location.href = `${domain}/view/${encodeURIComponent(channel)}/broadcast`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
windowActionButtons.forEach((button) => {
|
||||||
|
button.addEventListener("click", () => {
|
||||||
|
const action = button.dataset.windowAction;
|
||||||
|
if (action === "minimize") {
|
||||||
|
window.store.minimizeWindow();
|
||||||
|
}
|
||||||
|
if (action === "close") {
|
||||||
|
window.store.closeWindow();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
68
src/main.js
68
src/main.js
@@ -24,49 +24,29 @@ function resolveDefaultDomain() {
|
|||||||
return normalizeDomain(buildTimeDomain);
|
return normalizeDomain(buildTimeDomain);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createWindowOptionsForPlatform(platform) {
|
function createWindowOptions() {
|
||||||
switch (platform) {
|
return {
|
||||||
case "darwin":
|
width: INITIAL_WINDOW_WIDTH_PX,
|
||||||
case "linux":
|
height: INITIAL_WINDOW_HEIGHT_PX,
|
||||||
return {
|
transparent: true,
|
||||||
width: INITIAL_WINDOW_WIDTH_PX,
|
frame: false,
|
||||||
height: INITIAL_WINDOW_HEIGHT_PX,
|
backgroundColor: "#00000000",
|
||||||
transparent: true,
|
alwaysOnTop: false,
|
||||||
frame: true,
|
icon: path.join(__dirname, "../res/icon/appicon.ico"),
|
||||||
backgroundColor: "#00000000",
|
webPreferences: {
|
||||||
alwaysOnTop: false,
|
backgroundThrottling: false,
|
||||||
icon: path.join(__dirname, "../res/icon/appicon.ico"),
|
preload: path.join(__dirname, "preload.js"),
|
||||||
webPreferences: {
|
},
|
||||||
backgroundThrottling: false,
|
};
|
||||||
preload: path.join(__dirname, "preload.js"),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
case "win32":
|
|
||||||
return {
|
|
||||||
width: INITIAL_WINDOW_WIDTH_PX,
|
|
||||||
height: INITIAL_WINDOW_HEIGHT_PX,
|
|
||||||
transparent: true,
|
|
||||||
frame: false,
|
|
||||||
backgroundColor: "#00000000",
|
|
||||||
alwaysOnTop: false,
|
|
||||||
icon: path.join(__dirname, "../res/icon/appicon.ico"),
|
|
||||||
webPreferences: {
|
|
||||||
backgroundThrottling: false,
|
|
||||||
preload: path.join(__dirname, "preload.js"),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
default:
|
|
||||||
throw new Error(`Unsupported platform: ${platform}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function createWindow(version) {
|
function createWindow(version) {
|
||||||
const windowOptions = createWindowOptionsForPlatform(process.platform);
|
const windowOptions = createWindowOptions();
|
||||||
const win = new BrowserWindow(windowOptions);
|
const win = new BrowserWindow(windowOptions);
|
||||||
win.setMenu(null);
|
win.setMenu(null);
|
||||||
win.setFullScreenable(false)
|
win.setFullScreenable(false);
|
||||||
win.setFullScreen(false)
|
win.setFullScreen(false);
|
||||||
win.setResizable(false)
|
win.setResizable(false);
|
||||||
win.setTitle(`Imgfloat Client v${version}`);
|
win.setTitle(`Imgfloat Client v${version}`);
|
||||||
|
|
||||||
return win;
|
return win;
|
||||||
@@ -78,6 +58,18 @@ ipcMain.handle("set-window-size", (_, width, height) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.handle("minimize-window", () => {
|
||||||
|
if (ELECTRON_WINDOW && !ELECTRON_WINDOW.isDestroyed()) {
|
||||||
|
ELECTRON_WINDOW.minimize();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle("close-window", () => {
|
||||||
|
if (ELECTRON_WINDOW && !ELECTRON_WINDOW.isDestroyed()) {
|
||||||
|
ELECTRON_WINDOW.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
ipcMain.handle("save-broadcaster", (_, broadcaster) => {
|
ipcMain.handle("save-broadcaster", (_, broadcaster) => {
|
||||||
const store = readStore(STORE_PATH);
|
const store = readStore(STORE_PATH);
|
||||||
store.lastBroadcaster = broadcaster;
|
store.lastBroadcaster = broadcaster;
|
||||||
|
|||||||
@@ -7,4 +7,6 @@ contextBridge.exposeInMainWorld("store", {
|
|||||||
loadDomain: () => ipcRenderer.invoke("load-domain"),
|
loadDomain: () => ipcRenderer.invoke("load-domain"),
|
||||||
loadDefaultDomain: () => ipcRenderer.invoke("load-default-domain"),
|
loadDefaultDomain: () => ipcRenderer.invoke("load-default-domain"),
|
||||||
setWindowSize: (width, height) => ipcRenderer.invoke("set-window-size", width, height),
|
setWindowSize: (width, height) => ipcRenderer.invoke("set-window-size", width, height),
|
||||||
|
minimizeWindow: () => ipcRenderer.invoke("minimize-window"),
|
||||||
|
closeWindow: () => ipcRenderer.invoke("close-window"),
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user