Skip to content

Commit 8bff422

Browse files
committed
update: optimize
1 parent 263c970 commit 8bff422

File tree

5 files changed

+221
-8
lines changed

5 files changed

+221
-8
lines changed

tools/agently_helper/index.html

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ <h1 data-i18n="Agently Helper">Agently Helper</h1>
4141
</a>
4242
</div>
4343
</header>
44+
<div class="update-banner hidden" id="updateBanner">
45+
<span class="update-text">Update available</span>
46+
<a class="update-link" id="updateLink" href="#" target="_blank" rel="noopener">Download</a>
47+
</div>
4448

4549
<div class="workspace">
4650
<aside class="sidebar">
@@ -50,18 +54,18 @@ <h1 data-i18n="Agently Helper">Agently Helper</h1>
5054
<button class="tab sidebar-tab" data-tab="batch" data-i18n="Batch Test">Batch Test</button>
5155
</div>
5256
<div class="sidebar-section">
53-
<div class="sidebar-title" data-i18n="Community Zone">Community Zone</div>
57+
<div class="sidebar-title" data-i18n="Community">Community</div>
58+
<button class="tab sidebar-tab" data-tab="community" data-i18n="Community Zone">Community Zone</button>
5459
<a
5560
class="tab sidebar-tab"
5661
href="https://agently.tech"
5762
target="_blank"
5863
rel="noopener"
59-
data-i18n="Official Website"
64+
data-i18n="Agently Website"
6065
>
61-
Official Website
66+
Agently Website
6267
<img class="link-icon" src="icons/external_link.svg" alt="" />
6368
</a>
64-
<button class="tab sidebar-tab" data-tab="community" data-i18n="Community Zone">Community Zone</button>
6569
</div>
6670
<div class="sidebar-section">
6771
<div class="sidebar-title" data-i18n="Settings">Settings</div>
@@ -453,7 +457,7 @@ <h2 data-i18n="Settings">Settings</h2>
453457
<div class="panel-grid single">
454458
<section class="card">
455459
<div class="card-header">
456-
<h2 data-i18n="Community">Community</h2>
460+
<h2 data-i18n="Community Zone">Community Zone</h2>
457461
</div>
458462
<div class="output-tabs community-tabs">
459463
<button class="tab small active" data-community-tab="discussions">Github Discussions</button>

tools/agently_helper/main.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ const { app, BrowserWindow, ipcMain, shell } = require("electron");
22
const path = require("path");
33
const fs = require("fs");
44
const { spawn } = require("child_process");
5+
const https = require("https");
56

67
const SETTINGS_FILE = "settings.json";
8+
const UPDATE_INFO_URL =
9+
"https://raw.githubusercontent.com/AgentEra/Agently/docs/docs/agently_helper_latest.json";
710

