]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/app/helpers/utils.ts
allow private syndication feeds via a user feedToken
[github/Chocobozzz/PeerTube.git] / client / src / app / helpers / utils.ts
1 import { DatePipe } from '@angular/common'
2 import { SelectChannelItem } from '@app/shared/shared-forms'
3 import { environment } from '../../environments/environment'
4 import { AuthService } from '../core/auth'
5
6 // Thanks: https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript
7 function 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
20 function populateAsyncUserVideoChannels (
21 authService: AuthService,
22 channel: SelectChannelItem[]
23 ) {
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
34 videoChannels.forEach(c => channel.push({
35 id: c.id,
36 label: c.displayName,
37 support: c.support,
38 avatarPath: c.avatar?.path
39 }))
40
41 return res()
42 }
43 )
44 })
45 }
46
47 function getAbsoluteAPIUrl () {
48 let absoluteAPIUrl = environment.hmr === true
49 ? 'http://localhost:9000'
50 : environment.apiUrl
51
52 if (!absoluteAPIUrl) {
53 // The API is on the same domain
54 absoluteAPIUrl = window.location.origin
55 }
56
57 return absoluteAPIUrl
58 }
59
60 function 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
70 const datePipe = new DatePipe('en')
71 function dateToHuman (date: string) {
72 return datePipe.transform(date, 'medium')
73 }
74
75 function 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
84 return (
85 displayedHours + minutesPadding + minutes.toString() + ':' + secondsPadding + seconds.toString()
86 ).replace(/^0/, '')
87 }
88
89 function immutableAssign <A, B> (target: A, source: B) {
90 return Object.assign({}, target, source)
91 }
92
93 // Thanks: https://gist.github.com/ghinda/8442a57f22099bdb2e34
94 function objectToFormData (obj: any, form?: FormData, namespace?: string) {
95 const fd = form || new FormData()
96 let formKey
97
98 for (const key of Object.keys(obj)) {
99 if (namespace) formKey = `${namespace}[${key}]`
100 else formKey = key
101
102 if (obj[key] === undefined) continue
103
104 if (Array.isArray(obj[key]) && obj[key].length === 0) {
105 fd.append(key, null)
106 continue
107 }
108
109 if (obj[key] !== null && typeof obj[ key ] === 'object' && !(obj[ key ] instanceof File)) {
110 objectToFormData(obj[ key ], fd, formKey)
111 } else {
112 fd.append(formKey, obj[ key ])
113 }
114 }
115
116 return fd
117 }
118
119 function objectLineFeedToHtml (obj: any, keyToNormalize: string) {
120 return immutableAssign(obj, {
121 [keyToNormalize]: lineFeedToHtml(obj[keyToNormalize])
122 })
123 }
124
125 function lineFeedToHtml (text: string) {
126 if (!text) return text
127
128 return text.replace(/\r?\n|\r/g, '<br />')
129 }
130
131 function removeElementFromArray <T> (arr: T[], elem: T) {
132 const index = arr.indexOf(elem)
133 if (index !== -1) arr.splice(index, 1)
134 }
135
136 function 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
147 function scrollToTop (behavior: 'auto' | 'smooth' = 'auto') {
148 window.scrollTo({
149 left: 0,
150 top: 0,
151 behavior
152 })
153 }
154
155 function isInViewport (el: HTMLElement) {
156 const bounding = el.getBoundingClientRect()
157 return (
158 bounding.top >= 0 &&
159 bounding.left >= 0 &&
160 bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
161 bounding.right <= (window.innerWidth || document.documentElement.clientWidth)
162 )
163 }
164
165 function isXPercentInViewport (el: HTMLElement, percentVisible: number) {
166 const rect = el.getBoundingClientRect()
167 const windowHeight = (window.innerHeight || document.documentElement.clientHeight)
168
169 return !(
170 Math.floor(100 - (((rect.top >= 0 ? 0 : rect.top) / +-(rect.height / 1)) * 100)) < percentVisible ||
171 Math.floor(100 - ((rect.bottom - windowHeight) / rect.height) * 100) < percentVisible
172 )
173 }
174
175 export {
176 sortBy,
177 durationToString,
178 lineFeedToHtml,
179 getParameterByName,
180 populateAsyncUserVideoChannels,
181 getAbsoluteAPIUrl,
182 dateToHuman,
183 immutableAssign,
184 objectToFormData,
185 getAbsoluteEmbedUrl,
186 objectLineFeedToHtml,
187 removeElementFromArray,
188 scrollToTop,
189 isInViewport,
190 isXPercentInViewport
191 }