@@ -6,6 +6,15 @@ const logOutput = document.querySelector("#logOutput");
66const themeToggle = document . querySelector ( "#themeToggle" ) ;
77const themeIcon = document . querySelector ( "#themeIcon" ) ;
88const 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
1019const modelSelects = document . querySelectorAll ( ".model-select" ) ;
1120const defaultModelSelect = document . querySelector ( "#defaultModelSelect" ) ;
@@ -96,13 +105,16 @@ const editorRegistry = new Map();
96105let settingsCache = { defaultModel : "" , modelSettings : { } , modelOrder : [ ] } ;
97106let activeModelName = "" ;
98107let initPending = 2 ;
108+ const initStartedAt = Date . now ( ) ;
99109
100110function 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+
535630function bindThemeToggle ( ) {
536631 const savedTheme = localStorage . getItem ( "agently_theme" ) || "dark" ;
537632 applyTheme ( savedTheme ) ;
@@ -583,6 +678,11 @@ function loadUiValue(key, fallback = "") {
583678function 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
588688function 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
17881899refreshRequestModeUI ( ) ;
@@ -1799,6 +1910,23 @@ loadSettings();
17991910switchOutputTab ( "prompt" ) ;
18001911switchPromptTab ( "standard" ) ;
18011912autoResizeAllOutputs ( ) ;
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
18031931const savedInputTab = loadUiValue ( "inputTab" , "agently_code" ) ;
18041932const savedOutputTab = loadUiValue ( "outputTab" , "prompt" ) ;
0 commit comments