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 +6 -0
- package/components/layout/burger.vue +4 -5
- package/components/layout/header.vue +8 -0
- package/components/upload/main.vue +1 -7
- package/components/upload/picker.vue +6 -67
- package/composables/use-upload-entry.ts +33 -0
- package/i18n/locales/en-US.json +1 -1
- package/package.json +1 -1
- package/runtime/constants/upload.ts +0 -1
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:
|
|
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 {
|
|
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 {
|
|
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
|
+
}
|
package/i18n/locales/en-US.json
CHANGED
|
@@ -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