@dpgradio/creative 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,169 @@
1
+ import SockJS from 'sockjs-client/dist/sockjs'
2
+
3
+ export default class SocketConnection {
4
+ constructor(host, options) {
5
+ this.host = host
6
+ this.options = options
7
+
8
+ this.lastId = 0
9
+ this.subscriptions = {}
10
+ this.authData = []
11
+ this.messages = []
12
+ this.lastAttempt = 1
13
+ this.reconnecting = false
14
+
15
+ this.connect()
16
+ }
17
+
18
+ connect() {
19
+ this.socket = new SockJS(this.host)
20
+
21
+ this.socket.onopen = () => {
22
+ this.log('Connected')
23
+
24
+ // Reset lastAttempt counter
25
+ this.lastAttempt = 1
26
+
27
+ if (this.reconnecting) {
28
+ this._reauthenticate()
29
+ this._resubscribeSubscriptions()
30
+ }
31
+
32
+ this.reconnecting = false
33
+ this.flushMessages()
34
+ }
35
+
36
+ this.socket.onmessage = (event) => {
37
+ this.log('>>>', event.data)
38
+
39
+ try {
40
+ const message = JSON.parse(event.data)
41
+ this.processMessage(message)
42
+ } catch (e) {
43
+ this.log('Failed to parse server response', event.data)
44
+ return
45
+ }
46
+ }
47
+
48
+ this.socket.onclose = (event) => {
49
+ this.log(`Disconnected ${event.code}`, event)
50
+
51
+ // This is a technical issue, try again
52
+ if ([1000, 1001, 1002, 1003, 1004, 1005, 1006, 2000].includes(event.code)) {
53
+ this.reconnecting = true
54
+ setTimeout(() => {
55
+ this.connect()
56
+ }, this.lastAttempt * 1000)
57
+
58
+ this.lastAttempt *= 2
59
+ if (this.lastAttempt > this.options.maxRetryTimeout) {
60
+ this.lastAttempt = this.options.maxRetryTimeout
61
+ }
62
+ }
63
+ }
64
+ }
65
+
66
+ processMessage(message) {
67
+ if (message.action !== 'data') {
68
+ return
69
+ }
70
+ const payload = JSON.parse(message.data)
71
+
72
+ // Contribute internal ID
73
+ payload._push_id = message.key || null
74
+
75
+ for (const n of message.ids) {
76
+ try {
77
+ const callback = this.subscriptions[n]?.callback
78
+
79
+ callback(payload.data, payload)
80
+ } catch (error) {
81
+ this.log(error)
82
+
83
+ if (!this.options.catchErrors) {
84
+ throw error
85
+ }
86
+ }
87
+ }
88
+ }
89
+
90
+ flushMessages() {
91
+ if (this.isConnected()) {
92
+ for (const msg of this.messages) {
93
+ this.send(...msg)
94
+ }
95
+ this.messages = []
96
+ }
97
+ }
98
+
99
+ isConnected() {
100
+ return this.socket.readyState === 1
101
+ }
102
+
103
+ send(...args) {
104
+ if (this.isConnected()) {
105
+ this.log('<<<', ...args)
106
+ this.socket.send(args)
107
+ } else {
108
+ this.messages.push(args)
109
+ }
110
+ }
111
+
112
+ log(...args) {
113
+ if (this.options.debug) {
114
+ console?.log(...args)
115
+ }
116
+ }
117
+
118
+ _registerSubscription(subscription) {
119
+ const subscriptionId = this.lastId++
120
+
121
+ this.subscriptions[subscriptionId] = subscription
122
+
123
+ this._sendSubscription(subscription, subscriptionId)
124
+
125
+ return subscriptionId
126
+ }
127
+
128
+ _registerAuthentication(authentication) {
129
+ this.authData.push(authentication)
130
+
131
+ this._sendAuthentication(authentication)
132
+ }
133
+
134
+ _unregister(id) {
135
+ delete this.subscriptions[id]
136
+ }
137
+
138
+ _sendSubscription(subscription, id) {
139
+ const msg = {
140
+ action: 'join',
141
+ id,
142
+ sub: subscription.sub,
143
+ }
144
+
145
+ if (subscription.backlog) {
146
+ msg.backlog = subscription.backlog
147
+ }
148
+
149
+ this.send(JSON.stringify(msg))
150
+ }
151
+
152
+ _sendAuthentication(params) {
153
+ const msg = { action: 'authenticate', ...params }
154
+
155
+ this.send(JSON.stringify(msg))
156
+ }
157
+
158
+ _resubscribeSubscriptions() {
159
+ for (const [id, subscription] of Object.entries(this.subscriptions)) {
160
+ this._sendSubscription({ sub: subscription.sub }, id)
161
+ }
162
+ }
163
+
164
+ _reauthenticate() {
165
+ for (const auth of this.authData) {
166
+ this._sendAuthentication(auth)
167
+ }
168
+ }
169
+ }
@@ -0,0 +1,16 @@
1
+ import SocketSubscription from './SocketSubscription'
2
+
3
+ export default class SocketStation {
4
+ constructor(connection, station) {
5
+ this.connection = connection
6
+ this.station = station
7
+ }
8
+
9
+ subscribe(entity) {
10
+ return new SocketSubscription(this.connection, this.station, entity)
11
+ }
12
+
13
+ authenticate(method, authParams) {
14
+ this.connection._registerAuthentication({ station: this.station, method, ...authParams })
15
+ }
16
+ }
@@ -0,0 +1,47 @@
1
+ export default class SocketSubscription {
2
+ constructor(connection, station, entity) {
3
+ this.connection = connection
4
+ this.station = station
5
+ this.entity = entity
6
+
7
+ this.callbacks = {}
8
+ }
9
+
10
+ subscribe(entity) {
11
+ this.connection.subscribe(entity)
12
+ }
13
+
14
+ listen(callback, options = {}) {
15
+ this.on(null, callback, options)
16
+
17
+ return this
18
+ }
19
+
20
+ on(action, callback, options = {}) {
21
+ const id = this.connection._registerSubscription({
22
+ sub: {
23
+ station: this.station,
24
+ entity: this.entity,
25
+ action,
26
+ scope: options.scope,
27
+ },
28
+ callback,
29
+ backlog: options.backlog,
30
+ })
31
+
32
+ this.callbacks[action] = id
33
+
34
+ return this
35
+ }
36
+
37
+ off(action) {
38
+ const id = this.callbacks[action]
39
+ this.connection._unregister(id)
40
+ }
41
+
42
+ unsubscribe() {
43
+ for (const id of Object.values(this.callbacks)) {
44
+ this.connection._unregister(id)
45
+ }
46
+ }
47
+ }
@@ -0,0 +1,36 @@
1
+ import SocketConnection from './SocketConnection'
2
+ import SocketStation from './SocketStation'
3
+
4
+ // This is a JS rewrite of [https://github.com/medialaan/radio-sockets-server/blob/master/dist/q.coffee] with some minor additional functionality.
5
+ class Socket {
6
+ constructor() {
7
+ this.connections = {}
8
+ }
9
+
10
+ connect(station, host = 'https://socket.qmusic.be/api', options = {}) {
11
+ const connectionOptions = {
12
+ debug: false,
13
+ catchErrors: false,
14
+ maxRetryTimeout: 10,
15
+ ...options,
16
+ }
17
+
18
+ if (!this.connections[host]) {
19
+ this.connections[host] = new SocketConnection(host, connectionOptions)
20
+ }
21
+
22
+ return new SocketStation(this.connections[host], station)
23
+ }
24
+
25
+ /**
26
+ * Shortcut for subscribing to an entity action.
27
+ *
28
+ * Instead of `socket.connect('station').subscribe('entity').on('action', () => { ... })`
29
+ * you can use `socket.join({ station: 'station', entity: 'entity', action: 'action' }, () => { ... })`.
30
+ */
31
+ join({ station, entity, action, options = {} }, callback) {
32
+ return this.connect(station).subscribe(entity).on(action, callback, options)
33
+ }
34
+ }
35
+
36
+ export default new Socket()
@@ -0,0 +1,12 @@
1
+ const baseUrl = 'https://cdn-radio.dpgmedia.net'
2
+
3
+ export const cdnImageUrl = (endpoint, size = 'w480') => {
4
+ if (!endpoint) {
5
+ return null
6
+ }
7
+ return `${baseUrl}/site/${size}/${endpoint}`
8
+ }
9
+
10
+ export const cdnUrl = (endpoint) => {
11
+ return `${baseUrl}/${endpoint}`
12
+ }
@@ -0,0 +1,28 @@
1
+ // From: https://github.com/medialaan/radio-radioplayer-frontend/blob/develop/src/general/utils/loadScript.js
2
+ // TODO: Refactor
3
+
4
+ export default function loadScript(url, { timeout = undefined } = {}) {
5
+ return new Promise((resolve, reject) => {
6
+ let script = document.createElement('script')
7
+ const firstScript = document.getElementsByTagName('script')[0]
8
+ script.async = true
9
+ script.defer = true
10
+
11
+ const loadScriptTimeout = timeout ? setTimeout(() => reject(`Loading script [${url}] blocked.`), timeout) : null
12
+
13
+ const readyHandler = (_, isAbort) => {
14
+ if (isAbort) {
15
+ reject()
16
+ } else {
17
+ setTimeout(() => {
18
+ clearTimeout(loadScriptTimeout)
19
+ resolve()
20
+ }, 0)
21
+ }
22
+ }
23
+
24
+ script.onload = script.onreadystatechange = readyHandler
25
+ script.src = url
26
+ firstScript.parentNode.insertBefore(script, firstScript)
27
+ })
28
+ }
@@ -0,0 +1,14 @@
1
+ import hybrid from '../app/hybrid'
2
+
3
+ export default function openLink(url) {
4
+ const chromeAgent = navigator.userAgent.indexOf('Chrome') > -1
5
+ const safariAgent = chromeAgent ? false : navigator.userAgent.indexOf('Safari') > -1
6
+
7
+ if (hybrid.isNativeApp()) {
8
+ hybrid.call('navigateTo', { url, inApp: false })
9
+ } else if (!safariAgent) {
10
+ window.open(url)
11
+ } else {
12
+ window.location = url
13
+ }
14
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @template T
3
+ * @param {T} value
4
+ * @param {function(T): void} callback
5
+ * @returns {T}
6
+ */
7
+ export default function tap(value, callback) {
8
+ callback(value)
9
+ return value
10
+ }
@@ -0,0 +1,19 @@
1
+ :root {
2
+ --joe-lime: 206 220 0;
3
+
4
+ --joe-purple: 150 4 99;
5
+ --joe-purple-dark: 92 29 84;
6
+ --joe-purple-light: 220 50 130;
7
+
8
+ --joe-green: 3 112 108;
9
+ --joe-green-dark: 9 76 89;
10
+ --joe-green-light: 20 160 140;
11
+
12
+ --joe-red: 186 22 52;
13
+ --joe-red-dark: 154 23 54;
14
+ --joe-red-light: 240 40 70;
15
+
16
+ --joe-blue: 7 77 163;
17
+ --joe-blue-dark: 44 45 119;
18
+ --joe-blue-light: 0 130 220;
19
+ }
@@ -0,0 +1,17 @@
1
+ :root {
2
+ --q-red: 237 54 36;
3
+ --q-grey: 61 61 61;
4
+ --q-teal: 0 191 179;
5
+ --q-yellow: 249 212 35;
6
+ --q-purple: 210 110 230;
7
+ --q-green: 151 215 0;
8
+ --q-blue: 2 134 255;
9
+
10
+ --q-red-dark: 205 34 17;
11
+ --q-blue-dark: 9 0 134;
12
+
13
+ --q-blue-light: 91 194 231;
14
+ --q-teal-light: 184 229 209;
15
+ --q-grey-light: 249 249 250;
16
+ --q-purple-light: 244 224 249;
17
+ }
@@ -0,0 +1,34 @@
1
+ @font-face {
2
+ font-family: geomanist;
3
+ src: url(https://static1.qmusic.medialaancdn.be/store/static/fonts/geomanist-light-webfont.eot), url(https://static1.qmusic.medialaancdn.be/store/static/fonts/geomanist-light-webfont.woff), url(https://static1.qmusic.medialaancdn.be/store/static/fonts/geomanist-light-webfont.woff2);
4
+ font-weight: 200;
5
+ font-style: normal
6
+ }
7
+
8
+ @font-face {
9
+ font-family: geomanist;
10
+ src: url(https://static1.qmusic.medialaancdn.be/store/static/fonts/geomanist-book-webfont.eot), url(https://static1.qmusic.medialaancdn.be/store/static/fonts/geomanist-book-webfont.woff), url(https://static1.qmusic.medialaancdn.be/store/static/fonts/geomanist-book-webfont.woff2);
11
+ font-weight: 300;
12
+ font-style: normal
13
+ }
14
+
15
+ @font-face {
16
+ font-family: geomanist;
17
+ src: url(https://static1.qmusic.medialaancdn.be/store/static/fonts/geomanist-regular-webfont.eot), url(https://static1.qmusic.medialaancdn.be/store/static/fonts/geomanist-regular-webfont.woff), url(https://static1.qmusic.medialaancdn.be/store/static/fonts/geomanist-regular-webfont.woff2);
18
+ font-weight: 400;
19
+ font-style: normal
20
+ }
21
+
22
+ @font-face {
23
+ font-family: geomanist;
24
+ src: url(https://static1.qmusic.medialaancdn.be/store/static/fonts/geomanist-medium-webfont.eot), url(https://static1.qmusic.medialaancdn.be/store/static/fonts/geomanist-medium-webfont.woff), url(https://static1.qmusic.medialaancdn.be/store/static/fonts/geomanist-medium-webfont.woff2);
25
+ font-weight: 500;
26
+ font-style: normal
27
+ }
28
+
29
+ @font-face {
30
+ font-family: geomanist;
31
+ src: url(https://static1.qmusic.medialaancdn.be/store/static/fonts/geomanist-bold-webfont.eot), url(https://static1.qmusic.medialaancdn.be/store/static/fonts/geomanist-bold-webfont.woff), url(https://static1.qmusic.medialaancdn.be/store/static/fonts/geomanist-bold-webfont.woff2);
32
+ font-weight: 600;
33
+ font-style: normal
34
+ }
@@ -0,0 +1,48 @@
1
+ @font-face {
2
+ font-family: Cervo;
3
+ src: url(https://fonts.qmusic.be/cervo-light-webfont.ttf), url(https://fonts.qmusic.be/cervo-light-webfont.eot), url(https://fonts.qmusic.be/cervo-light-webfont.woff), url(https://fonts.qmusic.be/cervo-light-webfont.woff2), url(https://fonts.qmusic.be/cervo-light-webfont.svg);
4
+ font-weight: 400;
5
+ font-style: normal
6
+ }
7
+
8
+ @font-face {
9
+ font-family: Cervo;
10
+ src: url(https://fonts.qmusic.be/cervo-medium-webfont.ttf), url(https://fonts.qmusic.be/cervo-medium-webfont.eot), url(https://fonts.qmusic.be/cervo-medium-webfont.woff), url(https://fonts.qmusic.be/cervo-medium-webfont.woff2), url(https://fonts.qmusic.be/cervo-medium-webfont.svg);
11
+ font-weight: 600;
12
+ font-style: normal
13
+ }
14
+
15
+ @font-face {
16
+ font-family: Qarla;
17
+ src: url(https://fonts.qmusic.be/qarla-bold-webfont.ttf), url(https://fonts.qmusic.be/qarla-bold-webfont.eot), url(https://fonts.qmusic.be/qarla-bold-webfont.woff), url(https://fonts.qmusic.be/qarla-bold-webfont.woff2), url(https://fonts.qmusic.be/qarla-bold-webfont.svg);
18
+ font-weight: 700;
19
+ font-style: normal
20
+ }
21
+
22
+ @font-face {
23
+ font-family: Qarla;
24
+ src: url(https://fonts.qmusic.be/qarla-bolditalic-webfont.ttf), url(https://fonts.qmusic.be/qarla-bolditalic-webfont.eot), url(https://fonts.qmusic.be/qarla-bolditalic-webfont.woff), url(https://fonts.qmusic.be/qarla-bolditalic-webfont.woff2), url(https://fonts.qmusic.be/qarla-bolditalic-webfont.svg);
25
+ font-weight: 700;
26
+ font-style: italic
27
+ }
28
+
29
+ @font-face {
30
+ font-family: Qarla;
31
+ src: url(https://fonts.qmusic.be/qarla-italic-webfont.ttf), url(https://fonts.qmusic.be/qarla-italic-webfont.eot), url(https://fonts.qmusic.be/qarla-italic-webfont.woff), url(https://fonts.qmusic.be/qarla-italic-webfont.woff2), url(https://fonts.qmusic.be/qarla-italic-webfont.svg);
32
+ font-weight: 400;
33
+ font-style: italic
34
+ }
35
+
36
+ @font-face {
37
+ font-family: Qarla;
38
+ src: url(https://fonts.qmusic.be/qarla-regular-webfont.ttf), url(https://fonts.qmusic.be/qarla-regular-webfont.eot), url(https://fonts.qmusic.be/qarla-regular-webfont.woff), url(https://fonts.qmusic.be/qarla-regular-webfont.woff2), url(https://fonts.qmusic.be/qarla-regular-webfont.svg);
39
+ font-weight: 400;
40
+ font-style: normal
41
+ }
42
+
43
+ @font-face {
44
+ font-family: QMarkMyWords;
45
+ src: url(https://fonts.qmusic.be/qmarkmywords-webfont.ttf), url(https://fonts.qmusic.be/qmarkmywords-webfont.eot), url(https://fonts.qmusic.be/qmarkmywords-webfont.woff), url(https://fonts.qmusic.be/qmarkmywords-webfont.woff2), url(https://fonts.qmusic.be/qmarkmywords-webfont.svg);
46
+ font-weight: 400;
47
+ font-style: normal
48
+ }
@@ -0,0 +1,2 @@
1
+ @import url("https://fonts.googleapis.com/css2?family=Anton&family=Mulish:ital,wght@0,400;0,700;1,400;1,700&display=swap");
2
+ @import url("https://use.typekit.net/ijq2qjl.css");