chore: Adds responsiveness to Packet Documentation (#2304)
This commit is contained in:
parent
a9e611d46a
commit
efe385a176
5 changed files with 346 additions and 120 deletions
|
|
@ -113,70 +113,6 @@
|
||||||
"line": 27
|
"line": 27
|
||||||
},
|
},
|
||||||
"notes": "High Seas expansion only. Entities include mobiles and items on the boat. Coordinates include the boat\u0027s movement offset."
|
"notes": "High Seas expansion only. Entities include mobiles and items on the boat. Coordinates include the boat\u0027s movement offset."
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "0xF7",
|
|
||||||
"name": "Packet Container",
|
|
||||||
"description": "Container packet for batching multiple entity packets. Used for efficient display of boats and other groups of entities.",
|
|
||||||
"direction": "outgoing",
|
|
||||||
"isDynamic": true,
|
|
||||||
"size": "5+",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"name": "Packet ID",
|
|
||||||
"type": "byte",
|
|
||||||
"size": 1,
|
|
||||||
"value": "0xF7",
|
|
||||||
"description": "Packet identifier"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Length",
|
|
||||||
"type": "ushort",
|
|
||||||
"size": 2,
|
|
||||||
"description": "Total packet length"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Packet Count",
|
|
||||||
"type": "ushort",
|
|
||||||
"size": 2,
|
|
||||||
"description": "Number of embedded packets"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Packets",
|
|
||||||
"type": "array",
|
|
||||||
"description": "Embedded packets (typically 0xF3 World Entity packets)",
|
|
||||||
"loop": {
|
|
||||||
"countField": "packetCount",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"name": "Embedded Packet",
|
|
||||||
"type": "packet",
|
|
||||||
"description": "Complete embedded packet (0xF3 World Entity or similar)"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"related": [
|
|
||||||
{
|
|
||||||
"id": "0xF3",
|
|
||||||
"relationship": "contains",
|
|
||||||
"note": "Typically contains World Entity packets"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "0xF6",
|
|
||||||
"relationship": "variant",
|
|
||||||
"note": "Used alongside Move Boat HS for boat display"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"clientVersion": {
|
|
||||||
"feature": "HighSeas"
|
|
||||||
},
|
|
||||||
"notes": "Uses PacketContainerBuilder for dynamic growth when embedding many packets. Minimum packet length is 5 bytes (header only).",
|
|
||||||
"source": {
|
|
||||||
"file": "Projects/Server/Network/Packets/PacketContainerBuilder.cs",
|
|
||||||
"line": 23
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -522,6 +522,7 @@
|
||||||
"name": "Packet Container",
|
"name": "Packet Container",
|
||||||
"description": "Container packet for batching multiple entity packets. Used for sending groups of related entities efficiently, such as all items and mobiles visible on a boat.",
|
"description": "Container packet for batching multiple entity packets. Used for sending groups of related entities efficiently, such as all items and mobiles visible on a boat.",
|
||||||
"direction": "outgoing",
|
"direction": "outgoing",
|
||||||
|
"tags": ["Boat"],
|
||||||
"isDynamic": true,
|
"isDynamic": true,
|
||||||
"size": "5+",
|
"size": "5+",
|
||||||
"fields": [
|
"fields": [
|
||||||
|
|
@ -566,16 +567,20 @@
|
||||||
"id": "0xF3",
|
"id": "0xF3",
|
||||||
"relationship": "contains",
|
"relationship": "contains",
|
||||||
"note": "Typically contains World Entity packets"
|
"note": "Typically contains World Entity packets"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "0xF6",
|
||||||
|
"relationship": "variant",
|
||||||
|
"note": "Used alongside Move Boat HS for boat display"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"clientVersion": {
|
"clientVersion": {
|
||||||
"min": "7.0.0.0",
|
"feature": "HighSeas"
|
||||||
"feature": "StygianAbyss"
|
|
||||||
},
|
},
|
||||||
"notes": "Uses PacketContainerBuilder for efficient dynamic growth. Commonly used by boat system to batch all visible entities on deck.",
|
"notes": "Uses PacketContainerBuilder for efficient dynamic growth. Commonly used by boat system to batch all visible entities on deck. Minimum packet length is 5 bytes (header only).",
|
||||||
"source": {
|
"source": {
|
||||||
"file": "Projects/Server/Network/Packets/PacketContainerBuilder.cs",
|
"file": "Projects/Server/Network/Packets/PacketContainerBuilder.cs",
|
||||||
"line": 9
|
"line": 23
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -77,21 +77,24 @@
|
||||||
<body class="bg-modern-dark-black text-gold-300 font-sans h-screen overflow-hidden">
|
<body class="bg-modern-dark-black text-gold-300 font-sans h-screen overflow-hidden">
|
||||||
<div id="app" class="h-screen flex flex-col">
|
<div id="app" class="h-screen flex flex-col">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<header class="bg-modern-black p-4 shadow-lg border-b border-gold-500/30">
|
<header class="bg-modern-black p-3 md:p-4 shadow-lg border-b border-gold-500/30">
|
||||||
<div class="max-w-7xl mx-auto flex items-center justify-between">
|
<div class="max-w-7xl mx-auto flex items-center justify-between gap-2">
|
||||||
<div class="flex items-center space-x-4">
|
<div class="flex items-center space-x-2 md:space-x-4 min-w-0">
|
||||||
<img src="https://modernuo.com/branding/logo.svg" class="h-12 w-12">
|
<img src="https://modernuo.com/branding/logo.svg" class="h-8 w-8 md:h-12 md:w-12 flex-shrink-0">
|
||||||
<div>
|
<div class="min-w-0">
|
||||||
<h1 class="text-white text-xl font-medium">ModernUO Packet Documentation</h1>
|
<h1 class="text-white text-base md:text-xl font-medium">
|
||||||
<p class="text-gold-500/70 text-sm">Ultima Online Network Protocol Reference</p>
|
<span class="md:hidden">Packet Documentation</span>
|
||||||
|
<span class="hidden md:inline">ModernUO Packet Documentation</span>
|
||||||
|
</h1>
|
||||||
|
<p class="text-gold-500/70 text-xs md:text-sm hidden sm:block">Ultima Online Network Protocol Reference</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center space-x-4">
|
<div class="flex items-center space-x-2 md:space-x-4 flex-shrink-0">
|
||||||
<button id="typeLegendBtn" class="px-3 py-1.5 text-sm bg-modern-dark-black text-gold-400 rounded border border-gold-500/30 hover:border-gold-500 hover:bg-gold-500/10 transition-colors flex items-center space-x-1.5">
|
<button id="typeLegendBtn" class="px-2 md:px-3 py-1.5 text-sm bg-modern-dark-black text-gold-400 rounded border border-gold-500/30 hover:border-gold-500 hover:bg-gold-500/10 transition-colors flex items-center space-x-1.5">
|
||||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
|
||||||
<span>Types</span>
|
<span class="hidden sm:inline">Types</span>
|
||||||
</button>
|
</button>
|
||||||
<span id="packetCount" class="text-gold-500/70 text-sm"></span>
|
<span id="packetCount" class="text-gold-500/70 text-xs md:text-sm whitespace-nowrap"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
@ -99,9 +102,15 @@
|
||||||
<!-- Main Content -->
|
<!-- Main Content -->
|
||||||
<div class="flex-1 flex overflow-hidden min-h-0">
|
<div class="flex-1 flex overflow-hidden min-h-0">
|
||||||
<!-- Left Panel: Packet List -->
|
<!-- Left Panel: Packet List -->
|
||||||
<aside id="sidebar" class="w-80 bg-modern-black border-r border-gold-500/30 flex flex-col overflow-hidden">
|
<aside id="sidebar" class="w-full md:w-80 bg-modern-black border-r border-gold-500/30 flex flex-col overflow-hidden">
|
||||||
<!-- Search & Filter -->
|
<!-- Search & Filter -->
|
||||||
<div class="p-3 border-b border-gold-500/20 space-y-2">
|
<div class="p-3 border-b border-gold-500/20 space-y-2">
|
||||||
|
<!-- Collapse button for medium screens -->
|
||||||
|
<div class="hidden md:flex xl:hidden justify-end -mt-1 -mr-1 mb-1">
|
||||||
|
<button id="collapseSidebarBtn" class="p-1 text-gold-500/70 hover:text-gold-500 transition-colors" title="Collapse sidebar">
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 19l-7-7 7-7m8 14l-7-7 7-7"></path></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="searchInput"
|
id="searchInput"
|
||||||
|
|
@ -115,10 +124,14 @@
|
||||||
<button data-filter="both" class="filter-btn flex-1 px-2 py-1 text-xs rounded bg-modern-dark-black text-both border border-both/50 hover:bg-both/20">Both</button>
|
<button data-filter="both" class="filter-btn flex-1 px-2 py-1 text-xs rounded bg-modern-dark-black text-both border border-both/50 hover:bg-both/20">Both</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<span class="text-gold-500/70 text-xs flex-shrink-0">Tags:</span>
|
<button id="toggleTagsBtn" class="md:hidden text-gold-500/70 text-xs flex items-center gap-1 hover:text-gold-400">
|
||||||
|
<span>Tags</span>
|
||||||
|
<svg id="toggleTagsIcon" class="w-3 h-3 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg>
|
||||||
|
</button>
|
||||||
|
<span class="text-gold-500/70 text-xs flex-shrink-0 hidden md:inline">Tags:</span>
|
||||||
<button id="clearTagsBtn" class="text-xs px-2 py-0.5 rounded bg-modern-dark-black text-gold-500/70 border border-gold-500/30 hover:border-gold-500 hover:text-gold-400 hidden">Clear</button>
|
<button id="clearTagsBtn" class="text-xs px-2 py-0.5 rounded bg-modern-dark-black text-gold-500/70 border border-gold-500/30 hover:border-gold-500 hover:text-gold-400 hidden">Clear</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="tagFilter" class="flex flex-wrap gap-1 max-h-32 overflow-y-auto">
|
<div id="tagFilter" class="hidden md:flex flex-wrap gap-1 max-h-32 overflow-y-auto">
|
||||||
<!-- Tags will be populated by JavaScript -->
|
<!-- Tags will be populated by JavaScript -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -129,9 +142,20 @@
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
|
<!-- Expand sidebar button (shown when collapsed on medium screens) -->
|
||||||
|
<button id="expandSidebarBtn" class="hidden bg-modern-black border-r border-gold-500/30 px-2 py-4 text-gold-500/70 hover:text-gold-500 hover:bg-modern-black-hover transition-colors" title="Expand sidebar">
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 5l7 7-7 7M5 5l7 7-7 7"></path></svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
<!-- Right Panel: Packet Details -->
|
<!-- Right Panel: Packet Details -->
|
||||||
<main class="flex-1 overflow-y-auto bg-modern-dark-black">
|
<main id="detailPanel" class="hidden md:block flex-1 overflow-y-auto bg-modern-dark-black">
|
||||||
<div id="packetDetails" class="p-6 max-w-4xl mx-auto">
|
<div id="packetDetails" class="p-4 md:p-6 max-w-4xl mx-auto">
|
||||||
|
<!-- Mobile back button -->
|
||||||
|
<button id="mobileBackBtn" class="md:hidden flex items-center space-x-2 text-gold-500 hover:text-gold-400 mb-4 -ml-1">
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path></svg>
|
||||||
|
<span>Back to list</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
<!-- Welcome message when no packet selected -->
|
<!-- Welcome message when no packet selected -->
|
||||||
<div id="welcomeMessage" class="text-center py-16">
|
<div id="welcomeMessage" class="text-center py-16">
|
||||||
<div class="text-gold-500/50 text-6xl mb-4">📦</div>
|
<div class="text-gold-500/50 text-6xl mb-4">📦</div>
|
||||||
|
|
@ -152,9 +176,9 @@
|
||||||
</div>
|
</div>
|
||||||
<h2 id="detailName" class="text-xl text-gold-500 font-medium"></h2>
|
<h2 id="detailName" class="text-xl text-gold-500 font-medium"></h2>
|
||||||
</div>
|
</div>
|
||||||
<a id="sourceLink" href="#" target="_blank" class="flex items-center space-x-1 text-sm text-gold-500/70 hover:text-gold-500 transition-colors">
|
<a id="sourceLink" href="#" target="_blank" class="flex items-center space-x-1 text-sm text-gold-500/70 hover:text-gold-500 transition-colors" title="View Source on GitHub">
|
||||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
|
<svg class="w-5 h-5 md:w-4 md:h-4" fill="currentColor" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
|
||||||
<span>View Source</span>
|
<span class="hidden md:inline">View Source</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -183,8 +207,8 @@
|
||||||
<!-- Fields Table -->
|
<!-- Fields Table -->
|
||||||
<div id="fieldsSection" class="mb-6">
|
<div id="fieldsSection" class="mb-6">
|
||||||
<h3 class="text-gold-500 font-medium mb-3">Packet Structure</h3>
|
<h3 class="text-gold-500 font-medium mb-3">Packet Structure</h3>
|
||||||
<div class="bg-modern-black rounded-lg border border-gold-500/20 overflow-hidden">
|
<div class="bg-modern-black rounded-lg border border-gold-500/20 overflow-x-auto">
|
||||||
<table class="w-full text-sm table-fixed">
|
<table class="w-full text-sm table-fixed min-w-[600px]">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="bg-gold-500/10 text-gold-500">
|
<tr class="bg-gold-500/10 text-gold-500">
|
||||||
<th class="px-4 py-2 text-left font-medium w-16">Offset</th>
|
<th class="px-4 py-2 text-left font-medium w-16">Offset</th>
|
||||||
|
|
@ -204,8 +228,8 @@
|
||||||
<!-- Subpackets (for container packets like 0xBF, 0xD7) -->
|
<!-- Subpackets (for container packets like 0xBF, 0xD7) -->
|
||||||
<div id="subpacketsSection" class="mb-6 hidden">
|
<div id="subpacketsSection" class="mb-6 hidden">
|
||||||
<h3 class="text-gold-500 font-medium mb-3">Subpackets</h3>
|
<h3 class="text-gold-500 font-medium mb-3">Subpackets</h3>
|
||||||
<div class="bg-modern-black rounded-lg border border-gold-500/20 overflow-hidden">
|
<div class="bg-modern-black rounded-lg border border-gold-500/20 overflow-x-auto">
|
||||||
<table class="w-full text-sm">
|
<table class="w-full text-sm min-w-[500px]">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="bg-gold-500/10 text-gold-500">
|
<tr class="bg-gold-500/10 text-gold-500">
|
||||||
<th class="px-4 py-2 text-left font-medium w-24">SubID</th>
|
<th class="px-4 py-2 text-left font-medium w-24">SubID</th>
|
||||||
|
|
@ -524,6 +548,106 @@ const packetList = document.getElementById('packetList');
|
||||||
const packetCount = document.getElementById('packetCount');
|
const packetCount = document.getElementById('packetCount');
|
||||||
const welcomeMessage = document.getElementById('welcomeMessage');
|
const welcomeMessage = document.getElementById('welcomeMessage');
|
||||||
const packetContent = document.getElementById('packetContent');
|
const packetContent = document.getElementById('packetContent');
|
||||||
|
const sidebar = document.getElementById('sidebar');
|
||||||
|
const detailPanel = document.getElementById('detailPanel');
|
||||||
|
const mobileBackBtn = document.getElementById('mobileBackBtn');
|
||||||
|
const collapseSidebarBtn = document.getElementById('collapseSidebarBtn');
|
||||||
|
const expandSidebarBtn = document.getElementById('expandSidebarBtn');
|
||||||
|
|
||||||
|
// Responsive breakpoints
|
||||||
|
const MOBILE_BREAKPOINT = 768; // md breakpoint
|
||||||
|
const LARGE_BREAKPOINT = 1280; // xl breakpoint
|
||||||
|
|
||||||
|
function isMobile() {
|
||||||
|
return window.innerWidth < MOBILE_BREAKPOINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isMediumScreen() {
|
||||||
|
return window.innerWidth >= MOBILE_BREAKPOINT && window.innerWidth < LARGE_BREAKPOINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sidebar collapse state (for medium screens)
|
||||||
|
let isSidebarCollapsed = false;
|
||||||
|
|
||||||
|
function collapseSidebar() {
|
||||||
|
if (!isMediumScreen()) return;
|
||||||
|
isSidebarCollapsed = true;
|
||||||
|
sidebar.classList.add('hidden');
|
||||||
|
expandSidebarBtn.classList.remove('hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
function expandSidebar() {
|
||||||
|
isSidebarCollapsed = false;
|
||||||
|
sidebar.classList.remove('hidden');
|
||||||
|
expandSidebarBtn.classList.add('hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collapse/expand button handlers
|
||||||
|
collapseSidebarBtn.addEventListener('click', collapseSidebar);
|
||||||
|
expandSidebarBtn.addEventListener('click', expandSidebar);
|
||||||
|
|
||||||
|
function showMobileDetailView() {
|
||||||
|
if (!isMobile()) return;
|
||||||
|
sidebar.classList.add('hidden');
|
||||||
|
detailPanel.classList.remove('hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
function showMobileListView() {
|
||||||
|
if (!isMobile()) return;
|
||||||
|
sidebar.classList.remove('hidden');
|
||||||
|
detailPanel.classList.add('hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Back button handler
|
||||||
|
mobileBackBtn.addEventListener('click', () => {
|
||||||
|
showMobileListView();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle window resize - reset to proper state
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
if (isMobile()) {
|
||||||
|
// Mobile: hide expand button, handle list/detail toggle
|
||||||
|
expandSidebarBtn.classList.add('hidden');
|
||||||
|
if (!selectedPacket) {
|
||||||
|
sidebar.classList.remove('hidden');
|
||||||
|
detailPanel.classList.add('hidden');
|
||||||
|
}
|
||||||
|
} else if (isMediumScreen()) {
|
||||||
|
// Medium: show both panels, respect collapsed state
|
||||||
|
detailPanel.classList.remove('hidden');
|
||||||
|
if (isSidebarCollapsed) {
|
||||||
|
sidebar.classList.add('hidden');
|
||||||
|
expandSidebarBtn.classList.remove('hidden');
|
||||||
|
} else {
|
||||||
|
sidebar.classList.remove('hidden');
|
||||||
|
expandSidebarBtn.classList.add('hidden');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Large: always show both panels, no collapse
|
||||||
|
sidebar.classList.remove('hidden');
|
||||||
|
detailPanel.classList.remove('hidden');
|
||||||
|
expandSidebarBtn.classList.add('hidden');
|
||||||
|
isSidebarCollapsed = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Tags toggle for mobile
|
||||||
|
const toggleTagsBtn = document.getElementById('toggleTagsBtn');
|
||||||
|
const toggleTagsIcon = document.getElementById('toggleTagsIcon');
|
||||||
|
let tagsExpanded = false;
|
||||||
|
|
||||||
|
toggleTagsBtn.addEventListener('click', () => {
|
||||||
|
tagsExpanded = !tagsExpanded;
|
||||||
|
if (tagsExpanded) {
|
||||||
|
tagFilterContainer.classList.remove('hidden');
|
||||||
|
tagFilterContainer.classList.add('flex');
|
||||||
|
toggleTagsIcon.style.transform = 'rotate(180deg)';
|
||||||
|
} else {
|
||||||
|
tagFilterContainer.classList.add('hidden');
|
||||||
|
tagFilterContainer.classList.remove('flex');
|
||||||
|
toggleTagsIcon.style.transform = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Helper to ensure tags is always an array
|
// Helper to ensure tags is always an array
|
||||||
function ensureArray(val) {
|
function ensureArray(val) {
|
||||||
|
|
@ -848,6 +972,9 @@ function renderFields(fields, parentOffset = 0) {
|
||||||
function selectPacket(packet) {
|
function selectPacket(packet) {
|
||||||
selectedPacket = packet;
|
selectedPacket = packet;
|
||||||
|
|
||||||
|
// Switch to detail view on mobile
|
||||||
|
showMobileDetailView();
|
||||||
|
|
||||||
// Update list selection
|
// Update list selection
|
||||||
document.querySelectorAll('.packet-item').forEach(el => {
|
document.querySelectorAll('.packet-item').forEach(el => {
|
||||||
const idMatch = el.dataset.id === packet.id && (el.dataset.subid || '') === (packet.subId || '');
|
const idMatch = el.dataset.id === packet.id && (el.dataset.subid || '') === (packet.subId || '');
|
||||||
|
|
@ -1477,7 +1604,13 @@ function loadFromHash() {
|
||||||
(!direction || p.direction === direction)
|
(!direction || p.direction === direction)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (packet) selectPacket(packet);
|
if (packet) {
|
||||||
|
selectPacket(packet);
|
||||||
|
// Collapse sidebar on medium screens when loading with hash
|
||||||
|
if (isMediumScreen()) {
|
||||||
|
collapseSidebar();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ $outgoingDir = Join-Path $packetsDir "outgoing"
|
||||||
|
|
||||||
# Read incoming packets
|
# Read incoming packets
|
||||||
if (Test-Path $incomingDir) {
|
if (Test-Path $incomingDir) {
|
||||||
$incomingFiles = Get-ChildItem "$incomingDir\*.json" -ErrorAction SilentlyContinue
|
$incomingFiles = Get-ChildItem "$incomingDir\*.json" -ErrorAction SilentlyContinue | Sort-Object Name
|
||||||
foreach ($file in $incomingFiles) {
|
foreach ($file in $incomingFiles) {
|
||||||
Write-Host " Reading: $($file.Name)" -ForegroundColor Gray
|
Write-Host " Reading: $($file.Name)" -ForegroundColor Gray
|
||||||
try {
|
try {
|
||||||
|
|
@ -88,7 +88,7 @@ if (Test-Path $incomingDir) {
|
||||||
|
|
||||||
# Read outgoing packets
|
# Read outgoing packets
|
||||||
if (Test-Path $outgoingDir) {
|
if (Test-Path $outgoingDir) {
|
||||||
$outgoingFiles = Get-ChildItem "$outgoingDir\*.json" -ErrorAction SilentlyContinue
|
$outgoingFiles = Get-ChildItem "$outgoingDir\*.json" -ErrorAction SilentlyContinue | Sort-Object Name
|
||||||
foreach ($file in $outgoingFiles) {
|
foreach ($file in $outgoingFiles) {
|
||||||
Write-Host " Reading: $($file.Name)" -ForegroundColor Gray
|
Write-Host " Reading: $($file.Name)" -ForegroundColor Gray
|
||||||
try {
|
try {
|
||||||
|
|
@ -140,6 +140,25 @@ if ($totalPackets -eq 0) {
|
||||||
Write-Warning "No packets found! The output will have empty documentation."
|
Write-Warning "No packets found! The output will have empty documentation."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Sort packets by ID for deterministic output
|
||||||
|
# Handle IDs like "0x02" and "0xBF/0x05" (split on / and parse first part)
|
||||||
|
$allPackets.incoming = @($allPackets.incoming | Sort-Object {
|
||||||
|
$baseId = $_.id -split '/' | Select-Object -First 1
|
||||||
|
[Convert]::ToInt32($baseId, 16)
|
||||||
|
}, {
|
||||||
|
if ($_.subId) { [Convert]::ToInt32($_.subId, 16) }
|
||||||
|
elseif ($_.id -match '/') { [Convert]::ToInt32(($_.id -split '/' | Select-Object -Last 1), 16) }
|
||||||
|
else { 0 }
|
||||||
|
})
|
||||||
|
$allPackets.outgoing = @($allPackets.outgoing | Sort-Object {
|
||||||
|
$baseId = $_.id -split '/' | Select-Object -First 1
|
||||||
|
[Convert]::ToInt32($baseId, 16)
|
||||||
|
}, {
|
||||||
|
if ($_.subId) { [Convert]::ToInt32($_.subId, 16) }
|
||||||
|
elseif ($_.id -match '/') { [Convert]::ToInt32(($_.id -split '/' | Select-Object -Last 1), 16) }
|
||||||
|
else { 0 }
|
||||||
|
})
|
||||||
|
|
||||||
# Convert to JSON
|
# Convert to JSON
|
||||||
$packetsJson = $allPackets | ConvertTo-Json -Depth 20 -Compress
|
$packetsJson = $allPackets | ConvertTo-Json -Depth 20 -Compress
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue