1- <!-- index.html -->
21<!DOCTYPE html>
32< html lang ="vi " dir ="ltr ">
43< head >
4039</ div >
4140
4241< div id ="deleteTrash ">
43- < div class ="icon-wrapper " id ="trashIconWrapper " style ="width: 110px; height: 110px; margin: 0; ">
42+ < div class ="icon-wrapper " id ="trashIconWrapper " style ="width: 110px !important ; height: 110px !important ; margin: 0; ">
4443 < img src ="icons/icon_delete.png " id ="trashIconImg " class ="icon-img " onerror ="this.outerHTML='🗑️' " />
4544 < div class ="mark-overlay " id ="trashMarkOverlay "> </ div >
4645 </ div >
@@ -280,9 +279,7 @@ <h3 id="txtAddAppTitle">Thêm ứng dụng</h3>
280279
281280 function setSafeText ( id , text ) { const el = document . getElementById ( id ) ; if ( el ) el . innerText = text ; }
282281
283- // Cập nhật binding thông tin app bản quyền / phiên bản
284282 function applyLanguage ( ) {
285- // Mapping đầy đủ các UI Element từ vi_VN.json
286283 setSafeText ( 'infoTitle' , langData ?. info_popup ?. title || 'Thông tin' ) ;
287284 const infoDetails = document . getElementById ( 'infoDetails' ) ;
288285 if ( infoDetails && langData ?. info_popup ?. details ) {
@@ -296,6 +293,15 @@ <h3 id="txtAddAppTitle">Thêm ứng dụng</h3>
296293 setSafeText ( 'btnMail' , langData ?. info_popup ?. contact || 'Liên hệ' ) ;
297294 setSafeText ( 'btnFollow' , langData ?. info_popup ?. follow || 'Theo dõi' ) ;
298295 setSafeText ( 'btnInfoDetails' , langData ?. info_popup ?. info || 'Thông tin ứng dụng' ) ;
296+
297+ // Gắn thông tin chi tiết phiên bản từ key dock_info.app_version
298+ const btnInfoDetails = document . getElementById ( 'btnInfoDetails' ) ;
299+ if ( btnInfoDetails ) {
300+ btnInfoDetails . onclick = ( ) => {
301+ alert ( langData ?. dock_info ?. app_version || "Snowboard v1.0" ) ;
302+ } ;
303+ }
304+
299305 setSafeText ( 'txtSettingTitle' , langData ?. effects ?. settings ?. title || 'Cài đặt' ) ;
300306 setSafeText ( 'openEffectsBtn' , langData ?. effects ?. settings ?. effects_menu || 'Cài đặt icon' ) ;
301307 setSafeText ( 'openBgEffectsBtn' , langData ?. effects ?. settings ?. bg_menu || 'Cài đặt nền' ) ;
@@ -348,14 +354,6 @@ <h3 id="txtAddAppTitle">Thêm ứng dụng</h3>
348354 setSafeText ( 'btnLoadMoreLocal' , loadMoreText ) ;
349355
350356 if ( document . getElementById ( 'appSearchInput' ) ) document . getElementById ( 'appSearchInput' ) . placeholder = langData ?. modal ?. search_placeholder || '🔍 Tìm kiếm...' ;
351-
352- // Gắn thông tin chi tiết phiên bản từ key dock_info.app_version
353- const btnInfoDetails = document . getElementById ( 'btnInfoDetails' ) ;
354- if ( btnInfoDetails ) {
355- btnInfoDetails . onclick = ( ) => {
356- alert ( langData ?. dock_info ?. app_version || "Snowboard v1.0" ) ;
357- } ;
358- }
359357 }
360358
361359 function applySystemTheme ( isDark ) {
@@ -480,7 +478,7 @@ <h3 id="txtAddAppTitle">Thêm ứng dụng</h3>
480478
481479 div . innerHTML = `
482480 <div class="icon-wrapper ${ styles . stroke ? 'vision-stroke' : '' } " style="border-radius:${ styles . radCSS } ; box-shadow:${ styles . boxShadow } ;">
483- <span class="fallback-text">${ firstLetter } </span>
481+ <span class="fallback-text" style="display: none;" >${ firstLetter } </span>
484482 <img class="icon-img" style="border-radius:${ styles . radCSS } ;" src="${ iconSrc } "
485483 onerror="this.style.display='none'; this.previousElementSibling.style.display='block';">
486484 <div class="mark-overlay" style="border-radius:${ styles . radCSS } ; background:${ styles . markBg } "></div>
@@ -568,7 +566,7 @@ <h3 id="txtAddAppTitle">Thêm ứng dụng</h3>
568566
569567 if ( arr . length < MAX_DOCK_APPS ) {
570568 const addBtn = document . createElement ( 'div' ) ; addBtn . className = 'app-item' ;
571- addBtn . innerHTML = `<div class="icon-wrapper" style="width:64px; height:64px; display:flex; align-items:center; justify-content:center; background:rgba(255,255,255,0.2); border-radius:16px;"><span style="font-size:28px; color:#fff;">+</span></div>` ;
569+ addBtn . innerHTML = `<div class="icon-wrapper" style="display:flex; align-items:center; justify-content:center; background:rgba(255,255,255,0.2); border-radius:16px;"><span style="font-size:28px; color:#fff;">+</span></div>` ;
572570 addBtn . onclick = ( ) => { isAddingDock = true ; currentLocalLimit = 12 ; renderModal ( ) ; } ;
573571 fragment . appendChild ( addBtn ) ;
574572 }
@@ -577,7 +575,7 @@ <h3 id="txtAddAppTitle">Thêm ứng dụng</h3>
577575 const styles = getIconStyles ( ) ;
578576
579577 setBtn . innerHTML = `
580- <div class="icon-wrapper ${ styles . stroke ? 'vision-stroke' : '' } " style="border-radius:${ styles . radCSS } ; box-shadow:${ styles . boxShadow } ; width:64px; height:64px; background:transparent;" id="dockSetInner">
578+ <div class="icon-wrapper ${ styles . stroke ? 'vision-stroke' : '' } " style="border-radius:${ styles . radCSS } ; box-shadow:${ styles . boxShadow } ; background:transparent;" id="dockSetInner">
581579 <div class="mark-overlay" style="border-radius:${ styles . radCSS } ; background:${ styles . markBg } "></div>
582580 <img src="icons/icon_setting.png" onerror="this.outerHTML='⚙️'" style="width:100%; height:100%; object-fit:contain; position:relative; z-index:2; border-radius:${ styles . radCSS } ;">
583581 </div>
@@ -622,7 +620,7 @@ <h3 id="txtAddAppTitle">Thêm ứng dụng</h3>
622620
623621 const addBtn = document . createElement ( 'div' ) ; addBtn . className = 'app-item' ;
624622 addBtn . innerHTML = `
625- <div class="icon-wrapper ${ isEmpty ? 'wiggle-effect' : '' } " style="width:64px; height:64px; display:flex; align-items:center; justify-content:center; border:2px dashed rgba(255,255,255,0.6); border-radius:16px; background:rgba(255,255,255,0.15);">
623+ <div class="icon-wrapper ${ isEmpty ? 'wiggle-effect' : '' } " style="display:flex; align-items:center; justify-content:center; border:2px dashed rgba(255,255,255,0.6); border-radius:16px; background:rgba(255,255,255,0.15);">
626624 <span style="font-size:32px; color:#4f46e5; font-weight:300;">+</span>
627625 </div>
628626 <div class="app-info"><span class="app-name">${ addLabel } </span></div>
@@ -651,14 +649,19 @@ <h3 id="txtAddAppTitle">Thêm ứng dụng</h3>
651649 function searchOnlineApps ( query ) {
652650 currentQuery = query ;
653651 const ml = document . getElementById ( 'modalList' ) ;
652+ const btnMoreOnline = document . getElementById ( 'btnLoadMoreOnline' ) ;
653+ const btnMoreLocal = document . getElementById ( 'btnLoadMoreLocal' ) ;
654+
655+ if ( btnMoreLocal ) btnMoreLocal . style . display = 'none' ;
654656 if ( ! query . trim ( ) ) { renderModalList ( ) ; return ; }
655657
656- if ( ml ) ml . innerHTML = '<div style="grid-column: span 4; text-align: center; color: var(--color-channel-name); padding: 20px;">🔍 Đang tải dữ liệu...</div>' ;
658+ if ( currentSearchLimit === 12 && ml ) ml . innerHTML = '<div style="grid-column: span 4; text-align: center; color: var(--color-channel-name); padding: 20px;">🔍 Đang tải dữ liệu...</div>' ;
659+ if ( btnMoreOnline ) btnMoreOnline . style . display = 'none' ;
657660
658661 fetch ( `https://itunes.apple.com/search?term=${ encodeURIComponent ( query ) } &country=${ currentStore } &entity=software&limit=${ currentSearchLimit } ` )
659662 . then ( res => res . json ( ) )
660663 . then ( data => {
661- if ( ! ml ) return ;
664+ if ( ! ml ) return ;
662665 ml . innerHTML = '' ;
663666 if ( ! data . results || data . results . length === 0 ) {
664667 ml . innerHTML = '<div style="grid-column: span 4; text-align: center; color: #888; padding: 20px;">Không tìm thấy kết quả!</div>' ;
@@ -669,7 +672,7 @@ <h3 id="txtAddAppTitle">Thêm ứng dụng</h3>
669672 const bundleId = app . bundleId ;
670673 let appName = app . trackName . split ( ':' ) [ 0 ] . split ( '-' ) [ 0 ] . trim ( ) ;
671674 // Lấy icon chất lượng cao 512px
672- const iconUrl = app . artworkUrl512 || app . artworkUrl100 ;
675+ const iconUrl = cleanIconPath ( app . artworkUrl512 || app . artworkUrl100 ) ;
673676
674677 appDatabase [ bundleId ] = { Name : appName , icon : iconUrl } ;
675678
@@ -679,15 +682,16 @@ <h3 id="txtAddAppTitle">Thêm ứng dụng</h3>
679682
680683 item . innerHTML = `
681684 <div class="icon-wrapper" style="width:64px; height:64px; border-radius:16px;">
682- <span class="fallback-text" style="color:#333;">${ firstLetter } </span>
683- <img src="${ iconUrl } " class="icon-img" onerror="this.style.display='none';">
685+ <span class="fallback-text" style="color:#333; display:none; ">${ firstLetter } </span>
686+ <img src="${ iconUrl } " class="icon-img" onerror="this.style.display='none'; this.previousElementSibling.style.display='block'; ">
684687 </div>
685688 <span class="app-name" style="margin-top:4px;">${ appName } </span>
686689 ` ;
687690 item . onclick = ( ) => selectAppToAdd ( bundleId ) ;
688691 fragment . appendChild ( item ) ;
689692 } ) ;
690693 ml . appendChild ( fragment ) ;
694+ if ( data . results . length === currentSearchLimit && btnMoreOnline ) btnMoreOnline . style . display = 'block' ;
691695 } )
692696 . catch ( ( ) => {
693697 if ( ml ) ml . innerHTML = '<div style="grid-column: span 4; text-align: center; color: #ff3b30;">Lỗi kết nối App Store!</div>' ;
@@ -725,14 +729,16 @@ <h3 id="txtAddAppTitle">Thêm ứng dụng</h3>
725729 const fragment = document . createDocumentFragment ( ) ;
726730 availableApps . slice ( 0 , currentLocalLimit ) . forEach ( id => {
727731 const item = document . createElement ( 'div' ) ; item . className = 'app-item' ;
732+ let dName = appDatabase [ id ] . Name ;
728733 let cleanIcon = cleanIconPath ( appDatabase [ id ] . icon ) ;
729- let firstLetter = appDatabase [ id ] . Name . charAt ( 0 ) . toUpperCase ( ) ;
734+ let firstLetter = dName . charAt ( 0 ) . toUpperCase ( ) ;
735+
730736 item . innerHTML = `
731- <div class="icon-wrapper" style="width:64px; height:64px; border-radius:16px ;">
732- <span class="fallback-text" style="color:#333;">${ firstLetter } </span>
737+ <div class="icon-wrapper" style="width:64px; height:64px; border-radius:12px; box-shadow: var(--shadow-box) ;">
738+ <span class="fallback-text" style="color:#333; display:none; ">${ firstLetter } </span>
733739 <img src="${ cleanIcon } " class="icon-img" onerror="this.style.display='none'; this.previousElementSibling.style.display='block';">
734740 </div>
735- <span class="app-name" style=" margin-top:4px;">${ appDatabase [ id ] . Name } </span>
741+ <span style="display:block; font-size:10px; margin-top:6px; text-align:center; width:100%; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; padding: 0 4px; box-sizing:border-box; ">${ dName } </span>
736742 ` ;
737743 item . onclick = ( ) => selectAppToAdd ( id ) ;
738744 fragment . appendChild ( item ) ;
@@ -838,7 +844,6 @@ <h3 id="txtAddAppTitle">Thêm ứng dụng</h3>
838844 if ( document . getElementById ( 'btnInfo' ) ) document . getElementById ( 'btnInfo' ) . onclick = ( ) => { closeDrawerSecure ( ) ; document . getElementById ( 'infoModal' ) ?. classList . add ( 'active' ) ; } ;
839845 if ( document . getElementById ( 'btnMail' ) ) document . getElementById ( 'btnMail' ) . onclick = ( ) => window . open ( socialData ?. links ?. email || 'mailto:' , '_blank' ) ;
840846 if ( document . getElementById ( 'btnFollow' ) ) document . getElementById ( 'btnFollow' ) . onclick = ( ) => window . open ( socialData ?. links ?. social_follow || 'https://icloud.com' , '_blank' ) ;
841- if ( document . getElementById ( 'btnInfoDetails' ) ) document . getElementById ( 'btnInfoDetails' ) . onclick = ( ) => { alert ( langData ?. dock_info ?. app_version || "Snowboard v1.0" ) ; } ;
842847 if ( document . getElementById ( 'btnPlugin' ) ) document . getElementById ( 'btnPlugin' ) . onclick = ( ) => { closeDrawerSecure ( ) ; window . open ( socialData ?. links ?. plugin_shortcut || 'https://www.icloud.com/shortcuts' , '_blank' ) ; } ;
843848
844849 if ( document . getElementById ( 'btnSettings' ) ) document . getElementById ( 'btnSettings' ) . onclick = ( ) => openSettings ( 'settingsModal' ) ;
@@ -941,4 +946,4 @@ <h3 id="txtAddAppTitle">Thêm ứng dụng</h3>
941946 }
942947</ script >
943948</ body >
944- </ html >
949+ </ html >
0 commit comments