itube-specs 0.0.826 → 0.0.830

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -250,7 +250,7 @@ const options = computed<Omit<PlayerOptions, 'source'>>(() => ({
250
250
  },
251
251
  icons: PLAYER_ICONS,
252
252
  // Заголовок дропдауна выбора типа сцен (дефолт «Scene type»).
253
- labels: { sceneTypes: t('timeline_markers') },
253
+ labels: { sceneTypes: t('jump_to') },
254
254
  // Запоминаем громкость/mute в localStorage.
255
255
  persist: { key: PLAYER_PERSIST_KEY },
256
256
  }));
@@ -3,161 +3,163 @@
3
3
  колбэками, которые сами применяют выбор. Рендерим её в нашем ui-popup (--sheet).
4
4
  Дрилл «Настройки → Скорость/Качество» — через стек drill с кнопкой «назад». -->
5
5
  <template>
6
- <UiPopup
7
- v-if="open && request"
8
- v-model="open"
9
- sheet
10
- :back="!!drill"
11
- class="player-menu"
12
- @back="drill = null"
13
- >
14
- <template #title>
15
- {{ drill?.label ?? request.title }}
16
- </template>
17
-
18
- <!-- Дрилл: опции одной настройки (скорость / качество / субтитры) -->
19
- <ul
20
- v-if="drill"
21
- class="player-menu__options"
6
+ <transition mode="out-in">
7
+ <UiPopup
8
+ v-if="open && request"
9
+ v-model="open"
10
+ sheet
11
+ :back="!!drill"
12
+ class="player-menu"
13
+ @back="drill = null"
22
14
  >
23
- <li
24
- v-for="option in drill.options"
25
- :key="option.value"
15
+ <template #title>
16
+ {{ drill?.label ?? request.title }}
17
+ </template>
18
+
19
+ <!-- Дрилл: опции одной настройки (скорость / качество / субтитры) -->
20
+ <ul
21
+ v-if="drill"
22
+ class="player-menu__options"
26
23
  >
27
- <button
28
- :class="{ '--active': option.active }"
29
- class="player-menu__option"
30
- type="button"
31
- @click="pick(drill.select, option.value)"
24
+ <li
25
+ v-for="option in drill.options"
26
+ :key="option.value"
32
27
  >
33
- {{ option.label }}
34
- </button>
35
- </li>
36
- </ul>
37
-
38
- <!-- Шестерёнка: тоглы + строки-дриллы -->
39
- <ul
40
- v-else-if="request.kind === 'settings'"
41
- class="player-menu__rows"
42
- >
43
- <li
44
- v-for="entry in request.entries"
45
- :key="entry.key"
46
- class="player-menu__row"
28
+ <button
29
+ :class="{ '--active': option.active }"
30
+ class="player-menu__option"
31
+ type="button"
32
+ @click="pick(drill.select, option.value)"
33
+ >
34
+ {{ option.label }}
35
+ </button>
36
+ </li>
37
+ </ul>
38
+
39
+ <!-- Шестерёнка: тоглы + строки-дриллы -->
40
+ <ul
41
+ v-else-if="request.kind === 'settings'"
42
+ class="player-menu__rows"
47
43
  >
48
- <div
49
- v-if="entry.toggle"
50
- class="player-menu__toggle-row"
44
+ <li
45
+ v-for="entry in request.entries"
46
+ :key="entry.key"
47
+ class="player-menu__row"
51
48
  >
52
- <span class="player-menu__label">{{ entry.label }}</span>
53
- <UiToggle
54
- :model-value="entry.toggle.value"
55
- @update:model-value="entry.toggle.set(!!$event)"
56
- />
57
- </div>
58
- <button
59
- v-else-if="entry.options && entry.select"
60
- class="player-menu__row-btn"
61
- type="button"
62
- @click="drill = { label: entry.label, options: entry.options, select: entry.select }"
63
- >
64
- <span class="player-menu__label">{{ entry.label }}</span>
65
- <span class="player-menu__value">
66
- {{ entry.value }}
67
- <UiIcon
68
- name="angle-right"
69
- size="16"
49
+ <div
50
+ v-if="entry.toggle"
51
+ class="player-menu__toggle-row"
52
+ >
53
+ <span class="player-menu__label">{{ entry.label }}</span>
54
+ <UiToggle
55
+ :model-value="entry.toggle.value"
56
+ @update:model-value="entry.toggle.set(!!$event)"
70
57
  />
