Upgrade to angular 18 & vite
This commit is contained in:
parent
ec33467261
commit
9772280e99
56 changed files with 4040 additions and 6319 deletions
2
.github/CONTRIBUTING.md
vendored
2
.github/CONTRIBUTING.md
vendored
|
@ -192,7 +192,7 @@ npm run dev
|
|||
|
||||
### Embed
|
||||
|
||||
The embed is a standalone application built using Webpack.
|
||||
The embed is a standalone application built using Vite.
|
||||
The generated files (HTML entrypoint and multiple JS and CSS files) are served by the PeerTube server (behind `localhost:9000/videos/embed/:videoUUID` or `localhost:9000/video-playlists/embed/:playlistUUID`).
|
||||
The following command will compile embed files and run the PeerTube server:
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
"lines-between-class-members": "off",
|
||||
"@typescript-eslint/lines-between-class-members": [ "off" ],
|
||||
"arrow-body-style": "off",
|
||||
"import/no-webpack-loader-syntax": "off",
|
||||
"no-underscore-dangle": "off",
|
||||
"n/no-callback-literal": "off",
|
||||
"@angular-eslint/component-selector": [
|
||||
|
|
|
@ -161,18 +161,23 @@
|
|||
},
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"builder": "@angular/build:application",
|
||||
"options": {
|
||||
"i18nMissingTranslation": "ignore",
|
||||
"localize": true,
|
||||
"outputPath": "dist",
|
||||
"outputPath": {
|
||||
"base": "dist"
|
||||
},
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"tsConfig": "tsconfig.json",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"polyfills": [
|
||||
"src/polyfills.ts"
|
||||
],
|
||||
"baseHref": "/",
|
||||
"stylePreprocessorOptions": {
|
||||
"includePaths": [
|
||||
"src/sass/include"
|
||||
"src/sass/include",
|
||||
"."
|
||||
]
|
||||
},
|
||||
"assets": [
|
||||
|
@ -209,12 +214,14 @@
|
|||
"@formatjs/intl-pluralrules/should-polyfill"
|
||||
],
|
||||
"scripts": [],
|
||||
"vendorChunk": true,
|
||||
"extractLicenses": false,
|
||||
"buildOptimizer": false,
|
||||
"sourceMap": true,
|
||||
"optimization": false,
|
||||
"namedChunks": true
|
||||
"namedChunks": true,
|
||||
"browser": "src/main.ts",
|
||||
"loader": {
|
||||
".svg": "text"
|
||||
}
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
|
@ -223,10 +230,7 @@
|
|||
"sourceMap": false,
|
||||
"namedChunks": false,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true,
|
||||
"serviceWorker": true,
|
||||
"ngswConfigPath": "src/ngsw-config.json",
|
||||
"serviceWorker": "src/ngsw-config.json",
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
|
@ -281,7 +285,7 @@
|
|||
}
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"builder": "@angular/build:dev-server",
|
||||
"options": {
|
||||
"proxyConfig": "proxy.config.json",
|
||||
"buildTarget": "PeerTube:build"
|
||||
|
@ -299,7 +303,7 @@
|
|||
}
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"builder": "@angular/build:extract-i18n",
|
||||
"options": {
|
||||
"buildTarget": "PeerTube:build"
|
||||
}
|
||||
|
|
|
@ -16,40 +16,42 @@
|
|||
"lint": "npm run lint-ts && npm run lint-scss",
|
||||
"lint-ts": "eslint --cache --ext .ts src/standalone/**/*.ts && npm run ng lint",
|
||||
"lint-scss": "stylelint 'src/**/*.scss'",
|
||||
"webpack": "webpack",
|
||||
"eslint": "eslint",
|
||||
"ng": "ng",
|
||||
"webpack-bundle-analyzer": "webpack-bundle-analyzer",
|
||||
"webdriver-manager": "webdriver-manager",
|
||||
"ngx-extractor": "ngx-extractor",
|
||||
"stylelint": "stylelint"
|
||||
},
|
||||
"browser": {
|
||||
"net": false,
|
||||
"stream": false,
|
||||
"os": false,
|
||||
"util": false
|
||||
},
|
||||
"workspaces": [
|
||||
"../packages/*"
|
||||
],
|
||||
"typings": "*.d.ts",
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "^17.0.9",
|
||||
"@angular-eslint/builder": "^17.1.1",
|
||||
"@angular-eslint/eslint-plugin": "^17.1.1",
|
||||
"@angular-eslint/eslint-plugin-template": "^17.1.1",
|
||||
"@angular-eslint/schematics": "^17.1.1",
|
||||
"@angular-eslint/template-parser": "^17.1.1",
|
||||
"@angular/animations": "^17.0.8",
|
||||
"@angular/cdk": "^17.0.4",
|
||||
"@angular/cli": "^17.0.9",
|
||||
"@angular/common": "^17.0.8",
|
||||
"@angular/compiler": "^17.0.8",
|
||||
"@angular/compiler-cli": "^17.0.8",
|
||||
"@angular/core": "^17.0.8",
|
||||
"@angular/forms": "^17.0.8",
|
||||
"@angular/localize": "^17.0.8",
|
||||
"@angular/platform-browser": "^17.0.8",
|
||||
"@angular/platform-browser-dynamic": "^17.0.8",
|
||||
"@angular/router": "^17.0.8",
|
||||
"@angular/service-worker": "^17.0.8",
|
||||
"@babel/core": "^7.18.5",
|
||||
"@babel/preset-env": "^7.18.2",
|
||||
"@angular-eslint/builder": "^18.0.1",
|
||||
"@angular-eslint/eslint-plugin": "^18.0.1",
|
||||
"@angular-eslint/eslint-plugin-template": "^18.0.1",
|
||||
"@angular-eslint/schematics": "^18.0.1",
|
||||
"@angular-eslint/template-parser": "^18.0.1",
|
||||
"@angular/animations": "^18.0.4",
|
||||
"@angular/build": "^18.0.5",
|
||||
"@angular/cdk": "^18.0.4",
|
||||
"@angular/cli": "^18.0.5",
|
||||
"@angular/common": "^18.0.4",
|
||||
"@angular/compiler": "^18.0.4",
|
||||
"@angular/compiler-cli": "^18.0.4",
|
||||
"@angular/core": "^18.0.4",
|
||||
"@angular/forms": "^18.0.4",
|
||||
"@angular/localize": "^18.0.4",
|
||||
"@angular/platform-browser": "^18.0.4",
|
||||
"@angular/platform-browser-dynamic": "^18.0.4",
|
||||
"@angular/router": "^18.0.4",
|
||||
"@angular/service-worker": "^18.0.4",
|
||||
"@formatjs/intl-locale": "^4.0.0",
|
||||
"@formatjs/intl-pluralrules": "^5.2.2",
|
||||
"@ng-bootstrap/ng-bootstrap": "^17.0.0",
|
||||
|
@ -58,11 +60,8 @@
|
|||
"@ngx-loading-bar/http-client": "^6.0.0",
|
||||
"@ngx-loading-bar/router": "^6.0.0",
|
||||
"@peertube/maildev": "^1.2.0",
|
||||
"@peertube/p2p-media-loader-core": "^1.0.15",
|
||||
"@peertube/p2p-media-loader-hlsjs": "^1.0.15",
|
||||
"@peertube/peertube-core-utils": "*",
|
||||
"@peertube/peertube-models": "*",
|
||||
"@peertube/videojs-contextmenu": "^5.5.0",
|
||||
"@peertube/p2p-media-loader-core": "^1.0.19",
|
||||
"@peertube/p2p-media-loader-hlsjs": "^1.0.19",
|
||||
"@peertube/xliffmerge": "^2.0.3",
|
||||
"@popperjs/core": "^2.11.5",
|
||||
"@types/chart.js": "^2.9.37",
|
||||
|
@ -86,22 +85,18 @@
|
|||
"@wdio/shared-store-service": "^8.10.5",
|
||||
"@wdio/spec-reporter": "^8.10.5",
|
||||
"angularx-qrcode": "17.0.1",
|
||||
"babel-loader": "^9.1.0",
|
||||
"bootstrap": "^5.1.3",
|
||||
"buffer": "^6.0.3",
|
||||
"chart.js": "^4.3.0",
|
||||
"chartjs-plugin-zoom": "~2.0.1",
|
||||
"core-js": "^3.22.8",
|
||||
"css-loader": "^7.1.2",
|
||||
"debug": "^4.3.1",
|
||||
"eslint": "^8.28.0",
|
||||
"eslint-plugin-import": "2.29.1",
|
||||
"eslint-plugin-jsdoc": "^48.1.0",
|
||||
"eslint-plugin-prefer-arrow": "latest",
|
||||
"expect-webdriverio": "^4.2.3",
|
||||
"hls.js": "~1.3",
|
||||
"html-loader": "^5.0.0",
|
||||
"html-webpack-plugin": "^5.3.1",
|
||||
"hls.js": "~1.5.11",
|
||||
"intl-messageformat": "^10.1.0",
|
||||
"jschannel": "^1.0.2",
|
||||
"linkify-html": "^4.0.2",
|
||||
|
@ -109,29 +104,21 @@
|
|||
"lodash-es": "^4.17.4",
|
||||
"markdown-it": "14.1.0",
|
||||
"markdown-it-emoji": "^3.0.0",
|
||||
"mini-css-extract-plugin": "^2.2.0",
|
||||
"ngx-uploadx": "^6.1.0",
|
||||
"path-browserify": "^1.0.0",
|
||||
"postcss": "^8.4.14",
|
||||
"primeng": "^17.3.1",
|
||||
"raw-loader": "^4.0.2",
|
||||
"rxjs": "^7.3.0",
|
||||
"sanitize-html": "^2.1.2",
|
||||
"sass": "^1.58.1",
|
||||
"sass-loader": "^14.1.1",
|
||||
"sha.js": "^2.4.11",
|
||||
"socket.io-client": "^4.5.4",
|
||||
"stylelint": "^16.2.1",
|
||||
"stylelint-config-sass-guidelines": "^11.0.0",
|
||||
"tinykeys": "^2.1.0",
|
||||
"ts-loader": "^9.3.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"tslib": "^2.4.0",
|
||||
"typescript": "~5.2",
|
||||
"typescript": "~5.4.5",
|
||||
"video.js": "^7.19.2",
|
||||
"webpack": "^5.73.0",
|
||||
"webpack-bundle-analyzer": "^4.4.2",
|
||||
"webpack-cli": "^5.0.1",
|
||||
"vite": "^5.3.1",
|
||||
"vite-plugin-checker": "^0.6.4",
|
||||
"vite-plugin-node-polyfills": "^0.22.0",
|
||||
"zone.js": "~0.14.2"
|
||||
},
|
||||
"dependencies": {}
|
||||
|
|
|
@ -31,15 +31,5 @@
|
|||
"/client/locales": {
|
||||
"target": "http://127.0.0.1:9000",
|
||||
"secure": false
|
||||
},
|
||||
"/!(client)**": {
|
||||
"target": "http://127.0.0.1:3000/client/index.html",
|
||||
"secure": false,
|
||||
"logLevel": "debug"
|
||||
},
|
||||
"/!(client)**/**": {
|
||||
"target": "http://127.0.0.1:3000/client/index.html",
|
||||
"secure": false,
|
||||
"logLevel": "debug"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
|
|||
import { DomSanitizer } from '@angular/platform-browser'
|
||||
|
||||
const images = {
|
||||
about: require('!!raw-loader?!../../../assets/images/mascot/register/about.svg').default,
|
||||
terms: require('!!raw-loader?!../../../assets/images/mascot/register/terms.svg').default,
|
||||
success: require('!!raw-loader?!../../../assets/images/mascot/register/success.svg').default,
|
||||
channel: require('!!raw-loader?!../../../assets/images/mascot/register/channel.svg').default,
|
||||
account: require('!!raw-loader?!../../../assets/images/mascot/register/account.svg').default
|
||||
about: require('../../../assets/images/mascot/register/about.svg'),
|
||||
terms: require('../../../assets/images/mascot/register/terms.svg'),
|
||||
success: require('../../../assets/images/mascot/register/success.svg'),
|
||||
channel: require('../../../assets/images/mascot/register/channel.svg'),
|
||||
account: require('../../../assets/images/mascot/register/account.svg')
|
||||
}
|
||||
|
||||
export type MascotImageName = keyof typeof images
|
||||
|
|
|
@ -276,7 +276,7 @@ export class AppComponent implements OnInit, AfterViewInit {
|
|||
if (this.serverConfig.instance.customizations.javascript) {
|
||||
try {
|
||||
/* eslint-disable no-eval */
|
||||
eval(this.serverConfig.instance.customizations.javascript)
|
||||
window.eval(this.serverConfig.instance.customizations.javascript)
|
||||
} catch (err) {
|
||||
logger.error('Cannot eval custom JavaScript.', err)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as MarkdownIt from 'markdown-it'
|
||||
import MarkdownIt from 'markdown-it'
|
||||
import { Injectable } from '@angular/core'
|
||||
import {
|
||||
buildVideoLink,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as debug from 'debug'
|
||||
import debug from 'debug'
|
||||
import { SortMeta } from 'primeng/api'
|
||||
import { HttpParams } from '@angular/common/http'
|
||||
import { Injectable } from '@angular/core'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as debug from 'debug'
|
||||
import debug from 'debug'
|
||||
import { Observable } from 'rxjs'
|
||||
import { Injectable } from '@angular/core'
|
||||
import { ConfirmService } from '@app/core/confirm'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as debug from 'debug'
|
||||
import debug from 'debug'
|
||||
import { Injectable } from '@angular/core'
|
||||
import { NavigationCancel, NavigationEnd, Router } from '@angular/router'
|
||||
import { logger } from '@root-helpers/logger'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as debug from 'debug'
|
||||
import debug from 'debug'
|
||||
import { pairwise } from 'rxjs'
|
||||
import { ViewportScroller } from '@angular/common'
|
||||
import { Injectable } from '@angular/core'
|
||||
|
|
|
@ -23,7 +23,7 @@ import { LoginLinkComponent } from '@app/shared/shared-main/angular/login-link.c
|
|||
import { PeertubeModalService } from '@app/shared/shared-main/peertube-modal/peertube-modal.service'
|
||||
import { NgbDropdown, NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { HTMLServerConfig, ServerConfig, UserRight, UserRightType, VideoConstant } from '@peertube/peertube-models'
|
||||
import * as debug from 'debug'
|
||||
import debug from 'debug'
|
||||
import { forkJoin, Subscription } from 'rxjs'
|
||||
import { first, switchMap } from 'rxjs/operators'
|
||||
import { LanguageChooserComponent } from './language-chooser.component'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as debug from 'debug'
|
||||
import debug from 'debug'
|
||||
import { SortMeta, SharedModule } from 'primeng/api'
|
||||
import { Component, Input, OnInit, ViewChild } from '@angular/core'
|
||||
import { ActivatedRoute, Router } from '@angular/router'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as debug from 'debug'
|
||||
import debug from 'debug'
|
||||
import { Subject } from 'rxjs'
|
||||
import { debounceTime, distinctUntilChanged } from 'rxjs/operators'
|
||||
import { AfterViewInit, Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
|
||||
|
|
|
@ -3,82 +3,82 @@ import { HooksService } from '@app/core/plugins/hooks.service'
|
|||
|
||||
const icons = {
|
||||
// misc icons
|
||||
'npm': require('!!raw-loader?!../../../assets/images/misc/npm.svg').default,
|
||||
'markdown': require('!!raw-loader?!../../../assets/images/misc/markdown.svg').default,
|
||||
'language': require('!!raw-loader?!../../../assets/images/misc/language.svg').default,
|
||||
'video-lang': require('!!raw-loader?!../../../assets/images/misc/video-lang.svg').default,
|
||||
'support': require('!!raw-loader?!../../../assets/images/misc/support.svg').default,
|
||||
'peertube-x': require('!!raw-loader?!../../../assets/images/misc/peertube-x.svg').default,
|
||||
'robot': require('!!raw-loader?!../../../assets/images/misc/miscellaneous-services.svg').default, // material ui
|
||||
'videos': require('!!raw-loader?!../../../assets/images/misc/video-library.svg').default, // material ui
|
||||
'history': require('!!raw-loader?!../../../assets/images/misc/history.svg').default, // material ui
|
||||
'subscriptions': require('!!raw-loader?!../../../assets/images/misc/subscriptions.svg').default, // material ui
|
||||
'playlist-add': require('!!raw-loader?!../../../assets/images/misc/playlist-add.svg').default, // material ui
|
||||
'follower': require('!!raw-loader?!../../../assets/images/misc/account-arrow-left.svg').default, // material ui
|
||||
'following': require('!!raw-loader?!../../../assets/images/misc/account-arrow-right.svg').default, // material ui
|
||||
'tip': require('!!raw-loader?!../../../assets/images/misc/tip.svg').default, // material ui
|
||||
'flame': require('!!raw-loader?!../../../assets/images/misc/flame.svg').default,
|
||||
'local': require('!!raw-loader?!../../../assets/images/misc/local.svg').default,
|
||||
'npm': require('../../../assets/images/misc/npm.svg'),
|
||||
'markdown': require('../../../assets/images/misc/markdown.svg'),
|
||||
'language': require('../../../assets/images/misc/language.svg'),
|
||||
'video-lang': require('../../../assets/images/misc/video-lang.svg'),
|
||||
'support': require('../../../assets/images/misc/support.svg'),
|
||||
'peertube-x': require('../../../assets/images/misc/peertube-x.svg'),
|
||||
'robot': require('../../../assets/images/misc/miscellaneous-services.svg'), // material ui
|
||||
'videos': require('../../../assets/images/misc/video-library.svg'), // material ui
|
||||
'history': require('../../../assets/images/misc/history.svg'), // material ui
|
||||
'subscriptions': require('../../../assets/images/misc/subscriptions.svg'), // material ui
|
||||
'playlist-add': require('../../../assets/images/misc/playlist-add.svg'), // material ui
|
||||
'follower': require('../../../assets/images/misc/account-arrow-left.svg'), // material ui
|
||||
'following': require('../../../assets/images/misc/account-arrow-right.svg'), // material ui
|
||||
'tip': require('../../../assets/images/misc/tip.svg'), // material ui
|
||||
'flame': require('../../../assets/images/misc/flame.svg'),
|
||||
'local': require('../../../assets/images/misc/local.svg'),
|
||||
|
||||
// feather icons
|
||||
'copy': require('!!raw-loader?!../../../assets/images/feather/copy.svg').default,
|
||||
'flag': require('!!raw-loader?!../../../assets/images/feather/flag.svg').default,
|
||||
'playlists': require('!!raw-loader?!../../../assets/images/feather/list.svg').default,
|
||||
'syndication': require('!!raw-loader?!../../../assets/images/feather/syndication.svg').default,
|
||||
'help': require('!!raw-loader?!../../../assets/images/feather/help.svg').default,
|
||||
'alert': require('!!raw-loader?!../../../assets/images/feather/alert.svg').default,
|
||||
'globe': require('!!raw-loader?!../../../assets/images/feather/globe.svg').default,
|
||||
'home': require('!!raw-loader?!../../../assets/images/feather/home.svg').default,
|
||||
'trending': require('!!raw-loader?!../../../assets/images/feather/trending.svg').default,
|
||||
'search': require('!!raw-loader?!../../../assets/images/feather/search.svg').default,
|
||||
'upload': require('!!raw-loader?!../../../assets/images/feather/upload.svg').default,
|
||||
'dislike': require('!!raw-loader?!../../../assets/images/feather/dislike.svg').default,
|
||||
'like': require('!!raw-loader?!../../../assets/images/feather/like.svg').default,
|
||||
'no': require('!!raw-loader?!../../../assets/images/feather/no.svg').default,
|
||||
'cloud-download': require('!!raw-loader?!../../../assets/images/feather/cloud-download.svg').default,
|
||||
'clock': require('!!raw-loader?!../../../assets/images/feather/clock.svg').default,
|
||||
'cog': require('!!raw-loader?!../../../assets/images/feather/cog.svg').default,
|
||||
'delete': require('!!raw-loader?!../../../assets/images/feather/delete.svg').default,
|
||||
'bell': require('!!raw-loader?!../../../assets/images/feather/bell.svg').default,
|
||||
'sign-out': require('!!raw-loader?!../../../assets/images/feather/log-out.svg').default,
|
||||
'sign-in': require('!!raw-loader?!../../../assets/images/feather/log-in.svg').default,
|
||||
'download': require('!!raw-loader?!../../../assets/images/feather/download.svg').default,
|
||||
'ownership-change': require('!!raw-loader?!../../../assets/images/feather/share.svg').default,
|
||||
'share': require('!!raw-loader?!../../../assets/images/feather/share-2.svg').default,
|
||||
'channel': require('!!raw-loader?!../../../assets/images/feather/tv.svg').default,
|
||||
'user': require('!!raw-loader?!../../../assets/images/feather/user.svg').default,
|
||||
'user-x': require('!!raw-loader?!../../../assets/images/feather/user-x.svg').default,
|
||||
'users': require('!!raw-loader?!../../../assets/images/feather/users.svg').default,
|
||||
'user-add': require('!!raw-loader?!../../../assets/images/feather/user-plus.svg').default,
|
||||
'add': require('!!raw-loader?!../../../assets/images/feather/plus-circle.svg').default,
|
||||
'cloud-error': require('!!raw-loader?!../../../assets/images/feather/cloud-off.svg').default,
|
||||
'undo': require('!!raw-loader?!../../../assets/images/feather/corner-up-left.svg').default,
|
||||
'circle-tick': require('!!raw-loader?!../../../assets/images/feather/check-circle.svg').default,
|
||||
'more-horizontal': require('!!raw-loader?!../../../assets/images/feather/more-horizontal.svg').default,
|
||||
'more-vertical': require('!!raw-loader?!../../../assets/images/feather/more-vertical.svg').default,
|
||||
'play': require('!!raw-loader?!../../../assets/images/feather/play.svg').default,
|
||||
'p2p': require('!!raw-loader?!../../../assets/images/feather/airplay.svg').default,
|
||||
'fullscreen': require('!!raw-loader?!../../../assets/images/feather/maximize.svg').default,
|
||||
'exit-fullscreen': require('!!raw-loader?!../../../assets/images/feather/minimize.svg').default,
|
||||
'film': require('!!raw-loader?!../../../assets/images/feather/film.svg').default,
|
||||
'edit': require('!!raw-loader?!../../../assets/images/feather/edit-2.svg').default,
|
||||
'external-link': require('!!raw-loader?!../../../assets/images/feather/external-link.svg').default,
|
||||
'eye-open': require('!!raw-loader?!../../../assets/images/feather/eye.svg').default,
|
||||
'eye-close': require('!!raw-loader?!../../../assets/images/feather/eye-off.svg').default,
|
||||
'refresh': require('!!raw-loader?!../../../assets/images/feather/refresh-cw.svg').default,
|
||||
'command': require('!!raw-loader?!../../../assets/images/feather/command.svg').default,
|
||||
'go': require('!!raw-loader?!../../../assets/images/feather/arrow-up-right.svg').default,
|
||||
'cross': require('!!raw-loader?!../../../assets/images/feather/x.svg').default,
|
||||
'tick': require('!!raw-loader?!../../../assets/images/feather/check.svg').default,
|
||||
'columns': require('!!raw-loader?!../../../assets/images/feather/columns.svg').default,
|
||||
'live': require('!!raw-loader?!../../../assets/images/feather/live.svg').default,
|
||||
'repeat': require('!!raw-loader?!../../../assets/images/feather/repeat.svg').default,
|
||||
'chevrons-up': require('!!raw-loader?!../../../assets/images/feather/chevrons-up.svg').default,
|
||||
'message-circle': require('!!raw-loader?!../../../assets/images/feather/message-circle.svg').default,
|
||||
'codesandbox': require('!!raw-loader?!../../../assets/images/feather/codesandbox.svg').default,
|
||||
'award': require('!!raw-loader?!../../../assets/images/feather/award.svg').default,
|
||||
'stats': require('!!raw-loader?!../../../assets/images/feather/stats.svg').default,
|
||||
'shield': require('!!raw-loader?!../../../assets/images/misc/shield.svg').default
|
||||
'copy': require('../../../assets/images/feather/copy.svg'),
|
||||
'flag': require('../../../assets/images/feather/flag.svg'),
|
||||
'playlists': require('../../../assets/images/feather/list.svg'),
|
||||
'syndication': require('../../../assets/images/feather/syndication.svg'),
|
||||
'help': require('../../../assets/images/feather/help.svg'),
|
||||
'alert': require('../../../assets/images/feather/alert.svg'),
|
||||
'globe': require('../../../assets/images/feather/globe.svg'),
|
||||
'home': require('../../../assets/images/feather/home.svg'),
|
||||
'trending': require('../../../assets/images/feather/trending.svg'),
|
||||
'search': require('../../../assets/images/feather/search.svg'),
|
||||
'upload': require('../../../assets/images/feather/upload.svg'),
|
||||
'dislike': require('../../../assets/images/feather/dislike.svg'),
|
||||
'like': require('../../../assets/images/feather/like.svg'),
|
||||
'no': require('../../../assets/images/feather/no.svg'),
|
||||
'cloud-download': require('../../../assets/images/feather/cloud-download.svg'),
|
||||
'clock': require('../../../assets/images/feather/clock.svg'),
|
||||
'cog': require('../../../assets/images/feather/cog.svg'),
|
||||
'delete': require('../../../assets/images/feather/delete.svg'),
|
||||
'bell': require('../../../assets/images/feather/bell.svg'),
|
||||
'sign-out': require('../../../assets/images/feather/log-out.svg'),
|
||||
'sign-in': require('../../../assets/images/feather/log-in.svg'),
|
||||
'download': require('../../../assets/images/feather/download.svg'),
|
||||
'ownership-change': require('../../../assets/images/feather/share.svg'),
|
||||
'share': require('../../../assets/images/feather/share-2.svg'),
|
||||
'channel': require('../../../assets/images/feather/tv.svg'),
|
||||
'user': require('../../../assets/images/feather/user.svg'),
|
||||
'user-x': require('../../../assets/images/feather/user-x.svg'),
|
||||
'users': require('../../../assets/images/feather/users.svg'),
|
||||
'user-add': require('../../../assets/images/feather/user-plus.svg'),
|
||||
'add': require('../../../assets/images/feather/plus-circle.svg'),
|
||||
'cloud-error': require('../../../assets/images/feather/cloud-off.svg'),
|
||||
'undo': require('../../../assets/images/feather/corner-up-left.svg'),
|
||||
'circle-tick': require('../../../assets/images/feather/check-circle.svg'),
|
||||
'more-horizontal': require('../../../assets/images/feather/more-horizontal.svg'),
|
||||
'more-vertical': require('../../../assets/images/feather/more-vertical.svg'),
|
||||
'play': require('../../../assets/images/feather/play.svg'),
|
||||
'p2p': require('../../../assets/images/feather/airplay.svg'),
|
||||
'fullscreen': require('../../../assets/images/feather/maximize.svg'),
|
||||
'exit-fullscreen': require('../../../assets/images/feather/minimize.svg'),
|
||||
'film': require('../../../assets/images/feather/film.svg'),
|
||||
'edit': require('../../../assets/images/feather/edit-2.svg'),
|
||||
'external-link': require('../../../assets/images/feather/external-link.svg'),
|
||||
'eye-open': require('../../../assets/images/feather/eye.svg'),
|
||||
'eye-close': require('../../../assets/images/feather/eye-off.svg'),
|
||||
'refresh': require('../../../assets/images/feather/refresh-cw.svg'),
|
||||
'command': require('../../../assets/images/feather/command.svg'),
|
||||
'go': require('../../../assets/images/feather/arrow-up-right.svg'),
|
||||
'cross': require('../../../assets/images/feather/x.svg'),
|
||||
'tick': require('../../../assets/images/feather/check.svg'),
|
||||
'columns': require('../../../assets/images/feather/columns.svg'),
|
||||
'live': require('../../../assets/images/feather/live.svg'),
|
||||
'repeat': require('../../../assets/images/feather/repeat.svg'),
|
||||
'chevrons-up': require('../../../assets/images/feather/chevrons-up.svg'),
|
||||
'message-circle': require('../../../assets/images/feather/message-circle.svg'),
|
||||
'codesandbox': require('../../../assets/images/feather/codesandbox.svg'),
|
||||
'award': require('../../../assets/images/feather/award.svg'),
|
||||
'stats': require('../../../assets/images/feather/stats.svg'),
|
||||
'shield': require('../../../assets/images/misc/shield.svg')
|
||||
}
|
||||
|
||||
export type GlobalIconName = keyof typeof icons
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as debug from 'debug'
|
||||
import debug from 'debug'
|
||||
import {
|
||||
AfterViewInit,
|
||||
ChangeDetectorRef,
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
} from '@angular/core'
|
||||
import { ScreenService } from '@app/core'
|
||||
import { NgbDropdown, NgbModal, NgbDropdownAnchor, NgbDropdownMenu } from '@ng-bootstrap/ng-bootstrap'
|
||||
import * as debug from 'debug'
|
||||
import debug from 'debug'
|
||||
import { RouterLinkActive, RouterLink } from '@angular/router'
|
||||
import { NgFor, NgTemplateOutlet, NgIf, NgClass, SlicePipe } from '@angular/common'
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as debug from 'debug'
|
||||
import debug from 'debug'
|
||||
import { Observable, Subject } from 'rxjs'
|
||||
import { filter, first, map } from 'rxjs/operators'
|
||||
import { Injectable } from '@angular/core'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as debug from 'debug'
|
||||
import debug from 'debug'
|
||||
import { merge, Observable, of, ReplaySubject, Subject } from 'rxjs'
|
||||
import { catchError, filter, map, switchMap, tap } from 'rxjs/operators'
|
||||
import { HttpClient, HttpParams } from '@angular/common/http'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as debug from 'debug'
|
||||
import debug from 'debug'
|
||||
import { Subscription } from 'rxjs'
|
||||
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'
|
||||
import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'
|
||||
|
|
|
@ -16,7 +16,7 @@ import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap'
|
|||
import { isLastMonth, isLastWeek, isThisMonth, isToday, isYesterday } from '@peertube/peertube-core-utils'
|
||||
import { ResultList, UserRight, VideoSortField } from '@peertube/peertube-models'
|
||||
import { logger } from '@root-helpers/logger'
|
||||
import * as debug from 'debug'
|
||||
import debug from 'debug'
|
||||
import { Observable, Subject, Subscription, forkJoin, fromEvent, of } from 'rxjs'
|
||||
import { concatMap, debounceTime, map, switchMap } from 'rxjs/operators'
|
||||
import { InfiniteScrollerDirective } from '../shared-main/angular/infinite-scroller.directive'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as debug from 'debug'
|
||||
import debug from 'debug'
|
||||
import { Subject, Subscription } from 'rxjs'
|
||||
import { debounceTime, filter } from 'rxjs/operators'
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as debug from 'debug'
|
||||
import debug from 'debug'
|
||||
import { merge, Observable, of, ReplaySubject, Subject } from 'rxjs'
|
||||
import { catchError, filter, map, share, switchMap, tap } from 'rxjs/operators'
|
||||
import { HttpClient, HttpContext, HttpParams } from '@angular/common/http'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import '@peertube/videojs-contextmenu'
|
||||
import './shared/context-menu'
|
||||
import './shared/upnext/end-card'
|
||||
import './shared/upnext/upnext-plugin'
|
||||
import './shared/stats/stats-card'
|
||||
|
@ -28,6 +28,9 @@ import './shared/mobile/peertube-mobile-plugin'
|
|||
import './shared/mobile/peertube-mobile-buttons'
|
||||
import './shared/hotkeys/peertube-hotkeys-plugin'
|
||||
import './shared/metrics/metrics-plugin'
|
||||
import './shared/p2p-media-loader/hls-plugin'
|
||||
import './shared/p2p-media-loader/p2p-media-loader-plugin'
|
||||
import './shared/web-video/web-video-plugin'
|
||||
import videojs, { VideoJsPlayer } from 'video.js'
|
||||
import { logger } from '@root-helpers/logger'
|
||||
import { PluginsManager } from '@root-helpers/plugins-manager'
|
||||
|
@ -62,17 +65,10 @@ export class PeerTubePlayer {
|
|||
|
||||
private videojsDecodeErrors = 0
|
||||
|
||||
private p2pMediaLoaderModule: any
|
||||
|
||||
private player: VideoJsPlayer
|
||||
|
||||
private currentLoadOptions: PeerTubePlayerLoadOptions
|
||||
|
||||
private moduleLoaded = {
|
||||
webVideo: false,
|
||||
p2pMediaLoader: false
|
||||
}
|
||||
|
||||
constructor (private options: PeerTubePlayerContructorOptions) {
|
||||
this.pluginsManager = options.pluginsManager
|
||||
}
|
||||
|
@ -92,7 +88,6 @@ export class PeerTubePlayer {
|
|||
|
||||
this.disposeDynamicPluginsIfNeeded()
|
||||
|
||||
await this.lazyLoadModulesIfNeeded()
|
||||
await this.buildPlayerIfNeeded()
|
||||
|
||||
if (this.currentLoadOptions.mode === 'p2p-media-loader') {
|
||||
|
@ -169,7 +164,7 @@ export class PeerTubePlayer {
|
|||
'liveOptions',
|
||||
'hls'
|
||||
])
|
||||
}, this.p2pMediaLoaderModule)
|
||||
})
|
||||
|
||||
const { hlsjs, p2pMediaLoader } = await hlsOptionsBuilder.getPluginOptions()
|
||||
|
||||
|
@ -226,7 +221,7 @@ export class PeerTubePlayer {
|
|||
saveAverageBandwidth(data.bandwidthEstimate)
|
||||
})
|
||||
|
||||
this.player.contextmenuUI(this.getContextMenuOptions())
|
||||
this.player.contextMenu(this.getContextMenuOptions())
|
||||
|
||||
this.displayNotificationWhenOffline()
|
||||
})
|
||||
|
@ -298,22 +293,6 @@ export class PeerTubePlayer {
|
|||
}
|
||||
}
|
||||
|
||||
private async lazyLoadModulesIfNeeded () {
|
||||
if (this.currentLoadOptions.mode === 'web-video' && this.moduleLoaded.webVideo !== true) {
|
||||
await import('./shared/web-video/web-video-plugin')
|
||||
}
|
||||
|
||||
if (this.currentLoadOptions.mode === 'p2p-media-loader' && this.moduleLoaded.p2pMediaLoader !== true) {
|
||||
const [ p2pMediaLoaderModule ] = await Promise.all([
|
||||
import('@peertube/p2p-media-loader-hlsjs'),
|
||||
import('./shared/p2p-media-loader/hls-plugin'),
|
||||
import('./shared/p2p-media-loader/p2p-media-loader-plugin')
|
||||
])
|
||||
|
||||
this.p2pMediaLoaderModule = p2pMediaLoaderModule
|
||||
}
|
||||
}
|
||||
|
||||
private async tryToRecoverHLSError (err: any) {
|
||||
if (err.code === MediaError.MEDIA_ERR_DECODE) {
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
import videojs from 'video.js'
|
||||
import { ContextMenuItemOptions } from '../../types'
|
||||
|
||||
const MenuItem = videojs.getComponent('MenuItem')
|
||||
|
||||
class ContextMenuItem extends MenuItem {
|
||||
options_: ContextMenuItemOptions
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
|
||||
constructor (player: videojs.Player, options: ContextMenuItemOptions) {
|
||||
super(player, options)
|
||||
}
|
||||
|
||||
handleClick (e: videojs.EventTarget.Event) {
|
||||
super.handleClick(e)
|
||||
|
||||
this.options_.listener(e)
|
||||
|
||||
// Close the containing menu after the call stack clears.
|
||||
setTimeout(() => {
|
||||
this.player().contextMenu().menu.dispose()
|
||||
}, 1)
|
||||
}
|
||||
|
||||
createEl (type: string, props?: any, attrs?: any) {
|
||||
const el = super.createEl(type, props, attrs)
|
||||
|
||||
const newEl = videojs.dom.createEl('span')
|
||||
|
||||
newEl.innerHTML = `<span class="vjs-menu-item-text">${this.localize(this.options_.label)}</span>`
|
||||
|
||||
el.replaceChild(newEl, el.querySelector('.vjs-menu-item-text'))
|
||||
|
||||
return el
|
||||
}
|
||||
}
|
||||
|
||||
export { ContextMenuItem }
|
|
@ -0,0 +1,119 @@
|
|||
import videojs, { VideoJsPlayer } from 'video.js'
|
||||
import { ContextMenuPluginOptions } from '../../types'
|
||||
import { ContextMenu } from './context-menu'
|
||||
import { getPointerPosition } from './util'
|
||||
|
||||
const Plugin = videojs.getPlugin('plugin')
|
||||
|
||||
class ContextMenuPlugin extends Plugin {
|
||||
options_: ContextMenuPluginOptions & videojs.MenuOptions
|
||||
|
||||
menu: ContextMenu
|
||||
|
||||
private onContextMenuBind: (e: TouchEvent & MouseEvent) => void
|
||||
|
||||
constructor (player: videojs.Player, options: ContextMenuPluginOptions & videojs.MenuOptions) {
|
||||
super(player, options)
|
||||
|
||||
this.options_ = options
|
||||
|
||||
// If we have already invoked the plugin, teardown before setting up again.
|
||||
if (this.menu) {
|
||||
this.menu.dispose()
|
||||
this.player.off('contextmenu', this.onContextMenuBind)
|
||||
}
|
||||
|
||||
this.onContextMenuBind = this.onContextMenu.bind(this)
|
||||
this.player.on('contextmenu', this.onContextMenuBind)
|
||||
this.player.ready(() => this.player.addClass('vjs-contextmenu-ui'))
|
||||
}
|
||||
|
||||
private onContextMenu (e: TouchEvent & MouseEvent) {
|
||||
// If this event happens while the custom menu is open, close it and do
|
||||
// nothing else. This will cause native contextmenu events to be intercepted
|
||||
// once again; so, the next time a contextmenu event is encountered, we'll
|
||||
// open the custom menu.
|
||||
if (hasMenu(this.player)) {
|
||||
this.menu.dispose()
|
||||
return
|
||||
}
|
||||
|
||||
if (excludeElements(e.target as HTMLElement)) return
|
||||
|
||||
// Calculate the positioning of the menu based on the player size and
|
||||
// triggering event.
|
||||
const pointerPosition = getPointerPosition(this.player.el() as HTMLElement, e)
|
||||
const playerSize = this.player.el().getBoundingClientRect()
|
||||
const menuPosition = findMenuPosition(pointerPosition, playerSize)
|
||||
// A workaround for Firefox issue where "oncontextmenu" event
|
||||
// leaks "click" event to document https://bugzilla.mozilla.org/show_bug.cgi?id=990614
|
||||
const documentEl = (videojs.browser as any).IS_FIREFOX ? document.documentElement : document
|
||||
|
||||
e.preventDefault()
|
||||
|
||||
const menu = this.menu = new ContextMenu(this.player, {
|
||||
content: this.options_.content,
|
||||
position: menuPosition
|
||||
})
|
||||
|
||||
menu.on('dispose', () => {
|
||||
for (const event of [ 'click', 'tap' ]) {
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
videojs.off(documentEl as Element, event, menu.dispose)
|
||||
}
|
||||
|
||||
this.player.removeChild(menu)
|
||||
this.menu = undefined
|
||||
})
|
||||
|
||||
this.player.addChild(menu)
|
||||
|
||||
const menuEl = menu.el() as HTMLElement
|
||||
const menuSize = menuEl.getBoundingClientRect()
|
||||
const bodySize = document.body.getBoundingClientRect()
|
||||
|
||||
if (menuSize.right > bodySize.width || menuSize.bottom > bodySize.height) {
|
||||
menuEl.style.left = Math.floor(Math.min(
|
||||
menuPosition.left,
|
||||
this.player.currentWidth() - menu.currentWidth()
|
||||
)) + 'px'
|
||||
|
||||
menuEl.style.top = Math.floor(Math.min(
|
||||
menuPosition.top,
|
||||
this.player.currentHeight() - menu.currentHeight()
|
||||
)) + 'px'
|
||||
}
|
||||
|
||||
for (const event of [ 'click', 'tap' ]) {
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
videojs.on(documentEl as Element, event, menu.dispose)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
videojs.registerPlugin('contextMenu', ContextMenuPlugin)
|
||||
|
||||
export { ContextMenuPlugin }
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Private
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function hasMenu (player: VideoJsPlayer) {
|
||||
if (!player.usingPlugin('contextMenu')) return false
|
||||
|
||||
return !!player.contextMenu().menu?.el()
|
||||
}
|
||||
|
||||
function excludeElements (targetEl: HTMLElement) {
|
||||
const tagName = targetEl.tagName.toLowerCase()
|
||||
|
||||
return tagName === 'input' || tagName === 'textarea'
|
||||
}
|
||||
|
||||
function findMenuPosition (pointerPosition: { x?: number, y?: number }, playerSize: { height: number, width: number }) {
|
||||
return {
|
||||
left: Math.round(playerSize.width * pointerPosition.x),
|
||||
top: Math.round(playerSize.height - (playerSize.height * pointerPosition.y))
|
||||
}
|
||||
}
|
39
client/src/assets/player/shared/context-menu/context-menu.ts
Normal file
39
client/src/assets/player/shared/context-menu/context-menu.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
import videojs from 'video.js'
|
||||
import { ContextMenuItem } from './context-menu-item'
|
||||
import { ContextMenuPluginOptions } from '../../types'
|
||||
|
||||
const Menu = videojs.getComponent('Menu')
|
||||
|
||||
type ContextMenuOptions = ContextMenuPluginOptions & { position: { left: number, top: number } }
|
||||
|
||||
class ContextMenu extends Menu {
|
||||
options_: ContextMenuOptions & videojs.MenuOptions
|
||||
|
||||
constructor (player: videojs.Player, options: ContextMenuOptions) {
|
||||
super(player, { ...options, menuButton: undefined })
|
||||
|
||||
// Each menu component has its own `dispose` method that can be
|
||||
// safely bound and unbound to events while maintaining its context.
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
this.dispose = videojs.bind(this, this.dispose)
|
||||
|
||||
for (const c of options.content()) {
|
||||
this.addItem(new ContextMenuItem(player, {
|
||||
label: c.label,
|
||||
listener: videojs.bind(player, c.listener)
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
createEl () {
|
||||
const el = super.createEl()
|
||||
|
||||
videojs.dom.addClass(el, 'vjs-contextmenu-ui-menu')
|
||||
el.style.left = this.options_.position.left + 'px'
|
||||
el.style.top = this.options_.position.top + 'px'
|
||||
|
||||
return el
|
||||
}
|
||||
}
|
||||
|
||||
export { ContextMenu }
|
2
client/src/assets/player/shared/context-menu/index.ts
Normal file
2
client/src/assets/player/shared/context-menu/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
// Thanks & credits: https://github.com/videojs/videojs-contextmenu-ui/
|
||||
export * from './context-menu-plugin.js'
|
52
client/src/assets/player/shared/context-menu/util.ts
Normal file
52
client/src/assets/player/shared/context-menu/util.ts
Normal file
|
@ -0,0 +1,52 @@
|
|||
export function findElPosition (el: HTMLElement) {
|
||||
let box: DOMRect
|
||||
|
||||
if (el.getBoundingClientRect && el.parentNode) {
|
||||
box = el.getBoundingClientRect()
|
||||
}
|
||||
|
||||
if (!box) return { left: 0, top: 0 }
|
||||
|
||||
const docEl = document.documentElement
|
||||
const body = document.body
|
||||
|
||||
const clientLeft = docEl.clientLeft || body.clientLeft || 0
|
||||
const scrollLeft = window.pageXOffset || body.scrollLeft
|
||||
const left = box.left + scrollLeft - clientLeft
|
||||
|
||||
const clientTop = docEl.clientTop || body.clientTop || 0
|
||||
const scrollTop = window.pageYOffset || body.scrollTop
|
||||
const top = box.top + scrollTop - clientTop
|
||||
|
||||
// Android sometimes returns slightly off decimal values, so need to round
|
||||
return {
|
||||
left: Math.round(left),
|
||||
top: Math.round(top)
|
||||
}
|
||||
}
|
||||
|
||||
export function getPointerPosition (el: HTMLElement, event: TouchEvent & MouseEvent) {
|
||||
const position: { y?: number, x?: number } = {}
|
||||
|
||||
const box = findElPosition(el)
|
||||
const boxW = el.offsetWidth
|
||||
const boxH = el.offsetHeight
|
||||
const boxY = box.top
|
||||
const boxX = box.left
|
||||
let pageY = event.pageY
|
||||
let pageX = event.pageX
|
||||
|
||||
if (event.changedTouches) {
|
||||
pageX = event.changedTouches[0].pageX
|
||||
pageY = event.changedTouches[0].pageY
|
||||
}
|
||||
|
||||
position.y = Math.max(0, Math.min(1, ((boxY - pageY) + boxH) / boxH))
|
||||
position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW))
|
||||
|
||||
return position
|
||||
}
|
||||
|
||||
export function isFunction (functionToCheck: any) {
|
||||
return functionToCheck && {}.toString.call(functionToCheck) === '[object Function]'
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
import { basename, dirname } from 'path'
|
||||
import { logger } from '@root-helpers/logger'
|
||||
|
||||
class RedundancyUrlManager {
|
||||
|
@ -10,7 +9,7 @@ class RedundancyUrlManager {
|
|||
removeBySegmentUrl (segmentUrl: string) {
|
||||
logger.info(`Removing redundancy of segment URL ${segmentUrl}.`)
|
||||
|
||||
const baseUrl = dirname(segmentUrl)
|
||||
const baseUrl = getBaseUrl(segmentUrl)
|
||||
|
||||
this.baseUrls = this.baseUrls.filter(u => u !== baseUrl && u !== baseUrl + '/')
|
||||
}
|
||||
|
@ -24,7 +23,7 @@ class RedundancyUrlManager {
|
|||
const newBaseUrl = this.baseUrls[i]
|
||||
const slashPart = newBaseUrl.endsWith('/') ? '' : '/'
|
||||
|
||||
return newBaseUrl + slashPart + basename(url)
|
||||
return newBaseUrl + slashPart + getFilename(url)
|
||||
}
|
||||
|
||||
countBaseUrls () {
|
||||
|
@ -41,3 +40,16 @@ class RedundancyUrlManager {
|
|||
export {
|
||||
RedundancyUrlManager
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function getFilename (url: string) {
|
||||
return url.split('/').pop()
|
||||
}
|
||||
|
||||
function getBaseUrl (url: string) {
|
||||
const baseUrl = url.split('/')
|
||||
baseUrl.pop()
|
||||
|
||||
return baseUrl.join('/')
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { basename } from 'path'
|
||||
import { Segment } from '@peertube/p2p-media-loader-core'
|
||||
import { logger } from '@root-helpers/logger'
|
||||
import { wait } from '@root-helpers/utils'
|
||||
|
@ -32,7 +31,7 @@ export class SegmentValidator {
|
|||
|
||||
this.loadSha256SegmentsPromiseIfNeeded()
|
||||
|
||||
const filename = basename(removeQueryParams(segment.url))
|
||||
const filename = removeQueryParams(segment.url).split('/').pop()
|
||||
|
||||
const segmentValue = (await this.segmentJSONPromise)[filename]
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { HybridLoaderSettings } from '@peertube/p2p-media-loader-core'
|
||||
import { HlsJsEngineSettings } from '@peertube/p2p-media-loader-hlsjs'
|
||||
import { Engine, HlsJsEngineSettings } from '@peertube/p2p-media-loader-hlsjs'
|
||||
import { LiveVideoLatencyMode } from '@peertube/peertube-models'
|
||||
import { logger } from '@root-helpers/logger'
|
||||
import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage'
|
||||
|
@ -17,10 +17,7 @@ type ConstructorOptions =
|
|||
|
||||
export class HLSOptionsBuilder {
|
||||
|
||||
constructor (
|
||||
private options: ConstructorOptions,
|
||||
private p2pMediaLoaderModule?: any
|
||||
) {
|
||||
constructor (private options: ConstructorOptions) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -50,7 +47,7 @@ export class HLSOptionsBuilder {
|
|||
'filter:internal.player.p2p-media-loader.options.result',
|
||||
this.getP2PMediaLoaderOptions({ redundancyUrlManager, segmentValidator })
|
||||
)
|
||||
const loader = new this.p2pMediaLoaderModule.Engine(p2pMediaLoaderConfig).createLoaderClass() as P2PMediaLoader
|
||||
const loader = new Engine(p2pMediaLoaderConfig).createLoaderClass() as unknown as P2PMediaLoader
|
||||
|
||||
const p2pMediaLoader: P2PMediaLoaderPluginOptions = {
|
||||
requiresUserAuth: this.options.requiresUserAuth,
|
||||
|
@ -212,7 +209,8 @@ export class HLSOptionsBuilder {
|
|||
backBufferLength: 90,
|
||||
startLevel: -1,
|
||||
testBandwidth: false,
|
||||
debug: false
|
||||
debug: false,
|
||||
enableWorker: false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import { WebVideoPlugin } from '../shared/web-video/web-video-plugin'
|
|||
import { PlayerMode } from './peertube-player-options'
|
||||
import { SegmentValidator } from '../shared/p2p-media-loader/segment-validator'
|
||||
import { ChaptersPlugin } from '../shared/control-bar/chapters-plugin'
|
||||
import { ContextMenuPlugin } from '../shared/context-menu'
|
||||
|
||||
declare module 'video.js' {
|
||||
|
||||
|
@ -51,7 +52,7 @@ declare module 'video.js' {
|
|||
|
||||
peertubeResolutions (): PeerTubeResolutionsPlugin
|
||||
|
||||
contextmenuUI (options?: any): any
|
||||
contextMenu (options?: ContextMenuPluginOptions): ContextMenuPlugin
|
||||
|
||||
bezels (): BezelsPlugin
|
||||
peertubeMobile (): PeerTubeMobilePlugin
|
||||
|
@ -141,6 +142,19 @@ type MetricsPluginOptions = {
|
|||
videoUUID: () => string
|
||||
}
|
||||
|
||||
type ContextMenuPluginOptions = {
|
||||
content: () => {
|
||||
icon?: string
|
||||
label: string
|
||||
listener: () => void
|
||||
}[]
|
||||
}
|
||||
|
||||
type ContextMenuItemOptions = {
|
||||
listener: (e: videojs.EventTarget.Event) => void
|
||||
label: string
|
||||
}
|
||||
|
||||
type StoryboardOptions = {
|
||||
url: string
|
||||
width: number
|
||||
|
@ -294,8 +308,10 @@ export {
|
|||
PeerTubePluginOptions,
|
||||
WebVideoPluginOptions,
|
||||
P2PMediaLoaderPluginOptions,
|
||||
ContextMenuItemOptions,
|
||||
PeerTubeResolution,
|
||||
VideoJSPluginOptions,
|
||||
ContextMenuPluginOptions,
|
||||
UpNextPluginOptions,
|
||||
LoadedQualityData,
|
||||
StoryboardOptions,
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,31 +1,32 @@
|
|||
import { ApplicationRef, enableProdMode, APP_INITIALIZER, importProvidersFrom } from '@angular/core'
|
||||
import { enableDebugTools, BrowserModule, bootstrapApplication } from '@angular/platform-browser'
|
||||
import { environment } from './environments/environment'
|
||||
import { logger } from './root-helpers'
|
||||
import { AppComponent } from './app/app.component'
|
||||
import routes from './app/app.routes'
|
||||
import { ServiceWorkerModule } from '@angular/service-worker'
|
||||
import { polyfillICU } from './app/helpers'
|
||||
import { tap } from 'rxjs/operators'
|
||||
import {
|
||||
ServerService,
|
||||
PluginService,
|
||||
RedirectService, PreloadSelectedModulesList,
|
||||
MenuGuards,
|
||||
CustomReuseStrategy,
|
||||
getCoreProviders
|
||||
} from './app/core'
|
||||
import { APP_BASE_HREF, registerLocaleData } from '@angular/common'
|
||||
import localeOc from '@app/helpers/locales/oc'
|
||||
import { RouteReuseStrategy, provideRouter, withInMemoryScrolling, withPreloading } from '@angular/router'
|
||||
import { provideHttpClient } from '@angular/common/http'
|
||||
import { APP_INITIALIZER, ApplicationRef, enableProdMode, importProvidersFrom, provideZoneChangeDetection } from '@angular/core'
|
||||
import { BrowserModule, bootstrapApplication, enableDebugTools } from '@angular/platform-browser'
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
|
||||
import { RouteReuseStrategy, provideRouter, withInMemoryScrolling, withPreloading } from '@angular/router'
|
||||
import { ServiceWorkerModule } from '@angular/service-worker'
|
||||
import localeOc from '@app/helpers/locales/oc'
|
||||
import { getFormProviders } from '@app/shared/shared-forms/shared-form-providers'
|
||||
import { NgbModalModule } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { LoadingBarModule } from '@ngx-loading-bar/core'
|
||||
import { LoadingBarHttpClientModule } from '@ngx-loading-bar/http-client'
|
||||
import { NgbModalModule } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
|
||||
import { ToastModule } from 'primeng/toast'
|
||||
import { tap } from 'rxjs/operators'
|
||||
import { AppComponent } from './app/app.component'
|
||||
import routes from './app/app.routes'
|
||||
import {
|
||||
CustomReuseStrategy,
|
||||
MenuGuards,
|
||||
PluginService,
|
||||
PreloadSelectedModulesList,
|
||||
RedirectService,
|
||||
ServerService,
|
||||
getCoreProviders
|
||||
} from './app/core'
|
||||
import { polyfillICU } from './app/helpers'
|
||||
import { getMainProviders } from './app/shared/shared-main/main-providers'
|
||||
import { getFormProviders } from '@app/shared/shared-forms/shared-form-providers'
|
||||
import { environment } from './environments/environment'
|
||||
import { logger } from './root-helpers'
|
||||
|
||||
registerLocaleData(localeOc, 'oc')
|
||||
|
||||
|
@ -51,6 +52,8 @@ logger.registerServerSending(environment.apiUrl)
|
|||
|
||||
const bootstrap = () => bootstrapApplication(AppComponent, {
|
||||
providers: [
|
||||
provideZoneChangeDetection({ eventCoalescing: true }),
|
||||
|
||||
importProvidersFrom(
|
||||
BrowserModule,
|
||||
BrowserAnimationsModule,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-disable @typescript-eslint/no-implied-eval */
|
||||
import * as debug from 'debug'
|
||||
import debug from 'debug'
|
||||
import { firstValueFrom, ReplaySubject } from 'rxjs'
|
||||
import { first, shareReplay } from 'rxjs/operators'
|
||||
import { RegisterClientHelpers } from 'src/types/register-client-option.model'
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
@use '_icons' as *;
|
||||
|
||||
/* stylelint-disable */
|
||||
@import '~primeng/resources/primeng.css';
|
||||
@import 'primeng/resources/primeng.css';
|
||||
|
||||
// Override primeng style we don't want
|
||||
input[type=button] {
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
module.exports = require('path-browserify')
|
|
@ -1,3 +1,3 @@
|
|||
tsconfig.json
|
||||
*.ts
|
||||
webpack.config.ts
|
||||
vite.config.mjs
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"version": "0.0.7",
|
||||
"description": "API to communicate with the PeerTube player embed",
|
||||
"scripts": {
|
||||
"build": "../../../node_modules/.bin/tsc && ../../../node_modules/.bin/webpack --mode production --config ./webpack.config.js"
|
||||
"build": "rm -rf ./build ./dist && ../../../node_modules/.bin/tsc && ../../../node_modules/.bin/vite build --mode production --config ./vite.config.mjs"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
30
client/src/standalone/embed-player-api/vite.config.mjs
Normal file
30
client/src/standalone/embed-player-api/vite.config.mjs
Normal file
|
@ -0,0 +1,30 @@
|
|||
import { dirname, resolve } from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
import { defineConfig } from 'vite'
|
||||
import checker from 'vite-plugin-checker'
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
export default defineConfig(() => {
|
||||
return {
|
||||
build: {
|
||||
outDir: resolve(__dirname, 'build'),
|
||||
emptyOutDir: true,
|
||||
minify: 'esbuild',
|
||||
lib: {
|
||||
name: 'PeerTubePlayer',
|
||||
fileName: () => `player.min.js`,
|
||||
formats: [ 'umd' ],
|
||||
entry: './player.ts'
|
||||
}
|
||||
},
|
||||
|
||||
plugins: [
|
||||
checker({
|
||||
typescript: {
|
||||
tsconfigPath: resolve(__dirname, 'tsconfig.json')
|
||||
}
|
||||
})
|
||||
]
|
||||
}
|
||||
})
|
|
@ -84,5 +84,7 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<script type="module" src="./embed.ts"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -67,5 +67,7 @@
|
|||
<!-- iframes are used dynamically -->
|
||||
<iframe hidden></iframe>
|
||||
<a hidden></a>
|
||||
|
||||
<script type="module" src="./test-embed.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
55
client/src/standalone/videos/vite.config.mjs
Normal file
55
client/src/standalone/videos/vite.config.mjs
Normal file
|
@ -0,0 +1,55 @@
|
|||
import { defineConfig } from 'vite'
|
||||
import { resolve } from 'path'
|
||||
import { nodePolyfills } from 'vite-plugin-node-polyfills'
|
||||
import { dirname } from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
import checker from 'vite-plugin-checker'
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
const root = resolve(__dirname, '../../../')
|
||||
|
||||
export default defineConfig(() => {
|
||||
return {
|
||||
base: '/client/standalone/videos/',
|
||||
root: resolve(root, 'src', 'standalone', 'videos'),
|
||||
|
||||
resolve: {
|
||||
alias: [
|
||||
{ find: /^video.js$/, replacement: resolve(root, './node_modules/video.js/core.js') },
|
||||
{ find: /^hls.js$/, replacement: resolve(root, './node_modules/hls.js/dist/hls.light.mjs') },
|
||||
{ find: '@root-helpers', replacement: resolve(root, './src/root-helpers') }
|
||||
],
|
||||
},
|
||||
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
includePaths: [resolve(root, './src/sass/include')]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
build: {
|
||||
outDir: resolve(root, 'dist', 'standalone', 'videos'),
|
||||
emptyOutDir: true,
|
||||
|
||||
rollupOptions: {
|
||||
input: {
|
||||
embed: resolve(root, 'src', 'standalone', 'videos', 'embed.html'),
|
||||
'test-embed': resolve(root, 'src', 'standalone', 'videos', 'test-embed.html')
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
plugins: [
|
||||
checker({
|
||||
typescript: {
|
||||
tsconfigPath: resolve(root, 'src', 'standalone', 'videos', 'tsconfig.json')
|
||||
}
|
||||
}),
|
||||
|
||||
nodePolyfills()
|
||||
]
|
||||
}
|
||||
})
|
|
@ -1,19 +1,18 @@
|
|||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"downlevelIteration": true,
|
||||
"outDir": "./dist/out-tsc",
|
||||
"sourceMap": true,
|
||||
"declaration": false,
|
||||
"moduleResolution": "node",
|
||||
"module": "es2020",
|
||||
"esModuleInterop": true,
|
||||
"experimentalDecorators": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"alwaysStrict": true,
|
||||
"allowJs": true,
|
||||
"importHelpers": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strictBindCallApply": true,
|
||||
"target": "ES2022",
|
||||
"typeRoots": [
|
||||
|
@ -44,9 +43,6 @@
|
|||
"fs": [
|
||||
"src/shims/noop.ts"
|
||||
],
|
||||
"path": [
|
||||
"src/shims/path.ts"
|
||||
],
|
||||
"crypto": [
|
||||
"src/shims/noop.ts"
|
||||
]
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
const path = require('path')
|
||||
|
||||
// Helper functions
|
||||
const ROOT = path.resolve(__dirname, '..')
|
||||
const EVENT = process.env.npm_lifecycle_event || ''
|
||||
|
||||
function hasProcessFlag (flag) {
|
||||
return process.argv.join('').indexOf(flag) > -1
|
||||
}
|
||||
|
||||
function hasNpmFlag (flag) {
|
||||
return EVENT.includes(flag)
|
||||
}
|
||||
|
||||
function isWebpackDevServer () {
|
||||
return process.argv[1] && !!(/webpack-dev-server$/.exec(process.argv[1]))
|
||||
}
|
||||
|
||||
function root (args) {
|
||||
args = Array.prototype.slice.call(arguments, 0)
|
||||
return path.join.apply(path, [ROOT].concat(args))
|
||||
}
|
||||
|
||||
exports.hasProcessFlag = hasProcessFlag
|
||||
exports.hasNpmFlag = hasNpmFlag
|
||||
exports.isWebpackDevServer = isWebpackDevServer
|
||||
exports.root = root
|
|
@ -1,218 +0,0 @@
|
|||
const helpers = require('./helpers')
|
||||
const path = require('path')
|
||||
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
const TerserPlugin = require('terser-webpack-plugin')
|
||||
const ProvidePlugin = require('webpack/lib/ProvidePlugin')
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
||||
|
||||
module.exports = function () {
|
||||
const configuration = {
|
||||
entry: {
|
||||
'video-embed': './src/standalone/videos/embed.ts',
|
||||
'player': './src/standalone/embed-player-api/player.ts',
|
||||
'test-embed': './src/standalone/videos/test-embed.ts'
|
||||
},
|
||||
|
||||
resolve: {
|
||||
/*
|
||||
* An array of extensions that should be used to resolve modules.
|
||||
*
|
||||
* See: http://webpack.github.io/docs/configuration.html#resolve-extensions
|
||||
*/
|
||||
extensions: [ '.ts', '.js', '.json', '.scss' ],
|
||||
|
||||
modules: [ helpers.root('src'), 'node_modules' ],
|
||||
|
||||
symlinks: true,
|
||||
|
||||
alias: {
|
||||
'video.js$': path.resolve('node_modules/video.js/core.js'),
|
||||
'hls.js$': path.resolve('node_modules/hls.js/dist/hls.light.js'),
|
||||
'@root-helpers': path.resolve('src/root-helpers')
|
||||
},
|
||||
|
||||
fallback: {
|
||||
fs: [ path.resolve('src/shims/noop.ts') ],
|
||||
path: [ path.resolve('src/shims/path.ts') ],
|
||||
crypto: [ path.resolve('src/shims/noop.ts') ]
|
||||
}
|
||||
},
|
||||
|
||||
output: {
|
||||
path: helpers.root('dist/standalone/videos'),
|
||||
|
||||
filename: process.env.ANALYZE_BUNDLE === 'true'
|
||||
? '[name].bundle.js'
|
||||
: '[name].[contenthash].bundle.js',
|
||||
|
||||
sourceMapFilename: '[file].map',
|
||||
|
||||
chunkFilename: process.env.ANALYZE_BUNDLE === 'true'
|
||||
? '[name].chunk.js'
|
||||
: '[id].[contenthash].chunk.js',
|
||||
|
||||
publicPath: '/client/standalone/videos/'
|
||||
},
|
||||
|
||||
devtool: process.env.NODE_ENV === 'production' ? false : 'source-map',
|
||||
|
||||
module: {
|
||||
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
use: [
|
||||
getBabelLoader(),
|
||||
|
||||
{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
configFile: helpers.root('src/standalone/videos/tsconfig.json')
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.m?js$/,
|
||||
use: [ getBabelLoader() ]
|
||||
},
|
||||
|
||||
{
|
||||
test: /\.(sass|scss)$/,
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
importLoaders: 1
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
loader: 'sass-loader',
|
||||
options: {
|
||||
sassOptions: {
|
||||
sourceMap: true,
|
||||
includePaths: [
|
||||
helpers.root('src/sass/include')
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
test: /\.html$/,
|
||||
exclude: [
|
||||
helpers.root('src/index.html'),
|
||||
helpers.root('src/standalone/videos/embed.html'),
|
||||
helpers.root('src/standalone/videos/test-embed.html')
|
||||
],
|
||||
type: 'asset/source'
|
||||
},
|
||||
|
||||
{
|
||||
test: /\.(jpg|png|gif|svg)$/,
|
||||
type: 'asset'
|
||||
},
|
||||
|
||||
{
|
||||
test: /\.(ttf|eot|woff2?)$/,
|
||||
type: 'asset'
|
||||
}
|
||||
]
|
||||
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new ProvidePlugin({
|
||||
process: 'process/browser',
|
||||
Buffer: [ 'buffer', 'Buffer' ]
|
||||
}),
|
||||
|
||||
new MiniCssExtractPlugin({
|
||||
filename: process.env.ANALYZE_BUNDLE === 'true'
|
||||
? '[name].css'
|
||||
: '[name].[contenthash].css'
|
||||
}),
|
||||
|
||||
new HtmlWebpackPlugin({
|
||||
template: 'src/standalone/videos/embed.html',
|
||||
filename: 'embed.html',
|
||||
title: 'PeerTube',
|
||||
chunksSortMode: 'auto',
|
||||
inject: 'body',
|
||||
chunks: [ 'video-embed' ],
|
||||
minify: {
|
||||
collapseWhitespace: true,
|
||||
removeComments: false,
|
||||
removeRedundantAttributes: true,
|
||||
removeScriptTypeAttributes: true,
|
||||
removeStyleLinkTypeAttributes: true,
|
||||
useShortDoctype: true
|
||||
}
|
||||
}),
|
||||
|
||||
new HtmlWebpackPlugin({
|
||||
template: '!!html-loader!src/standalone/videos/test-embed.html',
|
||||
filename: 'test-embed.html',
|
||||
title: 'PeerTube',
|
||||
chunksSortMode: 'auto',
|
||||
inject: 'body',
|
||||
chunks: [ 'test-embed' ]
|
||||
})
|
||||
],
|
||||
|
||||
optimization: {
|
||||
minimizer: [
|
||||
new TerserPlugin({
|
||||
terserOptions: {
|
||||
ecma: 6,
|
||||
warnings: false,
|
||||
ie8: false,
|
||||
safari10: false,
|
||||
mangle: true,
|
||||
compress: {
|
||||
passes: 3,
|
||||
pure_getters: true
|
||||
},
|
||||
output: {
|
||||
ascii_only: true,
|
||||
comments: false
|
||||
}
|
||||
}
|
||||
})
|
||||
]
|
||||
},
|
||||
|
||||
performance: {
|
||||
maxEntrypointSize: 700000, // 600kB
|
||||
maxAssetSize: 700000
|
||||
},
|
||||
|
||||
node: {
|
||||
global: true
|
||||
}
|
||||
}
|
||||
|
||||
return configuration
|
||||
}
|
||||
|
||||
function getBabelLoader () {
|
||||
return {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
presets: [
|
||||
[
|
||||
'@babel/preset-env', {
|
||||
targets: 'last 1 Chrome version, last 2 Edge major versions, Firefox ESR, Safari >= 12, ios_saf >= 12'
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
5715
client/yarn.lock
5715
client/yarn.lock
File diff suppressed because it is too large
Load diff
|
@ -62,7 +62,7 @@ if [ -z ${1+x} ] || ([ "$1" != "--light" ] && [ "$1" != "--analyze-bundle" ]); t
|
|||
for key in "${!languages[@]}"; do
|
||||
lang=${languages[$key]}
|
||||
|
||||
mv "dist/build/$key" "dist/$lang"
|
||||
mv "dist/build/browser/$key" "dist/$lang"
|
||||
|
||||
if [ "$lang" != "en-US" ]; then
|
||||
# Do not duplicate assets
|
||||
|
@ -72,13 +72,14 @@ if [ -z ${1+x} ] || ([ "$1" != "--light" ] && [ "$1" != "--analyze-bundle" ]); t
|
|||
|
||||
mv "./dist/$defaultLanguage/assets" "./dist"
|
||||
|
||||
rmdir "dist/build"
|
||||
rm -r "dist/build"
|
||||
cp "./dist/$defaultLanguage/manifest.webmanifest" "./dist/manifest.webmanifest"
|
||||
else
|
||||
additionalParams=""
|
||||
if [ ! -z ${1+x} ] && [ "$1" == "--analyze-bundle" ]; then
|
||||
additionalParams="--named-chunks=true --output-hashing=none"
|
||||
|
||||
# For webpack
|
||||
# For Vite
|
||||
export ANALYZE_BUNDLE=true
|
||||
fi
|
||||
|
||||
|
@ -86,8 +87,6 @@ else
|
|||
--configuration production --stats-json $additionalParams
|
||||
fi
|
||||
|
||||
cp "./dist/$defaultLanguage/manifest.webmanifest" "./dist/manifest.webmanifest"
|
||||
|
||||
cd ../ && npm run build:embed && cd client/
|
||||
|
||||
# Copy runtime locales
|
||||
|
|
|
@ -2,12 +2,4 @@
|
|||
|
||||
set -eu
|
||||
|
||||
cd client
|
||||
|
||||
mkdir -p ./dist/standalone/videos/
|
||||
|
||||
if [ ! -z ${ANALYZE_BUNDLE+x} ] && [ "$ANALYZE_BUNDLE" == true ]; then
|
||||
NODE_ENV=production npm run webpack -- --config webpack/webpack.video-embed.js --mode production --json > "./dist/standalone/videos/embed-stats.json"
|
||||
else
|
||||
NODE_ENV=production npm run webpack -- --config webpack/webpack.video-embed.js --mode production
|
||||
fi
|
||||
cd client && ./node_modules/.bin/vite -c ./src/standalone/videos/vite.config.mjs build --mode=production
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
set -eu
|
||||
|
||||
gawk -i inplace 'BEGIN { found=0 } { if (found || $0 ~ /^{/) { found=1; print }}' ./client/dist/standalone/videos/embed-stats.json
|
||||
|
||||
npm run concurrently -- -k \
|
||||
"cd client && npm run webpack-bundle-analyzer -- -p 8888 ./dist/en-US/stats.json" \
|
||||
"cd client && npm run webpack-bundle-analyzer -- -p 8889 ./dist/standalone/videos/embed-stats.json"
|
||||
"cd client/src/standalone/videos/ && npx vite-bundle-visualizer" \
|
||||
"cd client && npx esbuild-visualizer --metadata ./dist/en-US/stats.json"
|
||||
|
|
|
@ -8,7 +8,7 @@ if [ ! -z ${2+x} ] && [ "$2" = "--ar-locale" ]; then
|
|||
clientConfiguration="ar-locale"
|
||||
fi
|
||||
|
||||
clientCommand="cd client && node --max_old_space_size=4096 node_modules/.bin/ng serve --proxy-config proxy.config.json --hmr --configuration $clientConfiguration --host 0.0.0.0 --disable-host-check --port 3000"
|
||||
clientCommand="cd client && node --max_old_space_size=4096 node_modules/.bin/ng serve --proxy-config proxy.config.json --hmr --configuration $clientConfiguration --host 0.0.0.0 --port 3000"
|
||||
serverCommand="NODE_ENV=dev node dist/server"
|
||||
|
||||
if [ ! -z ${1+x} ] && [ "$1" = "--skip-server" ]; then
|
||||
|
|
|
@ -5,5 +5,5 @@ set -eu
|
|||
npm run build:server
|
||||
|
||||
npm run concurrently -- -k \
|
||||
"cd client && npm run webpack -- --config webpack/webpack.video-embed.js --mode development --watch" \
|
||||
"cd client && ./node_modules/.bin/vite -c ./src/standalone/videos/vite.config.mjs build -w --mode=development" \
|
||||
"NODE_ENV=dev npm start"
|
||||
|
|
|
@ -4,8 +4,7 @@ set -eu
|
|||
|
||||
cd client/src/standalone/embed-player-api
|
||||
|
||||
rm -rf dist build && tsc -p . && ../../../node_modules/.bin/webpack --config ./webpack.config.js
|
||||
|
||||
npm run build
|
||||
npm publish --access public
|
||||
|
||||
rm -rf dist build node_modules
|
||||
|
|
|
@ -35,7 +35,7 @@ export class PageHtml {
|
|||
static async getEmbedHTML () {
|
||||
const path = this.getEmbedHTMLPath()
|
||||
|
||||
// Disable HTML cache in dev mode because webpack can regenerate JS files
|
||||
// Disable HTML cache in dev mode because Vite can regenerate JS files
|
||||
if (!isTestOrDevInstance() && this.htmlCache[path]) {
|
||||
return this.htmlCache[path]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue