itube-specs 0.0.1072 → 0.0.1073

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.
package/SITE_UPDATES.md CHANGED
@@ -11,6 +11,12 @@
11
11
  коммиты до бампа); `npm run patch` сам проставит ей номер версии. Формат пункта: что сделать и где,
12
12
  кому именно (всем / сайтам с N), что будет, если не сделать.
13
13
 
14
+ ## 0.0.1073 — 2026-11-03
15
+
16
+ - **Всем — к сведению:** гость больше не видит заглушку «Sign in to upload» на `/upload`: клик по Upload (шапка,
17
+ бургер) и по выбору файла открывает попап регистрации с пояснением (новый общий ключ `register_to_upload`, пока
18
+ только en-US), после входа — сразу `/upload`. Делать ничего не надо.
19
+
14
20
  ## 0.0.1071 — 2026-11-03
15
21
 
16
22
  - **Сайтам со своей темой в `assets/scss/vars/_theme.scss` (hd-sex-new), срочно:** без новых токенов сборка падает
@@ -162,6 +162,7 @@ function logOut() {
162
162
  }
163
163
 
164
164
  const featureFlags = useRuntimeConfig().public.featureFlags;
165
+ const { requireAuth } = useUploadEntry();
165
166
 
166
167
  const burgerButtons = computed<{ icon: string, label: string, action?: () => void, link?: string }[]>(() => [
167
168
  ...isAuthorized.value ? [
@@ -184,11 +185,9 @@ const burgerButtons = computed<{ icon: string, label: string, action?: () => voi
184
185
  },
185
186
  ],
186
187
  ...featureFlags.FeatureUploadEnabled ? [
187
- {
188
- icon: 'upload',
189
- label: 'upload',
190
- link: generateLink('/upload'),
191
- }
188
+ isAuthorized.value
189
+ ? { icon: 'upload', label: 'upload', link: generateLink('/upload') }
190
+ : { icon: 'upload', label: 'upload', action: () => requireAuth() },
192
191
  ] : [],
193
192
  ]);
194
193
 
@@ -63,6 +63,7 @@
63
63
  :tabindex="isUploadPage ? -1 : undefined"
64
64
  :class="{'--current': isUploadPage}"
65
65
  class="layout-header__upload _from-sd"
66
+ @click="onUploadClick"
66
67
  >
67
68
  <UiIcon
68
69
  name="upload-arrow"
@@ -122,6 +123,13 @@ const route = useRoute();
122
123
  const { generateLink } = useGenerateLink();
123
124
 
124
125
  const uploadLink = computed(() => generateLink('/upload'));
126
+ const { requireAuth, watchUploadEntry } = useUploadEntry();
127
+
128
+ watchUploadEntry();
129
+
130
+ function onUploadClick(event: MouseEvent) {
131
+ if (!requireAuth()) event.preventDefault();
132
+ }
125
133
  const isUploadPage = computed(() => route.path === uploadLink.value);
126
134
 
127
135
  const burgerShow = ref(false);
@@ -67,10 +67,8 @@
67
67
 
68
68
  <script setup lang="ts">
69
69
  import { UploadAccount, UploadStage } from '../../runtime';
70
- import { AuthorizationApiService } from '../../services/api/authorization.service';
71
70
 
72
71
  const { t } = useI18n();
73
- const { isAuthorized } = useUser(AuthorizationApiService);
74
72
 