811
function getPythonRunnerPath() {
912
if (!app.isPackaged) {
@@ -49,6 +52,32 @@ function getSettingsPath() {
4952
function getDotenvPath() {
5053
return path.join(app.getPath("userData"), DOTENV_FILENAME);
5154
}
55+
56+
function fetchUpdateInfo() {
57+
return new Promise((resolve) => {
58+
https
59+
.get(UPDATE_INFO_URL, (res) => {
60+
let data = "";
61+
res.on("data", (chunk) => {
62+
data += chunk.toString();
63+
});
64+
res.on("end", () => {
65+
if (!data.trim()) {
66+
resolve({ ok: false, error: "Empty update response." });
67+
return;
68+
}
69+
try {
70+
resolve({ ok: true, data: JSON.parse(data) });
71+
} catch (err) {
72+
resolve({ ok: false, error: `Update JSON parse failed: ${err.message || err}` });
73+
}
74+
});
75+
})
76+
.on("error", (err) => {
77+
resolve({ ok: false, error: err.message || String(err) });
78+
});
79+
});
80+
}
5281
function readSettings() {
5382
const settingsPath = getSettingsPath();
5483
try {
@@ -384,3 +413,11 @@ ipcMain.handle("batch:run", (_event, payload) => {
384413
dotenvPath: getDotenvPath(),
385414
});
386415
});
416+
417+
ipcMain.handle("app:checkUpdate", async () => {
418+
return fetchUpdateInfo();
419+
});
420+
421+
ipcMain.handle("app:getVersion", () => {
422+
return { ok: true, version: app.getVersion() };
423+
});

tools/agently_helper/preload.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ contextBridge.exposeInMainWorld("agentlyApi", {
1212
onLog: (callback) => ipcRenderer.on("log:append", (_event, data) => callback(data)),
1313
convertPrompt: (payload) => ipcRenderer.invoke("prompt:convert", payload),
1414
runBatch: (payload) => ipcRenderer.invoke("batch:run", payload),
15+
checkUpdate: () => ipcRenderer.invoke("app:checkUpdate"),
16+
getAppVersion: () => ipcRenderer.invoke("app:getVersion"),
1517
});

tools/agently_helper/renderer.js

Lines changed: 131 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ const logOutput = document.querySelector("#logOutput");
66
const themeToggle = document.querySelector("#themeToggle");
77
const themeIcon = document.querySelector("#themeIcon");
88
const startupModal = document.querySelector("#startupModal");
9+
const updateBanner = document.querySelector("#updateBanner");
10+
const updateLink = document.querySelector("#updateLink");
11+
const workspace = document.querySelector(".workspace");
12+
const appRoot = document.querySelector(".app");
13+
const topbar = document.querySelector(".topbar");
14+
const communityPanel = document.querySelector('.tab-panel[data-tab="community"]');
15+
const communityCard = communityPanel ? communityPanel.querySelector(".card") : null;
16+
const communityTabsRow = communityPanel ? communityPanel.querySelector(".community-tabs") : null;
17+
const communityIndicator = document.querySelector("#communityRunIndicator");
918

1019
const modelSelects = document.querySelectorAll(".model-select");
1120
const defaultModelSelect = document.querySelector("#defaultModelSelect");
@@ -96,13 +105,16 @@ const editorRegistry = new Map();
96105
let settingsCache = { defaultModel: "", modelSettings: {}, modelOrder: [] };
97106
let activeModelName = "";
98107
let initPending = 2;
108+
const initStartedAt = Date.now();
99109

100110
function markReady() {
101111
initPending = Math.max(0, initPending - 1);
102112
if (initPending === 0 && startupModal) {
103-
requestAnimationFrame(() => {
113+
const elapsed = Date.now() - initStartedAt;
114+
const delay = elapsed < 400 ? 400 - elapsed : 0;
115+
setTimeout(() => {
104116
startupModal.style.display = "none";
105-
});
117+
}, delay);
106118
}
107119
}
108120

@@ -485,7 +497,7 @@ const translations = {
485497
Console: "控制台",
486498
Reset: "重置",
487499
"model name": "模型名称",
488-
"Official Website": "官方网站",
500+
"Agently Website": "Agently 官网",
489501
"Community Zone": "交流区",
490502
},
491503
};
@@ -532,6 +544,89 @@ function applyUiScale(scale) {
532544
document.body.style.zoom = String(nextScale);
533545
}
534546

547+
function updateWorkspaceHeight() {
548+
if (!workspace || !appRoot) {
549+
return;
550+
}
551+
const appRect = appRoot.getBoundingClientRect();
552+
const workspaceRect = workspace.getBoundingClientRect();
553+
const nextHeight = Math.max(0, appRect.bottom - workspaceRect.top);
554+
workspace.style.height = `${nextHeight}px`;
555+
updateCommunityHeight();
556+
}
557+
558+
function updateCommunityHeight() {
559+
if (!communityPanel || !communityCard || !workspace) {
560+
return;
561+
}
562+
if (!communityPanel.classList.contains("active")) {
563+
return;
564+
}
565+
const workspaceRect = workspace.getBoundingClientRect();
566+
const cardRect = communityCard.getBoundingClientRect();
567+
const available = Math.max(0, workspaceRect.bottom - cardRect.top);
568+
communityCard.style.height = `${available}px`;
569+
const header = communityCard.querySelector(".card-header");
570+
const headerHeight = header ? header.offsetHeight : 0;
571+
const tabsHeight = communityTabsRow ? communityTabsRow.offsetHeight : 0;
572+
const indicatorHeight = communityIndicator ? communityIndicator.offsetHeight : 0;
573+
const extraGap = 12 * 2;
574+
const webviewHeight = Math.max(200, available - headerHeight - tabsHeight - indicatorHeight - extraGap);
575+
if (communityWebview) {
576+
communityWebview.style.height = `${webviewHeight}px`;
577+
}
578+
if (communityWechat) {
579+
communityWechat.style.height = `${webviewHeight}px`;
580+
}
581+
}
582+
583+
function parseVersion(version) {
584+
return String(version || "")
585+
.split(".")
586+
.map((part) => Number(part) || 0);
587+
}
588+
589+
function isNewerVersion(remote, current) {
590+
const remoteParts = parseVersion(remote);
591+
const currentParts = parseVersion(current);
592+
const maxLength = Math.max(remoteParts.length, currentParts.length);
593+
for (let i = 0; i < maxLength; i += 1) {
594+
const r = remoteParts[i] || 0;
595+
const c = currentParts[i] || 0;
596+
if (r > c) {
597+
return true;
598+
}
599+
if (r < c) {
600+
return false;
601+
}
602+
}
603+
return false;
604+
}
605+
606+
async function checkForUpdates() {
607+
if (!updateBanner || !updateLink || !window.agentlyApi?.checkUpdate) {
608+
return;
609+
}
610+
const [remote, local] = await Promise.all([
611+
window.agentlyApi.checkUpdate(),
612+
window.agentlyApi.getAppVersion(),
613+
]);
614+
if (!remote?.ok || !local?.ok) {
615+
return;
616+
}
617+
const remoteVersion = remote.data?.version;
618+
const downloadUrl = remote.data?.download;
619+
const currentVersion = local.version;
620+
if (!remoteVersion || !downloadUrl || !currentVersion) {
621+
return;
622+
}
623+
if (isNewerVersion(remoteVersion, currentVersion)) {
624+
updateLink.href = downloadUrl;
625+
updateBanner.classList.remove("hidden");
626+
updateWorkspaceHeight();
627+
}
628+
}
629+
535630
function bindThemeToggle() {
536631
const savedTheme = localStorage.getItem("agently_theme") || "dark";
537632
applyTheme(savedTheme);
@@ -583,6 +678,11 @@ function loadUiValue(key, fallback = "") {
583678
function switchTab(target) {
584679
tabButtons.forEach((btn) => btn.classList.toggle("active", btn.dataset.tab === target));
585680
tabPanels.forEach((panel) => panel.classList.toggle("active", panel.dataset.tab === target));
681+
if (target === "community") {
682+
requestAnimationFrame(() => {
683+
updateCommunityHeight();
684+
});
685+
}
586686
}
587687

588688
function switchOutputTab(target) {
@@ -1780,9 +1880,20 @@ function bindCommunityTabs() {
17801880
if (communityRunIndicator) {
17811881
communityRunIndicator.classList.add("active");
17821882
}
1883+
if (communityWebview && typeof communityWebview.setZoomFactor === "function") {
1884+
communityWebview.setZoomFactor(target === "gitee" ? 0.9 : 1);
1885+
}
17831886
}
17841887
});
17851888
});
1889+
1890+
if (communityWebview && typeof communityWebview.setZoomFactor === "function") {
1891+
communityWebview.addEventListener("did-finish-load", () => {
1892+
const active = document.querySelector("[data-community-tab].active");
1893+
const target = active ? active.dataset.communityTab : "discussions";
1894+
communityWebview.setZoomFactor(target === "gitee" ? 0.9 : 1);
1895+
});
1896+
}
17861897
}
17871898

