feat(ui): display current git branch in browser tab, header, and nav tabs
- Add branch indicator in browser tab title ([test-gay] GaC-Srtool...) - Add dynamic tab switching updates preserving branch prefix in browser title - Add branch badge in brand header and right-aligned branch pill in navigation tabs - Add scripts/sync-branch.js and version.json for automated branch detection
This commit is contained in:
1 parent
ba4398fe42
commit
fbe6a5f47e
6 files changed
+170
-4
No files matched your search
@@ -3001,3 +3001,50 @@ input:checked + .slider:before {
|
|||||||
.slot-picker-inv-card.active-wearer {
|
.slot-picker-inv-card.active-wearer {
|
||||||
border-color: var(--accent-gold);
|
border-color: var(--accent-gold);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Git Branch Indicators */
|
||||||
|
.badge-branch {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0.12rem 0.5rem;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: rgba(99, 102, 241, 0.15);
|
||||||
|
border: 1px solid rgba(99, 102, 241, 0.35);
|
||||||
|
color: #a5b4fc;
|
||||||
|
font-size: 0.72rem;
|
||||||
|
font-weight: 700;
|
||||||
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-branch-pill {
|
||||||
|
margin-left: auto;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.35rem;
|
||||||
|
padding: 0.25rem 0.65rem;
|
||||||
|
background: rgba(99, 102, 241, 0.12);
|
||||||
|
border: 1px solid rgba(99, 102, 241, 0.3);
|
||||||
|
border-radius: 9999px;
|
||||||
|
color: #a5b4fc;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
white-space: nowrap;
|
||||||
|
user-select: none;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-branch-pill:hover {
|
||||||
|
background: rgba(99, 102, 241, 0.22);
|
||||||
|
border-color: rgba(99, 102, 241, 0.55);
|
||||||
|
color: #c7d2fe;
|
||||||
|
}
|
||||||
|
|
||||||
|
.branch-icon {
|
||||||
|
flex-shrink: 0;
|
||||||
|
opacity: 0.85;
|
||||||
|
}
|
||||||
+11
-2
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>GaC-Srtool — Ultimate Star Rail Server & Build Manager</title>
|
<title>[test-gay] GaC-Srtool — Ultimate Star Rail Server & Build Manager</title>
|
||||||
<link rel="stylesheet" href="css/styles.css">
|
<link rel="stylesheet" href="css/styles.css">
|
||||||
<link rel="icon" type="image/png" href="assets/logo.png">
|
<link rel="icon" type="image/png" href="assets/logo.png">
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
|
||||||
@@ -15,7 +15,10 @@
|
|||||||
<div class="brand">
|
<div class="brand">
|
||||||
<img src="assets/logo.png" alt="GaC Logo" class="brand-logo-img">
|
<img src="assets/logo.png" alt="GaC Logo" class="brand-logo-img">
|
||||||
<div>
|
<div>
|
||||||
<div class="brand-title">GaC-Srtool</div>
|
<div class="brand-title" style="display: flex; align-items: center; gap: 0.5rem;">
|
||||||
|
<span>GaC-Srtool</span>
|
||||||
|
<span class="badge-branch" id="header-branch-badge">test-gay</span>
|
||||||
|
</div>
|
||||||
<div class="brand-subtitle" data-i18n="appSubtitle">Star Rail FreeSR & Server Controller</div>
|
<div class="brand-subtitle" data-i18n="appSubtitle">Star Rail FreeSR & Server Controller</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -60,6 +63,12 @@
|
|||||||
<button class="tab-btn" data-tab="tab-exrank" id="tab-btn-exrank" data-i18n="tabExrank">⚡ สกิลพิเศษ Ex-Rank</button>
|
<button class="tab-btn" data-tab="tab-exrank" id="tab-btn-exrank" data-i18n="tabExrank">⚡ สกิลพิเศษ Ex-Rank</button>
|
||||||
<button class="tab-btn" data-tab="tab-json" data-i18n="tabJson">📝 จัดการไฟล์ JSON</button>
|
<button class="tab-btn" data-tab="tab-json" data-i18n="tabJson">📝 จัดการไฟล์ JSON</button>
|
||||||
<button class="tab-btn" data-tab="tab-settings" data-i18n="tabSettings">⚙️ ตั้งค่า</button>
|
<button class="tab-btn" data-tab="tab-settings" data-i18n="tabSettings">⚙️ ตั้งค่า</button>
|
||||||
|
<div class="nav-branch-pill" id="nav-branch-pill" title="Git Branch ที่ใช้งานอยู่">
|
||||||
|
<svg class="branch-icon" viewBox="0 0 16 16" width="12" height="12" fill="currentColor">
|
||||||
|
<path fill-rule="evenodd" d="M11.75 2.5a.75.75 0 100 1.5.75.75 0 000-1.5zm-2.25.75a2.25 2.25 0 113 2.122V6A2.5 2.5 0 0110 8.5H6a1 1 0 00-1 1v1.128a2.251 2.251 0 11-1.5 0V5.372a2.25 2.25 0 111.5 0v1.836A2.492 2.492 0 016 7h4a1 1 0 001-1v-.628A2.25 2.25 0 019.5 3.25zM4.25 12a.75.75 0 100 1.5.75.75 0 000-1.5zM3.5 3.25a.75.75 0 111.5 0 .75.75 0 01-1.5 0z"></path>
|
||||||
|
</svg>
|
||||||
|
<span id="nav-branch-name">test-gay</span>
|
||||||
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<!-- Main Container -->
|
<!-- Main Container -->
|
||||||
|
|||||||
@@ -841,6 +841,7 @@ function applyTranslations() {
|
|||||||
renderAvatarsGrid();
|
renderAvatarsGrid();
|
||||||
}
|
}
|
||||||
loadEquipment();
|
loadEquipment();
|
||||||
|
updateDocumentTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup Language Selector
|
// Setup Language Selector
|
||||||
@@ -6328,6 +6329,7 @@ function setupTabs() {
|
|||||||
if (targetContent) {
|
if (targetContent) {
|
||||||
targetContent.classList.add('active');
|
targetContent.classList.add('active');
|
||||||
state.activeTab = targetId;
|
state.activeTab = targetId;
|
||||||
|
updateDocumentTitle(targetId);
|
||||||
|
|
||||||
// On-demand tab refresh
|
// On-demand tab refresh
|
||||||
if (targetId === 'tab-avatars') {
|
if (targetId === 'tab-avatars') {
|
||||||
@@ -7278,6 +7280,85 @@ function setupEvents() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// Git Branch Detection & Browser Tab Title
|
||||||
|
// ==========================================
|
||||||
|
let currentGitBranch = 'test-gay';
|
||||||
|
|
||||||
|
function updateDocumentTitle(tabId = state.activeTab || 'tab-dashboard') {
|
||||||
|
const branchPrefix = currentGitBranch ? `[${currentGitBranch}] ` : '';
|
||||||
|
const tabNames = {
|
||||||
|
'tab-dashboard': 'GaC-Srtool — Ultimate Star Rail Server & Build Manager',
|
||||||
|
'tab-avatars': `👥 ${t('tabAvatars') || 'ตัวละคร'} | GaC-Srtool`,
|
||||||
|
'tab-equipment': `🗡️ ${t('tabEquipment') || 'กรวยแสง & รีลิกส์'} | GaC-Srtool`,
|
||||||
|
'tab-persistent': `💾 ${t('tabPersistent') || 'จัดการเซฟ GaC'} | GaC-Srtool`,
|
||||||
|
'tab-exrank': `⚡ ${t('tabExrank') || 'สกิลพิเศษ Ex-Rank'} | GaC-Srtool`,
|
||||||
|
'tab-json': `📝 ${t('tabJson') || 'จัดการไฟล์ JSON'} | GaC-Srtool`,
|
||||||
|
'tab-settings': `⚙️ ${t('tabSettings') || 'ตั้งค่า'} | GaC-Srtool`
|
||||||
|
};
|
||||||
|
const titleBody = tabNames[tabId] || 'GaC-Srtool — Ultimate Star Rail Server & Build Manager';
|
||||||
|
document.title = `${branchPrefix}${titleBody}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyBranchToUI(branch) {
|
||||||
|
state.currentBranch = branch;
|
||||||
|
currentGitBranch = branch;
|
||||||
|
|
||||||
|
// 1. Browser Tab Title (<title> & document.title)
|
||||||
|
updateDocumentTitle();
|
||||||
|
|
||||||
|
// 2. Header Brand Badge
|
||||||
|
const headerBadge = document.getElementById('header-branch-badge');
|
||||||
|
if (headerBadge) {
|
||||||
|
headerBadge.textContent = branch;
|
||||||
|
headerBadge.style.display = 'inline-flex';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Nav Tabs Branch Indicator
|
||||||
|
const navBadge = document.getElementById('nav-branch-name');
|
||||||
|
if (navBadge) {
|
||||||
|
navBadge.textContent = branch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function initGitBranchDisplay() {
|
||||||
|
// 1. URL Query Param ?branch=...
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const branchFromUrl = urlParams.get('branch');
|
||||||
|
if (branchFromUrl) {
|
||||||
|
applyBranchToUI(branchFromUrl.trim());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. version.json (Generated by sync-branch or git commit)
|
||||||
|
try {
|
||||||
|
const res = await fetch('version.json?t=' + Date.now());
|
||||||
|
if (res.ok) {
|
||||||
|
const data = await res.json();
|
||||||
|
if (data && data.branch) {
|
||||||
|
applyBranchToUI(data.branch.trim());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
|
|
||||||
|
// 3. .git/HEAD (if served locally by dev server)
|
||||||
|
try {
|
||||||
|
const headRes = await fetch('.git/HEAD?t=' + Date.now());
|
||||||
|
if (headRes.ok) {
|
||||||
|
const headText = await headRes.text();
|
||||||
|
const match = headText.match(/ref:\s*refs\/heads\/([^\r\n]+)/);
|
||||||
|
if (match && match[1]) {
|
||||||
|
applyBranchToUI(match[1].trim());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
|
|
||||||
|
// 4. Fallback
|
||||||
|
applyBranchToUI(currentGitBranch);
|
||||||
|
}
|
||||||
|
|
||||||
// Background Ping Loop
|
// Background Ping Loop
|
||||||
function startPingLoop() {
|
function startPingLoop() {
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
@@ -7287,6 +7368,7 @@ function startPingLoop() {
|
|||||||
|
|
||||||
// Initialize Application
|
// Initialize Application
|
||||||
async function init() {
|
async function init() {
|
||||||
|
await initGitBranchDisplay();
|
||||||
await loadCachedGachabaseData({
|
await loadCachedGachabaseData({
|
||||||
idbGet,
|
idbGet,
|
||||||
idbSet,
|
idbSet,
|
||||||
|
|||||||
+3
-2
@@ -4,8 +4,9 @@
|
|||||||
"description": "Companion Web Management Dashboard & FreeSR Tool for GaC-hkrpg-go",
|
"description": "Companion Web Management Dashboard & FreeSR Tool for GaC-hkrpg-go",
|
||||||
"main": "index.html",
|
"main": "index.html",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "npx serve . -l 5173",
|
"sync-branch": "node scripts/sync-branch.js",
|
||||||
"start": "npx serve . -l 5173",
|
"dev": "node scripts/sync-branch.js && npx serve . -l 5173",
|
||||||
|
"start": "node scripts/sync-branch.js && npx serve . -l 5173",
|
||||||
"serve": "npx serve . -l 5173"
|
"serve": "npx serve . -l 5173"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const { execSync } = require('child_process');
|
||||||
|
|
||||||
|
let branch = 'test-gay';
|
||||||
|
try {
|
||||||
|
branch = execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf8' }).trim();
|
||||||
|
} catch (_) {
|
||||||
|
try {
|
||||||
|
const head = fs.readFileSync('.git/HEAD', 'utf8');
|
||||||
|
const m = head.match(/ref:\s*refs\/heads\/([^\r\n]+)/);
|
||||||
|
if (m && m[1]) branch = m[1].trim();
|
||||||
|
} catch (__) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
const versionData = {
|
||||||
|
branch,
|
||||||
|
version: '1.0.0',
|
||||||
|
updatedAt: new Date().toISOString()
|
||||||
|
};
|
||||||
|
|
||||||
|
fs.writeFileSync('version.json', JSON.stringify(versionData, null, 2) + '\n');
|
||||||
|
console.log(`[sync-branch] Updated version.json with branch: ${branch}`);
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"branch": "test-gay",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"updatedAt": "2026-10-17T04:56:43.360Z"
|
||||||
|
}
|
||||||
Reference in new issue
Block a user