|
431 | 431 | word-break: break-all; |
432 | 432 | } |
433 | 433 | .source-link:hover { text-decoration: underline; } |
| 434 | + .config-block { |
| 435 | + background: var(--bg); |
| 436 | + border: 1px solid var(--border-soft); |
| 437 | + border-radius: 6px; |
| 438 | + padding: 12px 14px; |
| 439 | + margin-top: 8px; |
| 440 | + margin-bottom: 12px; |
| 441 | + font-family: var(--font-mono); |
| 442 | + font-size: 11px; |
| 443 | + line-height: 1.7; |
| 444 | + color: var(--text-muted); |
| 445 | + overflow-x: auto; |
| 446 | + white-space: pre; |
| 447 | + } |
| 448 | + .config-block .key-hl { color: var(--accent); } |
| 449 | + .config-block .val-hl { color: var(--green); } |
| 450 | + .config-block .comment-hl { color: var(--text-dim); } |
| 451 | + .config-label { |
| 452 | + display: inline-block; |
| 453 | + padding: 2px 8px; |
| 454 | + background: var(--green-soft); |
| 455 | + border-radius: 4px; |
| 456 | + font-size: 10px; |
| 457 | + font-weight: 700; |
| 458 | + text-transform: uppercase; |
| 459 | + letter-spacing: 0.06em; |
| 460 | + color: var(--green); |
| 461 | + margin-bottom: 4px; |
| 462 | + } |
| 463 | + .config-note { |
| 464 | + font-size: 12px; |
| 465 | + color: var(--text-muted); |
| 466 | + margin-top: 4px; |
| 467 | + padding: 6px 0; |
| 468 | + line-height: 1.5; |
| 469 | + } |
434 | 470 |
|
435 | 471 | /* Footer */ |
436 | 472 | footer { |
@@ -860,6 +896,54 @@ <h3>No cameras found</h3> |
860 | 896 | } |
861 | 897 |
|
862 | 898 | // ── Detail drawer ───────────────────────────────────────────────── |
| 899 | +function renderConfigs(cam) { |
| 900 | + const cfg = cam.configs; |
| 901 | + if (!cfg) return ''; |
| 902 | + |
| 903 | + let html = '<div class="drawer-section"><div class="drawer-section-title">Integration Configs</div>'; |
| 904 | + |
| 905 | + if (cfg.frigate) { |
| 906 | + const f = cfg.frigate; |
| 907 | + html += '<span class="config-label">Frigate</span>'; |
| 908 | + if (f.rtsp_url_template || f.best_substream || f.detect) { |
| 909 | + let yaml = '<span class="comment-hl"># Frigate NVR config</span>\n'; |
| 910 | + yaml += '<span class="key-hl">cameras</span>:\n'; |
| 911 | + yaml += ' <span class="key-hl">your_camera</span>:\n'; |
| 912 | + if (f.rtsp_url_template || f.best_substream) { |
| 913 | + yaml += ' <span class="key-hl">ffmpeg</span>:\n'; |
| 914 | + yaml += ' <span class="key-hl">inputs</span>:\n'; |
| 915 | + if (f.rtsp_url_template) yaml += ' - <span class="key-hl">path</span>: <span class="val-hl">' + f.rtsp_url_template + '</span>\n <span class="key-hl">roles</span>: [record]\n'; |
| 916 | + if (f.best_substream) yaml += ' - <span class="key-hl">path</span>: <span class="val-hl">' + f.best_substream + '</span>\n <span class="key-hl">roles</span>: [detect]\n'; |
| 917 | + } |
| 918 | + if (f.detect) { |
| 919 | + yaml += ' <span class="key-hl">detect</span>:\n'; |
| 920 | + if (f.detect.width) yaml += ' <span class="key-hl">width</span>: <span class="val-hl">' + f.detect.width + '</span>\n'; |
| 921 | + if (f.detect.height) yaml += ' <span class="key-hl">height</span>: <span class="val-hl">' + f.detect.height + '</span>\n'; |
| 922 | + if (f.detect.fps) yaml += ' <span class="key-hl">fps</span>: <span class="val-hl">' + f.detect.fps + '</span>\n'; |
| 923 | + } |
| 924 | + html += '<div class="config-block">' + yaml + '</div>'; |
| 925 | + } |
| 926 | + if (f.notes) html += '<div class="config-note">' + f.notes + '</div>'; |
| 927 | + } |
| 928 | + |
| 929 | + if (cfg.home_assistant) { |
| 930 | + const ha = cfg.home_assistant; |
| 931 | + html += '<span class="config-label">Home Assistant</span>'; |
| 932 | + if (ha.integration) html += '<div class="config-note">Integration: <strong>' + ha.integration + '</strong></div>'; |
| 933 | + if (ha.notes) html += '<div class="config-note">' + ha.notes + '</div>'; |
| 934 | + } |
| 935 | + |
| 936 | + if (cfg.blue_iris) { |
| 937 | + const bi = cfg.blue_iris; |
| 938 | + html += '<span class="config-label">Blue Iris</span>'; |
| 939 | + if (bi.profile) html += '<div class="config-note">Profile: <strong>' + bi.profile + '</strong></div>'; |
| 940 | + if (bi.notes) html += '<div class="config-note">' + bi.notes + '</div>'; |
| 941 | + } |
| 942 | + |
| 943 | + html += '</div>'; |
| 944 | + return html; |
| 945 | +} |
| 946 | + |
863 | 947 | function openDrawer(cam) { |
864 | 948 | const msrpStr = (() => { |
865 | 949 | const p = []; |
@@ -917,6 +1001,8 @@ <h2>${cam.model}</h2> |
917 | 1001 | </div> |
918 | 1002 | </div>` : ''} |
919 | 1003 |
|
| 1004 | + ${renderConfigs(cam)} |
| 1005 | +
|
920 | 1006 | ${cam.sources?.length ? ` |
921 | 1007 | <div class="drawer-section"> |
922 | 1008 | <div class="drawer-section-title">Sources</div> |
|
0 commit comments