71
- </span>
72
- </button>
73
- <div
74
- v-else
75
- class="player-menu__toggle-row"
76
- >
77
- <span class="player-menu__label">{{ entry.label }}</span>
78
- <span class="player-menu__value">{{ entry.value }}</span>
79
- </div>
80
- </li>
81
- </ul>
82
-
83
- <!-- Тайм-коды: аккордеон типов сцен -->
84
- <ul
85
- v-else-if="request.kind === 'sceneTypes'"
86
- class="player-menu__groups"
87
- >
88
- <li
89
- v-for="group in request.groups"
90
- :key="group.id"
58
+ </div>
59
+ <button
60
+ v-else-if="entry.options && entry.select"
61
+ class="player-menu__row-btn"
62
+ type="button"
63
+ @click="drill = { label: entry.label, options: entry.options, select: entry.select }"
64
+ >
65
+ <span class="player-menu__label">{{ entry.label }}</span>
66
+ <span class="player-menu__value">
67
+ {{ entry.value }}
68
+ <UiIcon
69
+ name="chevron-right"
70
+ size="16"
71
+ />
72
+ </span>
73
+ </button>
74
+ <div
75
+ v-else
76
+ class="player-menu__toggle-row"
77
+ >
78
+ <span class="player-menu__label">{{ entry.label }}</span>
79
+ <span class="player-menu__value">{{ entry.value }}</span>
80
+ </div>
81
+ </li>
82
+ </ul>
83
+
84
+ <!-- Тайм-коды: аккордеон типов сцен -->
85
+ <ul
86
+ v-else-if="request.kind === 'sceneTypes'"
87
+ class="player-menu__groups"
91
88
  >
92
- <details
93
- :open="group.active"
94
- class="player-menu__group"
95
- @toggle="onGroupToggle($event, group)"
89
+ <li
90
+ v-for="group in request.groups"
91
+ :key="group.id"
96
92
  >
97
- <summary class="player-menu__summary">
98
- <span
99
- v-if="iconSvg(group.icon)"
100
- class="player-menu__summary-icon"
101
- v-html="iconSvg(group.icon)"
102
- />
103
- <span class="player-menu__summary-title">{{ group.title }}</span>
104
- <UiIcon
105
- name="angle-right"
106
- size="16"
107
- class="player-menu__summary-arrow"
108
- />
109
- </summary>
110
- <ul class="player-menu__scenes">
93
+ <details
94
+ :open="group.active"
95
+ class="player-menu__group"
96
+ @toggle="onGroupToggle($event, group)"
97
+ >
98
+ <summary class="player-menu__summary">
99
+ <span
100
+ v-if="iconSvg(group.icon)"
101
+ class="player-menu__summary-icon"
102
+ v-html="iconSvg(group.icon)"
103
+ />
104
+ <span class="player-menu__summary-title">{{ group.title }}</span>
105
+ <UiIcon
106
+ name="chevron-down"
107
+ size="20"
108
+ class="player-menu__summary-arrow"
109
+ />
110
+ </summary>
111
+ <ul class="player-menu__scenes">
112
+ <li
113
+ v-for="scene in group.scenes"
114
+ :key="scene.start"
115
+ >
116
+ <button
117
+ :class="{ '--current': scene.current }"
118
+ class="player-menu__scene"
119
+ type="button"
120
+ @click="selectScene(group.id, scene.start)"
121
+ >
122
+ <span class="player-menu__scene-label">{{ scene.label }}</span>
123
+ <span class="player-menu__scene-time">{{ scene.time }}</span>
124
+ </button>
125
+ </li>
126
+ </ul>
127
+ </details>
128
+ </li>
129
+ </ul>
130
+
131
+ <!-- ⋯ и одиночные меню (скорость/качество/субтитры, если вынесены кнопками) -->
132
+ <template v-else-if="request.kind === 'menu'">
133
+ <section
134
+ v-for="(section, index) in request.sections"
135
+ :key="index"
136
+ class="player-menu__section"
137
+ >
138
+ <h3
139
+ v-if="section.title"
140
+ class="player-menu__section-title"
141
+ >
142
+ {{ section.title }}
143
+ </h3>
144
+ <ul class="player-menu__options">
111
145
  <li
112
- v-for="scene in group.scenes"
113
- :key="scene.start"
146
+ v-for="item in section.items"
147
+ :key="item.value"
114
148
  >
