2222 .header .tab .active { color : var (--text-main ); border-bottom-color : var (--accent-color ); }
2323
2424 .main-container { display : flex; flex-grow : 1 ; overflow : hidden; }
25- .view-container { flex-grow : 1 ; padding : 10px ; }
26- # grid-container { width : 100% ; height : 100% ; display : grid; grid-template-columns : repeat (2 , 1fr ); grid-template-rows : repeat (2 , 1fr ); gap : 10px ; }
27- .grid-cell { position : relative; background-color : var (--bg-dark ); border-radius : 4px ; display : flex; flex-direction : column; justify-content : center; align-items : center; color : var (--text-secondary ); border : 1px solid var (--border-color ); cursor : default; text-align : center; transition : background-color 0.2s , border-color 0.2s ; }
25+ .view-container { flex-grow : 1 ; padding : 10px ; overflow-y : auto; }
26+ # grid-container { width : 100% ; display : grid; grid-template-columns : repeat (2 , 1fr ); gap : 10px ; }
27+ .grid-cell {
28+ position : relative;
29+ background-color : var (--bg-dark );
30+ border-radius : 4px ;
31+ display : flex;
32+ flex-direction : column;
33+ justify-content : center;
34+ align-items : center;
35+ color : var (--text-secondary );
36+ border : 1px solid var (--border-color );
37+ cursor : default;
38+ text-align : center;
39+ transition : background-color 0.2s , border-color 0.2s ;
40+ aspect-ratio : 16 / 9 ;
41+ }
2842 .grid-cell .drag-over { border : 2px dashed var (--accent-color ); background-color : var (--bg-light ); }
2943 .grid-cell canvas { width : 100% ; height : 100% ; object-fit : contain; border-radius : 4px ; }
3044 .grid-cell .active { border : 2px solid var (--accent-color ); }
3953 .sidebar { width : var (--sidebar-width ); background-color : var (--bg-dark ); border-left : 1px solid var (--border-color ); display : flex; flex-direction : column; }
4054 .sidebar-header { padding : 10px ; border-bottom : 1px solid var (--border-color ); display : flex; justify-content : space-between; align-items : center; flex-shrink : 0 ; }
4155 .sidebar-header h3 { margin : 0 ; font-size : 1em ; }
56+ .sidebar-header .header-buttons { display : flex; gap : 5px ; }
4257 .sidebar-header .icon-button { background : none; border : none; color : var (--text-secondary ); cursor : pointer; padding : 4px ; border-radius : 50% ; display : flex; align-items : center; }
4358 .sidebar-header .icon-button : hover { color : var (--text-main ); background-color : var (--bg-light ); }
44- # camera-list { list-style : none; padding : 10px ; margin : 0 ; flex-grow : 1 ; overflow-y : auto; }
59+
60+ # camera-list-container { overflow-y : auto; flex-grow : 1 ; }
61+ .group-container { margin-bottom : 10px ; padding : 0 5px ; }
62+ .group-header { display : flex; align-items : center; cursor : pointer; padding : 5px ; border-radius : 4px ; }
63+ .group-header : hover { background-color : var (--bg-light ); }
64+ .group-header .toggle-icon { font-size : 20px ; transition : transform 0.2s ; user-select : none; }
65+ .group-header .toggle-icon .collapsed { transform : rotate (-90deg ); }
66+ .group-header .group-name { font-weight : bold; margin-left : 5px ; }
67+ .group-cameras { padding-left : 10px ; overflow : hidden; max-height : 1000px ; transition : max-height 0.3s ease-in-out, padding 0.3s ease-in-out; }
68+ .group-cameras .collapsed { max-height : 0 ; padding-top : 0 ; padding-bottom : 0 ; }
4569 .camera-item { padding : 8px ; border-radius : 4px ; margin-bottom : 5px ; cursor : grab; display : flex; align-items : center; gap : 8px ; }
4670 .camera-item : hover { background-color : var (--bg-light ); }
4771 .status-icon { width : 10px ; height : 10px ; border-radius : 50% ; background-color : # 6c757d ; flex-shrink : 0 ; }
92116 < div class ="sidebar ">
93117 < div class ="sidebar-header ">
94118 < h3 > Устройства</ h3 >
95- < button id ="add-camera-sidebar-btn " class ="icon-button " title ="Добавить новую камеру "> < i class ="material-icons "> add_circle_outline</ i > </ button >
119+ < div class ="header-buttons ">
120+ < button id ="add-group-btn " class ="icon-button " title ="Создать новую группу "> < i class ="material-icons "> create_new_folder</ i > </ button >
121+ < button id ="add-camera-sidebar-btn " class ="icon-button " title ="Добавить новую камеру "> < i class ="material-icons "> add_circle_outline</ i > </ button >
122+ </ div >
96123 </ div >
97- < ul id ="camera-list "> </ ul >
124+ < div id ="camera-list-container "> </ div >
98125 </ div >
99126 </ div >
100127 < div class ="bottom-toolbar ">
101128 < div class ="status-info " id ="status-info "> CPU: -- | RAM: --</ div >
102129 < div class ="toolbar-group " id ="layout-controls "> </ div >
103130 </ div >
104131
132+ <!-- +++ МОДАЛЬНЫЕ ОКНА ПЕРЕМЕЩЕНЫ СЮДА, В КОНЕЦ BODY +++ -->
105133 < div id ="add-camera-modal " class ="modal-backdrop hidden ">
106134 < div class ="modal-content ">
107135 < span id ="add-modal-close-btn " class ="modal-close-btn "> ×</ span >
@@ -158,14 +186,7 @@ <h3>System</h3>
158186 < span > HTTPS порт</ span > < input type ="number " id ="system.httpsPort " min ="1 " max ="65535 ">
159187 < span class ="full-width "> Путь к SSL сертификату</ span > < input type ="text " id ="system.httpsCertificate " class ="full-width ">
160188 < span class ="full-width "> Путь к SSL ключу</ span > < input type ="text " id ="system.httpsCertificateKey " class ="full-width ">
161- < span > Уровень логов</ span >
162- < select id ="system.logLevel ">
163- < option value ="verbose "> Verbose</ option >
164- < option value ="debug "> Debug</ option >
165- < option value ="info "> Info</ option >
166- < option value ="warning "> Warning</ option >
167- < option value ="error "> Error</ option >
168- </ select >
189+ < span > Уровень логов</ span > < select id ="system.logLevel "> < option value ="verbose "> Verbose</ option > < option value ="debug "> Debug</ option > < option value ="info "> Info</ option > < option value ="warning "> Warning</ option > < option value ="error "> Error</ option > </ select >
169190 < span > Отключить авторизацию</ span > < input type ="checkbox " id ="system.unsafe ">
170191 < span > Макс. размер буфера (KB)</ span > < input type ="number " id ="system.buffer ">
171192 < span > Включить плагины</ span > < input type ="checkbox " id ="system.plugins ">
@@ -177,15 +198,11 @@ <h3>ISP (Процессор изображений)</h3>
177198 < span > Сжатие динам. диапазона</ span > < input type ="number " id ="isp.drc ">
178199 < span class ="full-width "> Конфиг. файл сенсора</ span > < input type ="text " id ="isp.sensorConfig " class ="full-width ">
179200 < span class ="full-width "> Профиль кач-ва изобр.</ span > < input type ="text " id ="isp.iqProfile " class ="full-width ">
180- < span > Подавление мерцания</ span >
181- < select id ="isp.antiFlicker "> < option value ="disabled "> Disabled</ option > < option value ="50 "> 50 Hz</ option > < option value ="60 "> 60 Hz</ option > </ select >
182- < span > Медленный затвор</ span >
183- < select id ="isp.slowShutter "> < option value ="disabled "> Disabled</ option > < option value ="low "> Low</ option > < option value ="medium "> Medium</ option > < option value ="high "> High</ option > </ select >
184- < span > Режим RAW</ span >
185- < select id ="isp.rawMode "> < option value ="none "> None</ option > < option value ="slow "> Slow</ option > < option value ="fast "> Fast</ option > </ select >
201+ < span > Подавление мерцания</ span > < select id ="isp.antiFlicker "> < option value ="disabled "> Disabled</ option > < option value ="50 "> 50 Hz</ option > < option value ="60 "> 60 Hz</ option > </ select >
202+ < span > Медленный затвор</ span > < select id ="isp.slowShutter "> < option value ="disabled "> Disabled</ option > < option value ="low "> Low</ option > < option value ="medium "> Medium</ option > < option value ="high "> High</ option > </ select >
203+ < span > Режим RAW</ span > < select id ="isp.rawMode "> < option value ="none "> None</ option > < option value ="slow "> Slow</ option > < option value ="fast "> Fast</ option > </ select >
186204 < span > Блоки памяти для кодера</ span > < input type ="number " id ="isp.blkCnt ">
187- < span > Режим памяти</ span >
188- < select id ="isp.memMode "> < option value ="normal "> Normal</ option > < option value ="reduction "> Reduction</ option > </ select >
205+ < span > Режим памяти</ span > < select id ="isp.memMode "> < option value ="normal "> Normal</ option > < option value ="reduction "> Reduction</ option > </ select >
189206 < span > Цифр. стаб. изображения</ span > < input type ="checkbox " id ="isp.dis ">
190207 < span > Зеркало (ISP)</ span > < input type ="checkbox " id ="isp.mirror ">
191208 < span > Переворот (ISP)</ span > < input type ="checkbox " id ="isp.flip ">
@@ -246,7 +263,7 @@ <h3>JPEG поток</h3>
246263 </ div >
247264 </ div >
248265 < div id ="tab-osd " class ="tab-content ">
249- < h3 > OSD (On-Screen Display) </ h3 >
266+ < h3 > OSD</ h3 >
250267 < div class ="form-grid ">
251268 < span > Включить OSD</ span > < input type ="checkbox " id ="osd.enabled ">
252269 < span class ="full-width "> Шаблон</ span > < input type ="text " id ="osd.template " class ="full-width ">
@@ -261,7 +278,7 @@ <h3>OSD (On-Screen Display)</h3>
261278 < h3 > Аудио</ h3 >
262279 < div class ="form-grid ">
263280 < span > Включено</ span > < input type ="checkbox " id ="audio.enabled ">
264- < span > Кодек</ span > < select id ="audio.codec "> < option value ="opus "> Opus</ option > < option value ="aac "> AAC</ option > < option value ="pcm "> PCM</ option > < option value ="alaw "> G.711A (alaw) </ option > < option value ="ulaw "> G.711U (ulaw) </ option > </ select >
281+ < span > Кодек</ span > < select id ="audio.codec "> < option value ="opus "> Opus</ option > < option value ="aac "> AAC</ option > < option value ="pcm "> PCM</ option > < option value ="alaw "> G.711A</ option > < option value ="ulaw "> G.711U</ option > </ select >
265282 < span > Частота</ span > < select id ="audio.srate "> < option value ="8000 "> 8000 Hz</ option > < option value ="16000 "> 16000 Hz</ option > < option value ="32000 "> 32000 Hz</ option > < option value ="48000 "> 48000 Hz</ option > </ select >
266283 < span > Громкость входа</ span > < input type ="number " id ="audio.volume " min ="0 " max ="100 ">
267284 < span > Двойной микрофон</ span > < input type ="checkbox " id ="audio.dual ">
@@ -272,7 +289,7 @@ <h3>Аудио</h3>
272289 </ div >
273290 </ div >
274291 < div id ="tab-rtsp " class ="tab-content ">
275- < h3 > RTSP сервер </ h3 >
292+ < h3 > RTSP</ h3 >
276293 < div class ="form-grid ">
277294 < span > Включен</ span > < input type ="checkbox " id ="rtsp.enabled ">
278295 < span > Порт</ span > < input type ="number " id ="rtsp.port ">
@@ -353,6 +370,21 @@ <h3>NETIP</h3>
353370 < div id ="settings-toast " class ="toast-notification "> </ div >
354371 </ div >
355372 </ div >
373+
374+ < div id ="add-group-modal " class ="modal-backdrop hidden ">
375+ < div class ="modal-content ">
376+ < span id ="add-group-modal-close-btn " class ="modal-close-btn "> ×</ span >
377+ < h2 id ="add-group-modal-title "> Создать новую группу</ h2 >
378+ < div class ="form-grid simple ">
379+ < b > Название:</ b > < input type ="text " id ="new-group-name " placeholder ="Моя новая группа ">
380+ < b > </ b >
381+ < div class ="form-buttons ">
382+ < button id ="save-group-btn "> Сохранить</ button >
383+ < button id ="cancel-group-btn " style ="background-color: #6c757d; "> Отмена</ button >
384+ </ div >
385+ </ div >
386+ </ div >
387+ </ div >
356388
357389 < script src ="jsmpeg.min.js "> </ script >
358390 < script src ="./renderer.js "> </ script >
0 commit comments