X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=client%2Fsrc%2Fapp%2Fhelpers%2Futils.ts;h=94f6def2676c0b84a907e9f8fe8cb48067aaa6db;hb=ad35265d743e621d86f3f0796dd9d8795c599dca;hp=825b6ca9620efe118e2c0c593b5bbd6bd959b290;hpb=4504f09f6e85f09b0489debb547a17209d7176ea;p=github%2FChocobozzz%2FPeerTube.git diff --git a/client/src/app/helpers/utils.ts b/client/src/app/helpers/utils.ts index 825b6ca96..94f6def26 100644 --- a/client/src/app/helpers/utils.ts +++ b/client/src/app/helpers/utils.ts @@ -1,4 +1,9 @@ +import { first, map } from 'rxjs/operators' +import { SelectChannelItem } from 'src/types/select-options-item.model' import { DatePipe } from '@angular/common' +import { HttpErrorResponse } from '@angular/common/http' +import { Notifier } from '@app/core' +import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' import { environment } from '../../environments/environment' import { AuthService } from '../core/auth' @@ -16,23 +21,31 @@ function getParameterByName (name: string, url: string) { return decodeURIComponent(results[2].replace(/\+/g, ' ')) } -function populateAsyncUserVideoChannels (authService: AuthService, channel: { id: number, label: string, support?: string }[]) { - return new Promise(res => { - authService.userInformationLoaded - .subscribe( - () => { - const user = authService.getUser() - if (!user) return - - const videoChannels = user.videoChannels - if (Array.isArray(videoChannels) === false) return - - videoChannels.forEach(c => channel.push({ id: c.id, label: c.displayName, support: c.support })) - - return res() - } - ) - }) +function listUserChannels (authService: AuthService) { + return authService.userInformationLoaded + .pipe( + first(), + map(() => { + const user = authService.getUser() + if (!user) return undefined + + const videoChannels = user.videoChannels + if (Array.isArray(videoChannels) === false) return undefined + + return videoChannels + .sort((a, b) => { + if (a.updatedAt < b.updatedAt) return 1 + if (a.updatedAt > b.updatedAt) return -1 + return 0 + }) + .map(c => ({ + id: c.id, + label: c.displayName, + support: c.support, + avatarPath: c.avatar?.path + }) as SelectChannelItem) + }) + ) } function getAbsoluteAPIUrl () { @@ -49,7 +62,7 @@ function getAbsoluteAPIUrl () { } function getAbsoluteEmbedUrl () { - let absoluteEmbedUrl = environment.embedUrl + let absoluteEmbedUrl = environment.originServerUrl if (!absoluteEmbedUrl) { // The Embed is on the same domain absoluteEmbedUrl = window.location.origin @@ -135,42 +148,11 @@ function sortBy (obj: any[], key1: string, key2?: string) { }) } -function scrollToTop () { - window.scroll(0, 0) -} - -// Thanks: https://github.com/uupaa/dynamic-import-polyfill -function importModule (path: string) { - return new Promise((resolve, reject) => { - const vector = '$importModule$' + Math.random().toString(32).slice(2) - const script = document.createElement('script') - - const destructor = () => { - delete window[ vector ] - script.onerror = null - script.onload = null - script.remove() - URL.revokeObjectURL(script.src) - script.src = '' - } - - script.defer = true - script.type = 'module' - - script.onerror = () => { - reject(new Error(`Failed to import: ${path}`)) - destructor() - } - script.onload = () => { - resolve(window[ vector ]) - destructor() - } - const absURL = (environment.apiUrl || window.location.origin) + path - const loader = `import * as m from "${absURL}"; window.${vector} = m;` // export Module - const blob = new Blob([ loader ], { type: 'text/javascript' }) - script.src = URL.createObjectURL(blob) - - document.head.appendChild(script) +function scrollToTop (behavior: 'auto' | 'smooth' = 'auto') { + window.scrollTo({ + left: 0, + top: 0, + behavior }) } @@ -194,12 +176,41 @@ function isXPercentInViewport (el: HTMLElement, percentVisible: number) { ) } +function genericUploadErrorHandler (parameters: { + err: Pick + name: string + notifier: Notifier + sticky?: boolean +}) { + const { err, name, notifier, sticky } = { sticky: false, ...parameters } + const title = $localize`The upload failed` + let message = err.message + + if (err instanceof ErrorEvent) { // network error + message = $localize`The connection was interrupted` + notifier.error(message, title, null, sticky) + } else if (err.status === HttpStatusCode.INTERNAL_SERVER_ERROR_500) { + message = $localize`The server encountered an error` + notifier.error(message, title, null, sticky) + } else if (err.status === HttpStatusCode.REQUEST_TIMEOUT_408) { + message = $localize`Your ${name} file couldn't be transferred before the set timeout (usually 10min)` + notifier.error(message, title, null, sticky) + } else if (err.status === HttpStatusCode.PAYLOAD_TOO_LARGE_413) { + const maxFileSize = err.headers?.get('X-File-Maximum-Size') || '8G' + message = $localize`Your ${name} file was too large (max. size: ${maxFileSize})` + notifier.error(message, title, null, sticky) + } else { + notifier.error(err.message, title) + } + + return message +} + export { sortBy, durationToString, lineFeedToHtml, getParameterByName, - populateAsyncUserVideoChannels, getAbsoluteAPIUrl, dateToHuman, immutableAssign, @@ -207,8 +218,9 @@ export { getAbsoluteEmbedUrl, objectLineFeedToHtml, removeElementFromArray, - importModule, scrollToTop, isInViewport, - isXPercentInViewport + isXPercentInViewport, + listUserChannels, + genericUploadErrorHandler }