75
73
  const {
76
74
  stage,
@@ -96,11 +94,7 @@ const isRulesOpen = ref(false);
96
94
 
97
95
  const isPick = computed(() => stage.value === UploadStage.Pick);
98
96
 
99
- const account = computed(() => {
100
- if (!isAuthorized.value) return UploadAccount.SignedOut;
101
-
102
- return remaining.value > 0 ? UploadAccount.Ok : UploadAccount.Limit;
103
- });
97
+ const account = computed(() => remaining.value > 0 ? UploadAccount.Ok : UploadAccount.Limit);
104
98
 
105
99
  function onBeforeUnload(event: BeforeUnloadEvent) {
106
100
  if (!isUploading.value) return;
@@ -1,34 +1,6 @@
1
- <!-- First upload step: sign-in gate, drop zone (desktop) or file button (mobile), requirement checks of the picked file -->
1
+ <!-- First upload step: drop zone (desktop) or file button (mobile), requirement checks of the picked file; a guest gets the auth popup instead of the file dialog -->
2
2
  <template>
3
- <div
4
- v-if="account === UploadAccount.SignedOut"
5
- class="upload-picker__gate"
6
- >
7
- <UiIcon
8
- class="upload-picker__gate-icon"
9
- name="lock"
10
- size="24"
11
- aria-hidden="true"
12
- />
13
- <p class="upload-picker__gate-title">{{ t('upload_page.sign_in') }}</p>
14
- <div class="upload-picker__gate-buttons">
15
- <UiBtn
16
- theme="primary"
17
- @click="openAuthPopup(AuthSteps.Registration)"
18
- >{{ t('auth.sign_up') }}
19
- </UiBtn>
20
- <UiBtn
21
- theme="muted"
22
- @click="openAuthPopup(AuthSteps.Login)"
23
- >{{ t('auth.log_in') }}
24
- </UiBtn>
25
- </div>
26
- </div>
27
-
28
- <div
29
- v-else
30
- class="upload-picker"
31
- >
3
+ <div class="upload-picker">
32
4
  <div class="upload-picker__mobile _to-sd">
33
5
  <UiBtn
34
6
  :disabled="isDisabled"
@@ -120,7 +92,7 @@
120
92
  </template>
121
93
 
122
94
  <script setup lang="ts">
123
- import { AuthSteps, UPLOAD_LIMITS, UploadAccount, UploadCheckStatus } from '../../runtime';
95
+ import { UPLOAD_LIMITS, UploadAccount, UploadCheckStatus } from '../../runtime';
124
96
  import type { IUploadFile } from '../../types';
125
97
  import { checkUploadFile } from '../../utils/upload/check-upload-file';
126
98
  import { createIdleUploadChecks } from '../../utils/upload/create-idle-upload-checks';
@@ -135,7 +107,7 @@ const emit = defineEmits<{
135
107
  }>();
136
108
 
137
109
  const { t } = useI18n();
138
- const { openAuthPopup } = useAuthPopup();
110
+ const { requireAuth } = useUploadEntry();
139
111
 
140
112
  const inputRef = ref<HTMLInputElement>();
141
113
  const isDragging = ref(false);
@@ -158,7 +130,7 @@ const zoneLabel = computed(() => {
158
130
  });
159
131
 
160
132
  function openDialog() {
161
- inputRef.value?.click();
133
+ if (requireAuth()) inputRef.value?.click();
162
134
  }
163
135
 
164
136
  async function check(file?: File) {
@@ -182,7 +154,7 @@ function onDragOver() {
182
154
 
183
155
  function onDrop(event: DragEvent) {
184
156
  isDragging.value = false;
185
- check(event.dataTransfer?.files[0]);
157
+ if (requireAuth()) check(event.dataTransfer?.files[0]);
186
158
  }
187
159
 
188
160
  function onChange(event: Event) {
@@ -283,37 +255,4 @@ function onChange(event: Event) {
283
255
  color: $upload-text;
284
256
  font-variant-numeric: tabular-nums;
285
257
  }
286
-
287
- .upload-picker__gate {
288
- display: flex;
289
- flex-direction: column;
290
- justify-content: center;
291
- align-items: center;
292
- gap: 16px;
293
- min-height: 180px;
294
- padding: 24px;
295
- text-align: center;
296
- background-color: $upload-card-bg;
297
- border-radius: $radius-12;
298
-
299
- @include from-br(sm) {
300
- min-height: 220px;
301
- }
302
- }
303
-
304
- .upload-picker__gate-icon {
305
- color: $upload-text;
306
- }
307
-
308
- .upload-picker__gate-title {
309
- @include font-base;
310
-
311
- font-weight: 500;
312
- color: $upload-title;
313
- }
314
-
315
- .upload-picker__gate-buttons {
316
- display: flex;
317
- gap: 8px;
318
- }
319
258
  </style>
@@ -0,0 +1,33 @@
1
+ import { AuthSteps } from '../runtime';
2
+ import { AuthorizationApiService } from '../services/api/authorization.service';
3
+
4
+ /**
5
+ * Entry to the upload page for guests: instead of a sign-in placeholder the auth popup opens with an explanation,
6
+ * and after a successful login the user lands on `/upload`. `watchUploadEntry` is called once, by the header.
7
+ */
8
+ export function useUploadEntry() {
9
+ const { isAuthorized } = useUser(AuthorizationApiService);
10
+ const { isAuthPopupOpen, openAuthPopup } = useAuthPopup();
11
+ const { generateLink } = useGenerateLink();
12
+ const isPending = useState('upload-entry-pending', () => false);
13
+
14
+ function requireAuth() {
15
+ if (isAuthorized.value) return true;
16
+
17
+ isPending.value = true;
18
+ openAuthPopup(AuthSteps.Registration, 'register_to_upload');
19
+
20
+ return false;
21
+ }
22
+
23
+ function watchUploadEntry() {
24
+ watch(isAuthPopupOpen, (isOpen) => {
25
+ if (isOpen || !isPending.value) return;
26
+
27
+ isPending.value = false;
28
+ if (isAuthorized.value) navigateTo(generateLink('/upload'));
29
+ });
30
+ }
31
+
32
+ return { requireAuth, watchUploadEntry };
33
+ }
@@ -1,4 +1,5 @@
1
1
  {
2
+ "register_to_upload": "Please sign up or log in to upload your videos",
2
3
  "age_gate": {
3
4
  "thumb": "18+",
4
5
  "title": "Laws in your region require age verification to view 18+ content",
@@ -58,7 +59,6 @@
58
59
  "title_details": "Video details",
59
60
  "subtitle_pick": "Pick a file. You'll add models and tags while it uploads.",
60
61
  "subtitle_details": "Your video keeps uploading while you fill this in.",
61
- "sign_in": "Sign in to upload",
62
62
  "drag": "Drag a video here",
63
63
  "drag_another": "Drag another video here",
64
64
  "checking_video": "Checking video...",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "itube-specs",
3
3
  "type": "module",
4
- "version": "0.0.1072",
4
+ "version": "0.0.1073",
5
5
  "main": "./nuxt.config.ts",
6
6
  "types": "./types/index.d.ts",
7
7
  "scripts": {
@@ -18,7 +18,6 @@ export type UploadStatus = typeof UploadStatus[keyof typeof UploadStatus];
18
18
 
19
19
  export const UploadAccount = {
20
20
  Ok: 'ok',
21
- SignedOut: 'signed-out',
22
21
  Limit: 'limit',
23
22
  } as const;
24
23