chore: update Angular TypeScript build info cache
This commit is contained in:
parent
2866d74b32
commit
23c9ec539e
2
.angular/cache/20.2.2/app/.tsbuildinfo
vendored
2
.angular/cache/20.2.2/app/.tsbuildinfo
vendored
File diff suppressed because one or more lines are too long
@ -100,8 +100,8 @@ import {
|
|||||||
DOCUMENT,
|
DOCUMENT,
|
||||||
IMAGE_CONFIG
|
IMAGE_CONFIG
|
||||||
} from "./chunk-FVA7C6JK.js";
|
} from "./chunk-FVA7C6JK.js";
|
||||||
import "./chunk-HWYXSU2G.js";
|
|
||||||
import "./chunk-JRFR6BLO.js";
|
import "./chunk-JRFR6BLO.js";
|
||||||
|
import "./chunk-HWYXSU2G.js";
|
||||||
import "./chunk-MARUHEWW.js";
|
import "./chunk-MARUHEWW.js";
|
||||||
import "./chunk-GOMI4DH3.js";
|
import "./chunk-GOMI4DH3.js";
|
||||||
export {
|
export {
|
||||||
|
@ -41,8 +41,8 @@ import {
|
|||||||
} from "./chunk-5DRVFSXL.js";
|
} from "./chunk-5DRVFSXL.js";
|
||||||
import "./chunk-OUSM42MY.js";
|
import "./chunk-OUSM42MY.js";
|
||||||
import "./chunk-FVA7C6JK.js";
|
import "./chunk-FVA7C6JK.js";
|
||||||
import "./chunk-HWYXSU2G.js";
|
|
||||||
import "./chunk-JRFR6BLO.js";
|
import "./chunk-JRFR6BLO.js";
|
||||||
|
import "./chunk-HWYXSU2G.js";
|
||||||
import "./chunk-MARUHEWW.js";
|
import "./chunk-MARUHEWW.js";
|
||||||
import "./chunk-GOMI4DH3.js";
|
import "./chunk-GOMI4DH3.js";
|
||||||
export {
|
export {
|
||||||
|
@ -498,8 +498,8 @@ import {
|
|||||||
ɵɵviewQuery,
|
ɵɵviewQuery,
|
||||||
ɵɵviewQuerySignal
|
ɵɵviewQuerySignal
|
||||||
} from "./chunk-FVA7C6JK.js";
|
} from "./chunk-FVA7C6JK.js";
|
||||||
import "./chunk-HWYXSU2G.js";
|
|
||||||
import "./chunk-JRFR6BLO.js";
|
import "./chunk-JRFR6BLO.js";
|
||||||
|
import "./chunk-HWYXSU2G.js";
|
||||||
import "./chunk-MARUHEWW.js";
|
import "./chunk-MARUHEWW.js";
|
||||||
import "./chunk-GOMI4DH3.js";
|
import "./chunk-GOMI4DH3.js";
|
||||||
export {
|
export {
|
||||||
|
@ -46,10 +46,10 @@ import {
|
|||||||
ɵɵgetInheritedFactory,
|
ɵɵgetInheritedFactory,
|
||||||
ɵɵlistener
|
ɵɵlistener
|
||||||
} from "./chunk-FVA7C6JK.js";
|
} from "./chunk-FVA7C6JK.js";
|
||||||
|
import "./chunk-JRFR6BLO.js";
|
||||||
import {
|
import {
|
||||||
forkJoin
|
forkJoin
|
||||||
} from "./chunk-HWYXSU2G.js";
|
} from "./chunk-HWYXSU2G.js";
|
||||||
import "./chunk-JRFR6BLO.js";
|
|
||||||
import {
|
import {
|
||||||
Subject,
|
Subject,
|
||||||
from,
|
from,
|
||||||
|
@ -41,8 +41,8 @@ import {
|
|||||||
} from "./chunk-H4LQPAO2.js";
|
} from "./chunk-H4LQPAO2.js";
|
||||||
import "./chunk-OUSM42MY.js";
|
import "./chunk-OUSM42MY.js";
|
||||||
import "./chunk-FVA7C6JK.js";
|
import "./chunk-FVA7C6JK.js";
|
||||||
import "./chunk-HWYXSU2G.js";
|
|
||||||
import "./chunk-JRFR6BLO.js";
|
import "./chunk-JRFR6BLO.js";
|
||||||
|
import "./chunk-HWYXSU2G.js";
|
||||||
import "./chunk-MARUHEWW.js";
|
import "./chunk-MARUHEWW.js";
|
||||||
import "./chunk-GOMI4DH3.js";
|
import "./chunk-GOMI4DH3.js";
|
||||||
export {
|
export {
|
||||||
|
@ -83,11 +83,11 @@ import {
|
|||||||
ɵɵqueryRefresh,
|
ɵɵqueryRefresh,
|
||||||
ɵɵsanitizeUrlOrResourceUrl
|
ɵɵsanitizeUrlOrResourceUrl
|
||||||
} from "./chunk-FVA7C6JK.js";
|
} from "./chunk-FVA7C6JK.js";
|
||||||
|
import "./chunk-JRFR6BLO.js";
|
||||||
import {
|
import {
|
||||||
defer,
|
defer,
|
||||||
isObservable
|
isObservable
|
||||||
} from "./chunk-HWYXSU2G.js";
|
} from "./chunk-HWYXSU2G.js";
|
||||||
import "./chunk-JRFR6BLO.js";
|
|
||||||
import {
|
import {
|
||||||
BehaviorSubject,
|
BehaviorSubject,
|
||||||
ConnectableObservable,
|
ConnectableObservable,
|
||||||
|
@ -1,61 +1,61 @@
|
|||||||
{
|
{
|
||||||
"hash": "23edc511",
|
"hash": "4a15fadf",
|
||||||
"configHash": "2277c002",
|
"configHash": "d859ec53",
|
||||||
"lockfileHash": "c86d7ad1",
|
"lockfileHash": "c86d7ad1",
|
||||||
"browserHash": "0d41a6ee",
|
"browserHash": "3b79ea76",
|
||||||
"optimized": {
|
"optimized": {
|
||||||
"@angular/common": {
|
"@angular/common": {
|
||||||
"src": "../../../../../../node_modules/@angular/common/fesm2022/common.mjs",
|
"src": "../../../../../../node_modules/@angular/common/fesm2022/common.mjs",
|
||||||
"file": "@angular_common.js",
|
"file": "@angular_common.js",
|
||||||
"fileHash": "ed7bea66",
|
"fileHash": "3cdf8c58",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
},
|
},
|
||||||
"@angular/common/http": {
|
"@angular/common/http": {
|
||||||
"src": "../../../../../../node_modules/@angular/common/fesm2022/http.mjs",
|
"src": "../../../../../../node_modules/@angular/common/fesm2022/http.mjs",
|
||||||
"file": "@angular_common_http.js",
|
"file": "@angular_common_http.js",
|
||||||
"fileHash": "d8740647",
|
"fileHash": "c729a905",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
},
|
},
|
||||||
"@angular/core": {
|
"@angular/core": {
|
||||||
"src": "../../../../../../node_modules/@angular/core/fesm2022/core.mjs",
|
"src": "../../../../../../node_modules/@angular/core/fesm2022/core.mjs",
|
||||||
"file": "@angular_core.js",
|
"file": "@angular_core.js",
|
||||||
"fileHash": "fc2503ca",
|
"fileHash": "262b482a",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
},
|
},
|
||||||
"@angular/forms": {
|
"@angular/forms": {
|
||||||
"src": "../../../../../../node_modules/@angular/forms/fesm2022/forms.mjs",
|
"src": "../../../../../../node_modules/@angular/forms/fesm2022/forms.mjs",
|
||||||
"file": "@angular_forms.js",
|
"file": "@angular_forms.js",
|
||||||
"fileHash": "36d0134e",
|
"fileHash": "08308e50",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
},
|
},
|
||||||
"@angular/platform-browser": {
|
"@angular/platform-browser": {
|
||||||
"src": "../../../../../../node_modules/@angular/platform-browser/fesm2022/platform-browser.mjs",
|
"src": "../../../../../../node_modules/@angular/platform-browser/fesm2022/platform-browser.mjs",
|
||||||
"file": "@angular_platform-browser.js",
|
"file": "@angular_platform-browser.js",
|
||||||
"fileHash": "c0c2a1fa",
|
"fileHash": "f61025b6",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
},
|
},
|
||||||
"@angular/router": {
|
"@angular/router": {
|
||||||
"src": "../../../../../../node_modules/@angular/router/fesm2022/router.mjs",
|
"src": "../../../../../../node_modules/@angular/router/fesm2022/router.mjs",
|
||||||
"file": "@angular_router.js",
|
"file": "@angular_router.js",
|
||||||
"fileHash": "381708ba",
|
"fileHash": "f2b90ce6",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
},
|
},
|
||||||
"@google/genai": {
|
"@google/genai": {
|
||||||
"src": "../../../../../../node_modules/@google/genai/dist/web/index.mjs",
|
"src": "../../../../../../node_modules/@google/genai/dist/web/index.mjs",
|
||||||
"file": "@google_genai.js",
|
"file": "@google_genai.js",
|
||||||
"fileHash": "a56c743a",
|
"fileHash": "3476d74f",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
},
|
},
|
||||||
"rxjs": {
|
"rxjs": {
|
||||||
"src": "../../../../../../node_modules/rxjs/dist/esm5/index.js",
|
"src": "../../../../../../node_modules/rxjs/dist/esm5/index.js",
|
||||||
"file": "rxjs.js",
|
"file": "rxjs.js",
|
||||||
"fileHash": "c69b23b3",
|
"fileHash": "df88f612",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
},
|
},
|
||||||
"rxjs/operators": {
|
"rxjs/operators": {
|
||||||
"src": "../../../../../../node_modules/rxjs/dist/esm5/operators/index.js",
|
"src": "../../../../../../node_modules/rxjs/dist/esm5/operators/index.js",
|
||||||
"file": "rxjs_operators.js",
|
"file": "rxjs_operators.js",
|
||||||
"fileHash": "56086c3c",
|
"fileHash": "8d5942d8",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -75,12 +75,12 @@
|
|||||||
"chunk-FVA7C6JK": {
|
"chunk-FVA7C6JK": {
|
||||||
"file": "chunk-FVA7C6JK.js"
|
"file": "chunk-FVA7C6JK.js"
|
||||||
},
|
},
|
||||||
"chunk-HWYXSU2G": {
|
|
||||||
"file": "chunk-HWYXSU2G.js"
|
|
||||||
},
|
|
||||||
"chunk-JRFR6BLO": {
|
"chunk-JRFR6BLO": {
|
||||||
"file": "chunk-JRFR6BLO.js"
|
"file": "chunk-JRFR6BLO.js"
|
||||||
},
|
},
|
||||||
|
"chunk-HWYXSU2G": {
|
||||||
|
"file": "chunk-HWYXSU2G.js"
|
||||||
|
},
|
||||||
"chunk-MARUHEWW": {
|
"chunk-MARUHEWW": {
|
||||||
"file": "chunk-MARUHEWW.js"
|
"file": "chunk-MARUHEWW.js"
|
||||||
},
|
},
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"hash": "bd8fc5b3",
|
"hash": "65ebd7bc",
|
||||||
"configHash": "d5bc65c8",
|
"configHash": "3d00a7fd",
|
||||||
"lockfileHash": "c86d7ad1",
|
"lockfileHash": "c86d7ad1",
|
||||||
"browserHash": "5244fe32",
|
"browserHash": "acdb5c3c",
|
||||||
"optimized": {},
|
"optimized": {},
|
||||||
"chunks": {}
|
"chunks": {}
|
||||||
}
|
}
|
BIN
db/newtube.db
BIN
db/newtube.db
Binary file not shown.
@ -561,6 +561,37 @@ r.get('/peertube/:instance/*', async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// -------------------- Generic video details (GET) --------------------
|
||||||
|
// Returns metadata such as title, description, uploader, thumbnail, duration and views for a provider/videoId
|
||||||
|
// Supports query params similar to download endpoints: instance (PeerTube), slug (Odysee), sourceUrl (direct)
|
||||||
|
r.get('/details/:provider/:videoId', async (req, res) => {
|
||||||
|
try {
|
||||||
|
const { provider, videoId } = req.params;
|
||||||
|
const instance = req.query.instance || undefined;
|
||||||
|
const slug = req.query.slug || undefined;
|
||||||
|
const sourceUrl = req.query.sourceUrl || undefined;
|
||||||
|
const url = providerUrlFrom(provider, videoId, { instance, slug, sourceUrl });
|
||||||
|
const raw = await youtubedl(url, { dumpSingleJson: true, noWarnings: true, noCheckCertificates: true, skipDownload: true });
|
||||||
|
const meta = (typeof raw === 'string') ? JSON.parse(raw || '{}') : (raw || {});
|
||||||
|
const out = {
|
||||||
|
videoId,
|
||||||
|
title: meta.title || '',
|
||||||
|
thumbnail: meta.thumbnail || (Array.isArray(meta.thumbnails) && meta.thumbnails.length ? meta.thumbnails[0].url : ''),
|
||||||
|
uploaderName: meta.uploader || meta.channel || '',
|
||||||
|
uploaderAvatar: '',
|
||||||
|
views: typeof meta.view_count === 'number' ? meta.view_count : (typeof meta.viewCount === 'number' ? meta.viewCount : 0),
|
||||||
|
duration: typeof meta.duration === 'number' ? meta.duration : 0,
|
||||||
|
uploadedDate: meta.upload_date ? new Date(meta.upload_date.replace(/(\d{4})(\d{2})(\d{2})/, '$1-$2-$3')).toISOString() : (meta.release_timestamp ? new Date(meta.release_timestamp * 1000).toISOString() : ''),
|
||||||
|
description: meta.description || meta.summary || '',
|
||||||
|
url,
|
||||||
|
type: 'video',
|
||||||
|
};
|
||||||
|
return res.json(out);
|
||||||
|
} catch (e) {
|
||||||
|
return res.status(500).json({ error: 'details_failed', details: String(e?.message || e) });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Download routes middleware (auth supports both Authorization header and cookies)
|
// Download routes middleware (auth supports both Authorization header and cookies)
|
||||||
r.use('/download', authMiddlewareCookieAware, downloadLimiter);
|
r.use('/download', authMiddlewareCookieAware, downloadLimiter);
|
||||||
|
|
||||||
|
@ -21,39 +21,41 @@
|
|||||||
<span [class.hidden]="collapsed">{{ 'nav.shorts' | t }}</span>
|
<span [class.hidden]="collapsed">{{ 'nav.shorts' | t }}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
<a routerLink="/library/subscriptions" routerLinkActive="bg-slate-800" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? ('nav.subscriptions' | t) : null">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" fill="currentColor"><path d="M4 4h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2zm0 2v12h16V6H4zm3 3h10v2H7V9zm0 4h7v2H7v-2z"/></svg>
|
|
||||||
<span [class.hidden]="collapsed">{{ 'nav.subscriptions' | t }}</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Vous -->
|
<!-- Vous -->
|
||||||
<div>
|
@if (isLoggedIn()) {
|
||||||
<div class="px-3 py-2 text-xs uppercase tracking-wide text-slate-400" [class.hidden]="collapsed">{{ 'nav.you' | t }}</div>
|
<div>
|
||||||
<ul class="space-y-1">
|
<div class="px-3 py-2 text-xs uppercase tracking-wide text-slate-400" [class.hidden]="collapsed">{{ 'nav.you' | t }}</div>
|
||||||
<li>
|
<ul class="space-y-1">
|
||||||
<a routerLink="/account/history" routerLinkActive="bg-slate-800" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? ('nav.history' | t) : null">
|
<li>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" fill="currentColor"><path d="M12 8a1 1 0 0 1 1 1v3.38l2.32 1.34a1 1 0 1 1-1 1.74l-2.82-1.63A1 1 0 0 1 11 13V9a1 1 0 0 1 1-1zm0-6a10 10 0 1 0 10 10 10.011 10.011 0 0 0-10-10z"/></svg>
|
<a routerLink="/library/subscriptions" routerLinkActive="bg-slate-800" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? ('nav.subscriptions' | t) : null">
|
||||||
<span [class.hidden]="collapsed">{{ 'nav.history' | t }}</span>
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" fill="currentColor"><path d="M4 4h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2zm0 2v12h16V6H4zm3 3h10v2H7V9zm0 4h7v2H7v-2z"/></svg>
|
||||||
</a>
|
<span [class.hidden]="collapsed">{{ 'nav.subscriptions' | t }}</span>
|
||||||
</li>
|
</a>
|
||||||
<li>
|
</li>
|
||||||
<a routerLink="/library/playlists" routerLinkActive="bg-slate-800" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? ('nav.playlists' | t) : null">
|
<li>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" fill="currentColor"><path d="M4 6h12v2H4V6zm0 4h12v2H4v-2zm0 4h8v2H4v-2zm14-6h2v8h-2v-8z"/></svg>
|
<a routerLink="/account/history" routerLinkActive="bg-slate-800" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? ('nav.history' | t) : null">
|
||||||
<span [class.hidden]="collapsed">{{ 'nav.playlists' | t }}</span>
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" fill="currentColor"><path d="M12 8a1 1 0 0 1 1 1v3.38l2.32 1.34a1 1 0 1 1-1 1.74l-2.82-1.63A1 1 0 0 1 11 13V9a1 1 0 0 1 1-1zm0-6a10 10 0 1 0 10 10 10.011 10.011 0 0 0-10-10z"/></svg>
|
||||||
</a>
|
<span [class.hidden]="collapsed">{{ 'nav.history' | t }}</span>
|
||||||
</li>
|
</a>
|
||||||
<li>
|
</li>
|
||||||
<a routerLink="/library/liked" routerLinkActive="bg-slate-800" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? ('nav.liked' | t) : null">
|
<li>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" fill="currentColor"><path d="M12 21s-6.716-4.248-9.193-6.725A6 6 0 0 1 12 5.414 6 6 0 0 1 21.193 14.275C18.716 16.752 12 21 12 21z"/></svg>
|
<a routerLink="/library/playlists" routerLinkActive="bg-slate-800" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? ('nav.playlists' | t) : null">
|
||||||
<span [class.hidden]="collapsed">{{ 'nav.liked' | t }}</span>
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" fill="currentColor"><path d="M4 6h12v2H4V6zm0 4h12v2H4v-2zm0 4h8v2H4v-2zm14-6h2v8h-2v-8z"/></svg>
|
||||||
</a>
|
<span [class.hidden]="collapsed">{{ 'nav.playlists' | t }}</span>
|
||||||
</li>
|
</a>
|
||||||
</ul>
|
</li>
|
||||||
</div>
|
<li>
|
||||||
|
<a routerLink="/library/liked" routerLinkActive="bg-slate-800" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? ('nav.liked' | t) : null">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" fill="currentColor"><path d="M12 21s-6.716-4.248-9.193-6.725A6 6 0 0 1 12 5.414 6 6 0 0 1 21.193 14.275C18.716 16.752 12 21 12 21z"/></svg>
|
||||||
|
<span [class.hidden]="collapsed">{{ 'nav.liked' | t }}</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
<!-- Fournisseurs -->
|
<!-- Fournisseurs -->
|
||||||
<div>
|
<div>
|
||||||
|
@ -3,6 +3,7 @@ import { CommonModule } from '@angular/common';
|
|||||||
import { RouterLink, RouterLinkActive } from '@angular/router';
|
import { RouterLink, RouterLinkActive } from '@angular/router';
|
||||||
import { InstanceService } from '../../services/instance.service';
|
import { InstanceService } from '../../services/instance.service';
|
||||||
import { ThemesService } from '../../services/themes.service';
|
import { ThemesService } from '../../services/themes.service';
|
||||||
|
import { AuthService } from '../../services/auth.service';
|
||||||
import { TranslatePipe } from '../../pipes/translate.pipe';
|
import { TranslatePipe } from '../../pipes/translate.pipe';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -14,8 +15,12 @@ import { TranslatePipe } from '../../pipes/translate.pipe';
|
|||||||
})
|
})
|
||||||
export class SidebarComponent {
|
export class SidebarComponent {
|
||||||
private instances = inject(InstanceService);
|
private instances = inject(InstanceService);
|
||||||
|
private auth = inject(AuthService);
|
||||||
themes = inject(ThemesService);
|
themes = inject(ThemesService);
|
||||||
|
|
||||||
|
// Check if user is logged in
|
||||||
|
isLoggedIn = computed(() => !!this.auth.currentUser());
|
||||||
|
|
||||||
provider = computed(() => this.instances.selectedProvider());
|
provider = computed(() => this.instances.selectedProvider());
|
||||||
providerLabel = computed(() => this.instances.selectedProviderLabel());
|
providerLabel = computed(() => this.instances.selectedProviderLabel());
|
||||||
// Providers with PeerTube last
|
// Providers with PeerTube last
|
||||||
|
@ -100,10 +100,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-4 bg-slate-800/70 p-4 rounded-lg">
|
<div class="mt-4 bg-slate-800/70 p-4 rounded-lg">
|
||||||
<p [class.line-clamp-3]="!showFullDescription()">{{ v.description }}</p>
|
<p class="whitespace-pre-wrap text-slate-300" [class.line-clamp-3]="!showFullDescription()">
|
||||||
<button (click)="toggleDescription()" class="text-red-400 hover:text-red-300 font-semibold mt-2">
|
{{ hasDescription() ? descriptionText() : 'Aucune description disponible.' }}
|
||||||
{{ showFullDescription() ? 'Show less' : 'Show more' }}
|
</p>
|
||||||
</button>
|
@if (showMoreAvailable()) {
|
||||||
|
<button (click)="toggleDescription()" class="text-red-400 hover:text-red-300 font-semibold mt-2">
|
||||||
|
{{ showFullDescription() ? 'Show less' : 'Show more' }}
|
||||||
|
</button>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Download Panel (shown only when logged in) -->
|
<!-- Download Panel (shown only when logged in) -->
|
||||||
|
@ -33,9 +33,30 @@ export class WatchComponent implements OnDestroy {
|
|||||||
private http = inject(HttpClient);
|
private http = inject(HttpClient);
|
||||||
private routeSubscription: Subscription;
|
private routeSubscription: Subscription;
|
||||||
|
|
||||||
|
// Choose correct API base: use dev proxy when UI runs on a different port than the backend
|
||||||
|
private apiBase(): string {
|
||||||
|
try {
|
||||||
|
const port = window?.location?.port || '';
|
||||||
|
// If not running on backend port, route through Angular proxy
|
||||||
|
return port && port !== '4000' ? '/proxy/api' : '/api';
|
||||||
|
} catch {
|
||||||
|
return '/api';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
video = signal<VideoDetail | null>(null);
|
video = signal<VideoDetail | null>(null);
|
||||||
loading = signal(true);
|
loading = signal(true);
|
||||||
showFullDescription = signal(false);
|
showFullDescription = signal(false);
|
||||||
|
// Prefer full description if available; otherwise fallback to shortDescription
|
||||||
|
descriptionText = computed(() => {
|
||||||
|
const v = this.video();
|
||||||
|
const full = (v?.description || '').trim();
|
||||||
|
if (full) return full;
|
||||||
|
const short = (v?.shortDescription || '').trim();
|
||||||
|
return short || '';
|
||||||
|
});
|
||||||
|
hasDescription = computed(() => this.descriptionText().length > 0);
|
||||||
|
showMoreAvailable = computed(() => this.descriptionText().length > 240);
|
||||||
|
|
||||||
summary = signal<string | null>(null);
|
summary = signal<string | null>(null);
|
||||||
isSummarizing = signal(false);
|
isSummarizing = signal(false);
|
||||||
@ -268,9 +289,30 @@ export class WatchComponent implements OnDestroy {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// For other providers rely on embed/placeholder
|
// For other providers, enrich details via backend using yt-dlp metadata when possible
|
||||||
this.loading.set(false);
|
const opts = this.buildProviderOpts();
|
||||||
this.loadRelatedSuggestions();
|
this.http.get<any>(`${this.apiBase()}/details/${encodeURIComponent(provider)}/${encodeURIComponent(id)}`, { params: opts as any }).subscribe({
|
||||||
|
next: (data) => {
|
||||||
|
this.video.update(v => v ? {
|
||||||
|
...v,
|
||||||
|
title: data?.title || v.title,
|
||||||
|
thumbnail: data?.thumbnail || v.thumbnail,
|
||||||
|
uploaderName: data?.uploaderName || v.uploaderName,
|
||||||
|
uploadedDate: data?.uploadedDate || v.uploadedDate,
|
||||||
|
views: typeof data?.views === 'number' ? data.views : v.views,
|
||||||
|
duration: typeof data?.duration === 'number' ? data.duration : v.duration,
|
||||||
|
description: (data?.description || v.description || v.shortDescription || ''),
|
||||||
|
url: data?.url || v.url,
|
||||||
|
} : v);
|
||||||
|
this.loading.set(false);
|
||||||
|
this.loadRelatedSuggestions();
|
||||||
|
},
|
||||||
|
error: () => {
|
||||||
|
// Fallback to existing placeholder
|
||||||
|
this.loading.set(false);
|
||||||
|
this.loadRelatedSuggestions();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record watch start
|
// Record watch start
|
||||||
|
Loading…
x
Reference in New Issue
Block a user