17881899
refreshRequestModeUI();
@@ -1799,6 +1910,23 @@ loadSettings();
17991910
switchOutputTab("prompt");
18001911
switchPromptTab("standard");
18011912
autoResizeAllOutputs();
1913+
setTimeout(() => {
1914+
checkForUpdates();
1915+
}, 0);
1916+
updateWorkspaceHeight();
1917+
window.addEventListener("resize", updateWorkspaceHeight);
1918+
if (appRoot) {
1919+
const observer = new ResizeObserver(() => {
1920+
updateWorkspaceHeight();
1921+
});
1922+
observer.observe(appRoot);
1923+
if (topbar) {
1924+
observer.observe(topbar);
1925+
}
1926+
if (updateBanner) {
1927+
observer.observe(updateBanner);
1928+
}
1929+
}
18021930

18031931
const savedInputTab = loadUiValue("inputTab", "agently_code");
18041932
const savedOutputTab = loadUiValue("outputTab", "prompt");

tools/agently_helper/styles.css

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ body {
102102
flex-direction: column;
103103
gap: 10px;
104104
min-height: 100dvh;
105+
height: 100dvh;
105106
}
106107

107108
.topbar {
@@ -117,6 +118,32 @@ body {
117118
animation: floatIn 700ms ease;
118119
}
119120

121+
.update-banner {
122+
display: flex;
123+
align-items: center;
124+
gap: 8px;
125+
padding: 6px 10px;
126+
border-radius: var(--radius);
127+
background: var(--surface);
128+
box-shadow: 0 12px 30px var(--shadow);
129+
font-size: 9px;
130+
color: var(--ink);
131+
}
132+
133+
.update-text {
134+
color: var(--ink-soft);
135+
}
136+
137+
.update-link {
138+
color: var(--ink);
139+
text-decoration: none;
140+
font-weight: 600;
141+
}
142+
143+
.update-link:hover {
144+
color: var(--ink);
145+
}
146+
120147
.theme-toggle {
121148
width: 32px;
122149
height: 32px;
@@ -235,6 +262,7 @@ h1 {
235262
gap: 12px;
236263
min-height: 0;
237264
align-items: start;
265+
flex: 1;
238266
}
239267

240268
.sidebar {
@@ -343,6 +371,7 @@ a.sidebar-tab {
343371
flex-direction: column;
344372
gap: 8px;
345373
min-height: 0;
374+
flex: 1;
346375
}
347376

348377

@@ -358,6 +387,10 @@ a.sidebar-tab {
358387
flex: 1;
359388
}
360389

390+
.tab-panel[data-tab="community"] {
391+
height: 100%;
392+
}
393+
361394
.panel-grid {
362395
display: grid;
363396
grid-template-columns: repeat(2, minmax(0, 1fr));
@@ -371,6 +404,15 @@ a.sidebar-tab {
371404
min-height: 0;
372405
}
373406

407+
.tab-panel[data-tab="community"] .panel-grid.single {
408+
grid-template-rows: minmax(0, 1fr);
409+
height: 100%;
410+
}
411+
412+
.tab-panel[data-tab="community"] .card {
413+
height: 100%;
414+
}
415+
374416
.log-card {
375417
margin-top: 8px;
376418
}

0 commit comments

Comments
 (0)