From 15a7eafb892441957ba7dd6fcbf556086fe5b2b3 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 26 Jul 2021 15:04:37 +0200 Subject: Refactor video links builders --- shared/core-utils/common/date.ts | 47 ++++++++++++- shared/core-utils/common/index.ts | 3 +- shared/core-utils/common/miscs.ts | 10 --- shared/core-utils/common/promises.ts | 12 ++++ shared/core-utils/common/url.ts | 130 +++++++++++++++++++++++++++++++++++ shared/core-utils/index.ts | 1 - shared/core-utils/logs/index.ts | 1 - shared/core-utils/logs/logs.ts | 25 ------- shared/core-utils/plugins/hooks.ts | 2 +- 9 files changed, 191 insertions(+), 40 deletions(-) create mode 100644 shared/core-utils/common/promises.ts delete mode 100644 shared/core-utils/logs/index.ts delete mode 100644 shared/core-utils/logs/logs.ts (limited to 'shared/core-utils') diff --git a/shared/core-utils/common/date.ts b/shared/core-utils/common/date.ts index 4f92f758f..3e4a3c08c 100644 --- a/shared/core-utils/common/date.ts +++ b/shared/core-utils/common/date.ts @@ -43,6 +43,49 @@ function isLastWeek (d: Date) { return getDaysDifferences(now, d) <= 7 } +function timeToInt (time: number | string) { + if (!time) return 0 + if (typeof time === 'number') return time + + const reg = /^((\d+)[h:])?((\d+)[m:])?((\d+)s?)?$/ + const matches = time.match(reg) + + if (!matches) return 0 + + const hours = parseInt(matches[2] || '0', 10) + const minutes = parseInt(matches[4] || '0', 10) + const seconds = parseInt(matches[6] || '0', 10) + + return hours * 3600 + minutes * 60 + seconds +} + +function secondsToTime (seconds: number, full = false, symbol?: string) { + let time = '' + + if (seconds === 0 && !full) return '0s' + + const hourSymbol = (symbol || 'h') + const minuteSymbol = (symbol || 'm') + const secondsSymbol = full ? '' : 's' + + const hours = Math.floor(seconds / 3600) + if (hours >= 1) time = hours + hourSymbol + else if (full) time = '0' + hourSymbol + + seconds %= 3600 + const minutes = Math.floor(seconds / 60) + if (minutes >= 1 && minutes < 10 && full) time += '0' + minutes + minuteSymbol + else if (minutes >= 1) time += minutes + minuteSymbol + else if (full) time += '00' + minuteSymbol + + seconds %= 60 + if (seconds >= 1 && seconds < 10 && full) time += '0' + seconds + secondsSymbol + else if (seconds >= 1) time += seconds + secondsSymbol + else if (full) time += '00' + + return time +} + // --------------------------------------------------------------------------- export { @@ -51,7 +94,9 @@ export { isThisMonth, isToday, isLastMonth, - isLastWeek + isLastWeek, + timeToInt, + secondsToTime } // --------------------------------------------------------------------------- diff --git a/shared/core-utils/common/index.ts b/shared/core-utils/common/index.ts index 83f2ccbb6..0908ff981 100644 --- a/shared/core-utils/common/index.ts +++ b/shared/core-utils/common/index.ts @@ -1,5 +1,6 @@ export * from './date' export * from './miscs' export * from './regexp' +export * from './promises' export * from './types' -export * from './url +export * from './url' diff --git a/shared/core-utils/common/miscs.ts b/shared/core-utils/common/miscs.ts index 4780ca922..bc65dc338 100644 --- a/shared/core-utils/common/miscs.ts +++ b/shared/core-utils/common/miscs.ts @@ -20,14 +20,6 @@ function compareSemVer (a: string, b: string) { return segmentsA.length - segmentsB.length } -function isPromise (value: any) { - return value && typeof value.then === 'function' -} - -function isCatchable (value: any) { - return value && typeof value.catch === 'function' -} - function sortObjectComparator (key: string, order: 'asc' | 'desc') { return (a: any, b: any) => { if (a[key] < b[key]) { @@ -45,7 +37,5 @@ function sortObjectComparator (key: string, order: 'asc' | 'desc') { export { randomInt, compareSemVer, - isPromise, - isCatchable, sortObjectComparator } diff --git a/shared/core-utils/common/promises.ts b/shared/core-utils/common/promises.ts new file mode 100644 index 000000000..7ef9d60b6 --- /dev/null +++ b/shared/core-utils/common/promises.ts @@ -0,0 +1,12 @@ +function isPromise (value: any) { + return value && typeof value.then === 'function' +} + +function isCatchable (value: any) { + return value && typeof value.catch === 'function' +} + +export { + isPromise, + isCatchable +} diff --git a/shared/core-utils/common/url.ts b/shared/core-utils/common/url.ts index e69de29bb..52ed247c4 100644 --- a/shared/core-utils/common/url.ts +++ b/shared/core-utils/common/url.ts @@ -0,0 +1,130 @@ +import { Video, VideoPlaylist } from '../../models' +import { secondsToTime } from './date' + +function buildPlaylistLink (playlist: Pick, base?: string) { + return (base ?? window.location.origin) + buildPlaylistWatchPath(playlist) +} + +function buildPlaylistWatchPath (playlist: Pick) { + return '/w/p/' + playlist.shortUUID +} + +function buildVideoWatchPath (video: Pick) { + return '/w/' + video.shortUUID +} + +function buildVideoLink (video: Pick, base?: string) { + return (base ?? window.location.origin) + buildVideoWatchPath(video) +} + +function buildPlaylistEmbedPath (playlist: Pick) { + return '/video-playlists/embed/' + playlist.uuid +} + +function buildPlaylistEmbedLink (playlist: Pick, base?: string) { + return (base ?? window.location.origin) + buildPlaylistEmbedPath(playlist) +} + +function buildVideoEmbedPath (video: Pick) { + return '/videos/embed/' + video.uuid +} + +function buildVideoEmbedLink (video: Pick, base?: string) { + return (base ?? window.location.origin) + buildVideoEmbedPath(video) +} + +function decorateVideoLink (options: { + url: string + + startTime?: number + stopTime?: number + + subtitle?: string + + loop?: boolean + autoplay?: boolean + muted?: boolean + + // Embed options + title?: boolean + warningTitle?: boolean + controls?: boolean + peertubeLink?: boolean +}) { + const { url } = options + + const params = generateParams(window.location.search) + + if (options.startTime !== undefined && options.startTime !== null) { + const startTimeInt = Math.floor(options.startTime) + params.set('start', secondsToTime(startTimeInt)) + } + + if (options.stopTime) { + const stopTimeInt = Math.floor(options.stopTime) + params.set('stop', secondsToTime(stopTimeInt)) + } + + if (options.subtitle) params.set('subtitle', options.subtitle) + + if (options.loop === true) params.set('loop', '1') + if (options.autoplay === true) params.set('autoplay', '1') + if (options.muted === true) params.set('muted', '1') + if (options.title === false) params.set('title', '0') + if (options.warningTitle === false) params.set('warningTitle', '0') + if (options.controls === false) params.set('controls', '0') + if (options.peertubeLink === false) params.set('peertubeLink', '0') + + return buildUrl(url, params) +} + +function decoratePlaylistLink (options: { + url: string + + playlistPosition?: number +}) { + const { url } = options + + const params = generateParams(window.location.search) + + if (options.playlistPosition) params.set('playlistPosition', '' + options.playlistPosition) + + return buildUrl(url, params) +} + +// --------------------------------------------------------------------------- + +export { + buildPlaylistLink, + buildVideoLink, + + buildVideoWatchPath, + buildPlaylistWatchPath, + + buildPlaylistEmbedPath, + buildVideoEmbedPath, + + buildPlaylistEmbedLink, + buildVideoEmbedLink, + + decorateVideoLink, + decoratePlaylistLink +} + +function buildUrl (url: string, params: URLSearchParams) { + let hasParams = false + params.forEach(() => { hasParams = true }) + + if (hasParams) return url + '?' + params.toString() + + return url +} + +function generateParams (url: string) { + const params = new URLSearchParams(window.location.search) + // Unused parameters in embed + params.delete('videoId') + params.delete('resume') + + return params +} diff --git a/shared/core-utils/index.ts b/shared/core-utils/index.ts index 0b05dc9eb..66d50ef93 100644 --- a/shared/core-utils/index.ts +++ b/shared/core-utils/index.ts @@ -1,7 +1,6 @@ export * from './abuse' export * from './common' export * from './i18n' -export * from './logs' export * from './plugins' export * from './renderer' export * from './users' diff --git a/shared/core-utils/logs/index.ts b/shared/core-utils/logs/index.ts deleted file mode 100644 index ceb5d7a7f..000000000 --- a/shared/core-utils/logs/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './logs' diff --git a/shared/core-utils/logs/logs.ts b/shared/core-utils/logs/logs.ts deleted file mode 100644 index d0996cf55..000000000 --- a/shared/core-utils/logs/logs.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { stat } from 'fs-extra' - -async function mtimeSortFilesDesc (files: string[], basePath: string) { - const promises = [] - const out: { file: string, mtime: number }[] = [] - - for (const file of files) { - const p = stat(basePath + '/' + file) - .then(stats => { - if (stats.isFile()) out.push({ file, mtime: stats.mtime.getTime() }) - }) - - promises.push(p) - } - - await Promise.all(promises) - - out.sort((a, b) => b.mtime - a.mtime) - - return out -} - -export { - mtimeSortFilesDesc -} diff --git a/shared/core-utils/plugins/hooks.ts b/shared/core-utils/plugins/hooks.ts index 5405e0529..92cb5ad68 100644 --- a/shared/core-utils/plugins/hooks.ts +++ b/shared/core-utils/plugins/hooks.ts @@ -1,5 +1,5 @@ import { HookType } from '../../models/plugins/hook-type.enum' -import { isCatchable, isPromise } from '../miscs/miscs' +import { isCatchable, isPromise } from '../common/promises' function getHookType (hookName: string) { if (hookName.startsWith('filter:')) return HookType.FILTER -- cgit v1.2.3