115
149
  <button
116
- :class="{ '--current': scene.current }"
117
- class="player-menu__scene"
150
+ :class="{ '--active': item.active }"
151
+ class="player-menu__option"
118
152
  type="button"
119
- @click="selectScene(group.id, scene.start)"
153
+ @click="pick(section.select, item.value)"
120
154
  >
121
- <span class="player-menu__scene-label">{{ scene.label }}</span>
122
- <span class="player-menu__scene-time">{{ scene.time }}</span>
155
+ {{ item.label }}
123
156
  </button>
124
157
  </li>
125
158
  </ul>
126
- </details>
127
- </li>
128
- </ul>
129
-
130
- <!-- ⋯ и одиночные меню (скорость/качество/субтитры, если вынесены кнопками) -->
131
- <template v-else-if="request.kind === 'menu'">
132
- <section
133
- v-for="(section, index) in request.sections"
134
- :key="index"
135
- class="player-menu__section"
136
- >
137
- <h3
138
- v-if="section.title"
139
- class="player-menu__section-title"
140
- >
141
- {{ section.title }}
142
- </h3>
143
- <ul class="player-menu__options">
144
- <li
145
- v-for="item in section.items"
146
- :key="item.value"
147
- >
148
- <button
149
- :class="{ '--active': item.active }"
150
- class="player-menu__option"
151
- type="button"
152
- @click="pick(section.select, item.value)"
153
- >
154
- {{ item.label }}
155
- </button>
156
- </li>
157
- </ul>
158
- </section>
159
- </template>
160
- </UiPopup>
159
+ </section>
160
+ </template>
161
+ </UiPopup>
162
+ </transition>
161
163
  </template>
162
164
 
163
165
  <script setup lang="ts">
@@ -213,12 +215,18 @@ function onGroupToggle(event: Event, group: SceneGroup): void {
213
215
  </script>
214
216
 
215
217
  <style lang="scss">
216
- // Фон шторки под нативную (bg-zinc-900); шапка/бордеры ui-popup уже совпадают (#0d0d0d, zinc-800).
218
+ // Фон шторки (bg-zinc-900); шапка/бордеры ui-popup уже совпадают с v0 (#0d0d0d, zinc-800).
217
219
  .player-menu .ui-popup__wrapper,
218
220
  .player-menu .ui-popup__content {
219
221
  background-color: $player-menu-bg;
220
222
  }
221
223
 
224
+ // Вертикальный воздух списка + safe-area снизу (py-2 pb-[env(safe-area-inset-bottom)] в v0).
225
+ // Сильный селектор — перебиваем padding:0 у .ui-popup--sheet на мобиле.
226
+ .player-menu.ui-popup[open].--sheet .ui-popup__content {
227
+ padding: 8px 0 calc(8px + env(safe-area-inset-bottom, 0px));
228
+ }
229
+
222
230
  .player-menu__rows,
223
231
  .player-menu__groups,
224
232
  .player-menu__options {
@@ -247,14 +255,26 @@ function onGroupToggle(event: Event, group: SceneGroup): void {
247
255
  }
248
256
  }
249
257
 
258
+ // Без слота лейбл ui-toggle нулевой ширины → абсолютный трек уезжает за padding шторки.
259
+ // Резервируем ширину контрола и перекрашиваем вкл-состояние в indigo (в v0 bg-indigo-500).
260
+ .player-menu .ui-toggle {
261
+ flex-shrink: 0;
262
+ width: 36px;
263
+ height: 20px;
264
+ }
265
+
266
+ .player-menu .ui-toggle.ui-toggle--checked::before {
267
+ background: $player-menu-toggle-bg--active;
268
+ }
269
+
250
270
  .player-menu__label {
251
- @include font-sm;
271
+ @include font-md;
252
272
 
253
273
  color: $player-menu-row-text;
254
274
  }
255
275
 
256
276
  .player-menu__value {
257
- @include font-sm;
277
+ @include font-md;
258
278
 
259
279
  display: inline-flex;
260
280
  align-items: center;
@@ -263,7 +283,7 @@ function onGroupToggle(event: Event, group: SceneGroup): void {
263
283
  }
264
284
 
265
285
  .player-menu__option {
266
- @include font-sm;
286
+ @include font-md;
267
287
 
268
288
  position: relative;
269
289
  display: flex;
@@ -301,8 +321,8 @@ function onGroupToggle(event: Event, group: SceneGroup): void {
301
321
  display: flex;
302
322
  align-items: center;
303
323
  gap: 10px;
304
- min-height: 52px;
305
- padding: 13px 20px;
324
+ min-height: 44px;
325
+ padding: 8px 20px;
306
326
  color: $player-menu-acc-head-text;
307
327
  cursor: pointer;
308
328
  list-style: none;
@@ -311,6 +331,10 @@ function onGroupToggle(event: Event, group: SceneGroup): void {
311
331
  &::-webkit-details-marker {
312
332
  display: none;
313
333
  }
334
+
335
+ @include hover(background-color) {
336
+ background-color: $player-menu-acc-head-bg--hover;
337
+ }
314
338
  }
315
339
 
316
340
  .player-menu__group[open] .player-menu__summary {
@@ -320,63 +344,82 @@ function onGroupToggle(event: Event, group: SceneGroup): void {
320
344
  .player-menu__summary-icon {
321
345
  display: grid;
322
346
  place-content: center;
323
- color: $player-menu-icon;
347
+ flex-shrink: 0;
324
348
 
325
349
  svg {
326
- width: 20px;
327
- height: 20px;
350
+ width: 16px;
351
+ height: 16px;
328
352
  }
329
353
  }
330
354
 
331
355
  .player-menu__summary-title {
332
- @include font-sm;
356
+ @include font-md;
333
357
 
334
358
  flex: 1;
359
+ font-weight: 500;
335
360
  overflow: hidden;
336
361
  text-overflow: ellipsis;
337
362
  white-space: nowrap;
338
363
  }
339
364
 
340
365
  .player-menu__summary-arrow {
366
+ margin-right: 12px;
341
367
  flex-shrink: 0;
342
368
  color: $player-menu-icon;
343
- transition: transform var(--transition);
369
+ transition: transform var(--transition), color var(--transition);
344
370
  }
345
371
 
346
372
  .player-menu__group[open] .player-menu__summary-arrow {
347
- transform: rotate(90deg);
373
+ color: $player-menu-icon--open;
374
+ transform: rotate(180deg);
375
+ }
376
+
377
+ .player-menu__scenes {
378
+ padding-bottom: 4px;
348
379
  }
349
380
 
350
381
  .player-menu__scene {
351
- @include font-sm;
382
+ @include font-md;
352
383
 
353
384
  position: relative;
354
385
  display: flex;
355
386
  align-items: center;
356
387
  justify-content: space-between;
357
- gap: 16px;
388
+ gap: 12px;
358
389
  width: 100%;
359
- min-height: 44px;
360
- padding: 10px 20px 10px 48px;
390
+ min-height: 48px;
391
+ padding: 6px 20px 6px 56px;
361
392
  color: $player-menu-scene-text;
362
393
 
363
- @include hover(background-color, color) {
394
+ @include hover(background-color) {
364
395
  background-color: $player-menu-scene-bg--hover;
365
- color: $player-menu-scene-text--current;
366
396
  }
367
397
  }
368
398
 
369
399
  .player-menu__scene.--current {
370
400
  background-color: $player-menu-scene-bg--current;
371
- color: $player-menu-scene-text--current;
372
- font-weight: 500;
373
- box-shadow: inset 3px 0 $player-menu-scene-bar--current;
401
+ }
402
+
403
+ .player-menu__scene.--current::before {
404
+ content: '';
405
+ position: absolute;
406
+ inset-block: 0;
407
+ left: 0;
408
+ width: 2px;
409
+ background-color: $player-menu-scene-bar--current;
374
410
  }
375
411
 
376
412
  .player-menu__scene-label {
413
+ flex: 1;
377
414
  overflow: hidden;
378
415
  text-overflow: ellipsis;
379
416
  white-space: nowrap;
417
+ text-align: left;
418
+ }
419
+
420
+ .player-menu__scene.--current .player-menu__scene-label {
421
+ font-weight: 500;
422
+ color: $player-menu-scene-text--current;
380
423
  }
381
424
 
382
425
  .player-menu__scene-time {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "itube-specs",
3
3
  "type": "module",
4
- "version": "0.0.826",
4
+ "version": "0.0.830",
5
5
  "main": "./nuxt.config.ts",
6
6
  "types": "./types/index.d.ts",
7
7
  "scripts": {