]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - client/src/app/helpers/utils.ts
Fix tags in search filters
[github/Chocobozzz/PeerTube.git] / client / src / app / helpers / utils.ts
CommitLineData
61bbc727 1import { DatePipe } from '@angular/common'
67ed6552
C
2import { environment } from '../../environments/environment'
3import { AuthService } from '../core/auth'
9abd170d 4import { SelectChannelItem } from '@app/shared/shared-forms/select-channel.component'
15a7387d 5
240458d0 6// Thanks: https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript
f3aaa9a9
C
7function getParameterByName (name: string, url: string) {
8 if (!url) url = window.location.href
9 name = name.replace(/[\[\]]/g, '\\$&')
10
11 const regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)')
12 const results = regex.exec(url)
13
14 if (!results) return null
15 if (!results[2]) return ''
16
17 return decodeURIComponent(results[2].replace(/\+/g, ' '))
18}
19
02c01341
RK
20function populateAsyncUserVideoChannels (
21 authService: AuthService,
9abd170d 22 channel: SelectChannelItem[]
02c01341 23) {
15a7387d
C
24 return new Promise(res => {
25 authService.userInformationLoaded
26 .subscribe(
27 () => {
28 const user = authService.getUser()
29 if (!user) return
30
31 const videoChannels = user.videoChannels
32 if (Array.isArray(videoChannels) === false) return
33
02c01341
RK
34 videoChannels.forEach(c => channel.push({
35 id: c.id,
36 label: c.displayName,
37 support: c.support,
38 avatarPath: c.avatar?.path
39 }))
15a7387d
C
40
41 return res()
42 }
43 )
44 })
45}
46
c5911fd3 47function getAbsoluteAPIUrl () {
94148c90
C
48 let absoluteAPIUrl = environment.hmr === true
49 ? 'http://localhost:9000'
50 : environment.apiUrl
51
c5911fd3
C
52 if (!absoluteAPIUrl) {
53 // The API is on the same domain
54 absoluteAPIUrl = window.location.origin
55 }
56
57 return absoluteAPIUrl
58}
59
72493e44
C
60function getAbsoluteEmbedUrl () {
61 let absoluteEmbedUrl = environment.embedUrl
62 if (!absoluteEmbedUrl) {
63 // The Embed is on the same domain
64 absoluteEmbedUrl = window.location.origin
65 }
66
67 return absoluteEmbedUrl
68}
69
61bbc727
C
70const datePipe = new DatePipe('en')
71function dateToHuman (date: string) {
72 return datePipe.transform(date, 'medium')
73}
74
11b8762f
C
75function durationToString (duration: number) {
76 const hours = Math.floor(duration / 3600)
77 const minutes = Math.floor((duration % 3600) / 60)
78 const seconds = duration % 60
79
80 const minutesPadding = minutes >= 10 ? '' : '0'
81 const secondsPadding = seconds >= 10 ? '' : '0'
82 const displayedHours = hours > 0 ? hours.toString() + ':' : ''
83
e66883b3
RK
84 return (
85 displayedHours + minutesPadding + minutes.toString() + ':' + secondsPadding + seconds.toString()
86 ).replace(/^0/, '')
11b8762f
C
87}
88
0cd4344f
C
89function immutableAssign <A, B> (target: A, source: B) {
90 return Object.assign({}, target, source)
91}
92
6de36768
C
93// Thanks: https://gist.github.com/ghinda/8442a57f22099bdb2e34
94function objectToFormData (obj: any, form?: FormData, namespace?: string) {
c4710631 95 const fd = form || new FormData()
6de36768
C
96 let formKey
97
c4710631 98 for (const key of Object.keys(obj)) {
6de36768
C
99 if (namespace) formKey = `${namespace}[${key}]`
100 else formKey = key
101
102 if (obj[key] === undefined) continue
103
2efd32f6
C
104 if (Array.isArray(obj[key]) && obj[key].length === 0) {
105 fd.append(key, null)
106 continue
107 }
108
360329cc 109 if (obj[key] !== null && typeof obj[ key ] === 'object' && !(obj[ key ] instanceof File)) {
40e87e9e 110 objectToFormData(obj[ key ], fd, formKey)
6de36768
C
111 } else {
112 fd.append(formKey, obj[ key ])
113 }
114 }
115
116 return fd
117}
118
1506307f 119function objectLineFeedToHtml (obj: any, keyToNormalize: string) {
5de8a55a 120 return immutableAssign(obj, {
1506307f 121 [keyToNormalize]: lineFeedToHtml(obj[keyToNormalize])
5de8a55a
C
122 })
123}
124
1506307f
C
125function lineFeedToHtml (text: string) {
126 if (!text) return text
127
128 return text.replace(/\r?\n|\r/g, '<br />')
129}
130
40e87e9e
C
131function removeElementFromArray <T> (arr: T[], elem: T) {
132 const index = arr.indexOf(elem)
133 if (index !== -1) arr.splice(index, 1)
134}
135
ad774752
C
136function sortBy (obj: any[], key1: string, key2?: string) {
137 return obj.sort((a, b) => {
138 const elem1 = key2 ? a[key1][key2] : a[key1]
139 const elem2 = key2 ? b[key1][key2] : b[key1]
140
141 if (elem1 < elem2) return -1
142 if (elem1 === elem2) return 0
143 return 1
144 })
145}
146
7373507f
C
147function scrollToTop () {
148 window.scroll(0, 0)
149}
150
0c503f5c
C
151// Thanks: https://github.com/uupaa/dynamic-import-polyfill
152function importModule (path: string) {
153 return new Promise((resolve, reject) => {
154 const vector = '$importModule$' + Math.random().toString(32).slice(2)
155 const script = document.createElement('script')
156
157 const destructor = () => {
158 delete window[ vector ]
159 script.onerror = null
160 script.onload = null
161 script.remove()
162 URL.revokeObjectURL(script.src)
163 script.src = ''
164 }
165
166 script.defer = true
167 script.type = 'module'
168
169 script.onerror = () => {
170 reject(new Error(`Failed to import: ${path}`))
171 destructor()
172 }
173 script.onload = () => {
174 resolve(window[ vector ])
175 destructor()
176 }
177 const absURL = (environment.apiUrl || window.location.origin) + path
178 const loader = `import * as m from "${absURL}"; window.${vector} = m;` // export Module
179 const blob = new Blob([ loader ], { type: 'text/javascript' })
180 script.src = URL.createObjectURL(blob)
181
182 document.head.appendChild(script)
183 })
184}
185
223b24e6
RK
186function isInViewport (el: HTMLElement) {
187 const bounding = el.getBoundingClientRect()
188 return (
189 bounding.top >= 0 &&
190 bounding.left >= 0 &&
191 bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
192 bounding.right <= (window.innerWidth || document.documentElement.clientWidth)
193 )
194}
195
196function isXPercentInViewport (el: HTMLElement, percentVisible: number) {
197 const rect = el.getBoundingClientRect()
198 const windowHeight = (window.innerHeight || document.documentElement.clientHeight)
199
200 return !(
201 Math.floor(100 - (((rect.top >= 0 ? 0 : rect.top) / +-(rect.height / 1)) * 100)) < percentVisible ||
202 Math.floor(100 - ((rect.bottom - windowHeight) / rect.height) * 100) < percentVisible
203 )
204}
205
f3aaa9a9 206export {
ad774752 207 sortBy,
11b8762f 208 durationToString,
1506307f 209 lineFeedToHtml,
15a7387d 210 getParameterByName,
c5911fd3 211 populateAsyncUserVideoChannels,
61bbc727
C
212 getAbsoluteAPIUrl,
213 dateToHuman,
6de36768 214 immutableAssign,
5de8a55a 215 objectToFormData,
72493e44 216 getAbsoluteEmbedUrl,
1506307f 217 objectLineFeedToHtml,
7373507f 218 removeElementFromArray,
0c503f5c 219 importModule,
223b24e6
RK
220 scrollToTop,
221 isInViewport,
222 isXPercentInViewport
f3aaa9a9 223}