@5stones/react-native-audio-browser 0.1.4 → 0.1.6
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.
- package/android/src/main/java/com/audiobrowser/player/MediaFactory.kt +11 -71
- package/android/src/main/java/com/audiobrowser/player/TransformingDataSource.kt +125 -0
- package/ios/Browser/BrowserManager.swift +17 -2
- package/ios/TrackPlayer.swift +145 -31
- package/lib/commonjs/features/browser.js.map +1 -1
- package/lib/commonjs/features/equalizer.js.map +1 -1
- package/lib/commonjs/features/errors.js.map +1 -1
- package/lib/commonjs/features/favorites.js.map +1 -1
- package/lib/commonjs/features/metadata.js.map +1 -1
- package/lib/commonjs/features/nowPlaying.js.map +1 -1
- package/lib/commonjs/features/output.js.map +1 -1
- package/lib/commonjs/features/playback/state.js.map +1 -1
- package/lib/commonjs/features/player/options.js.map +1 -1
- package/lib/commonjs/features/queue/activeTrack.js.map +1 -1
- package/lib/commonjs/features/queue/queue.js +1 -1
- package/lib/commonjs/features/queue/queue.js.map +1 -1
- package/lib/commonjs/features/remoteControls.js.map +1 -1
- package/lib/commonjs/utils/useDebug.js.map +1 -1
- package/lib/commonjs/utils/validation.js +23 -0
- package/lib/commonjs/utils/validation.js.map +1 -0
- package/lib/commonjs/web/NativeAudioBrowser.js +53 -15
- package/lib/commonjs/web/NativeAudioBrowser.js.map +1 -1
- package/lib/commonjs/web/SimpleRouter.js +5 -4
- package/lib/commonjs/web/SimpleRouter.js.map +1 -1
- package/lib/commonjs/web/TrackPlayer/Player.js +49 -24
- package/lib/commonjs/web/TrackPlayer/Player.js.map +1 -1
- package/lib/commonjs/web/TrackPlayer/PlaylistPlayer.js +54 -45
- package/lib/commonjs/web/TrackPlayer/PlaylistPlayer.js.map +1 -1
- package/lib/commonjs/web/TrackPlayer/State.js.map +1 -1
- package/lib/commonjs/web/browser/BrowserManager.js +10 -17
- package/lib/commonjs/web/browser/BrowserManager.js.map +1 -1
- package/lib/commonjs/web/browser/FavoriteManager.js.map +1 -1
- package/lib/commonjs/web/browser/NavigationErrorManager.js.map +1 -1
- package/lib/commonjs/web/browser/SearchManager.js.map +1 -1
- package/lib/commonjs/web/http/HttpClient.js +15 -2
- package/lib/commonjs/web/http/HttpClient.js.map +1 -1
- package/lib/commonjs/web/http/RequestConfigBuilder.js.map +1 -1
- package/lib/commonjs/web/player/NowPlayingManager.js +9 -0
- package/lib/commonjs/web/player/NowPlayingManager.js.map +1 -1
- package/lib/commonjs/web/player/OptionsManager.js +1 -1
- package/lib/commonjs/web/player/OptionsManager.js.map +1 -1
- package/lib/commonjs/web/util/BrowserPathHelper.js.map +1 -1
- package/lib/module/features/browser.js.map +1 -1
- package/lib/module/features/equalizer.js.map +1 -1
- package/lib/module/features/errors.js.map +1 -1
- package/lib/module/features/favorites.js.map +1 -1
- package/lib/module/features/metadata.js.map +1 -1
- package/lib/module/features/nowPlaying.js +1 -0
- package/lib/module/features/nowPlaying.js.map +1 -1
- package/lib/module/features/output.js.map +1 -1
- package/lib/module/features/playback/state.js.map +1 -1
- package/lib/module/features/player/options.js.map +1 -1
- package/lib/module/features/queue/activeTrack.js.map +1 -1
- package/lib/module/features/queue/queue.js +1 -1
- package/lib/module/features/queue/queue.js.map +1 -1
- package/lib/module/features/remoteControls.js.map +1 -1
- package/lib/module/utils/useDebug.js.map +1 -1
- package/lib/module/utils/validation.js +18 -0
- package/lib/module/utils/validation.js.map +1 -0
- package/lib/module/web/NativeAudioBrowser.js +53 -15
- package/lib/module/web/NativeAudioBrowser.js.map +1 -1
- package/lib/module/web/SimpleRouter.js +5 -4
- package/lib/module/web/SimpleRouter.js.map +1 -1
- package/lib/module/web/TrackPlayer/Player.js +49 -24
- package/lib/module/web/TrackPlayer/Player.js.map +1 -1
- package/lib/module/web/TrackPlayer/PlaylistPlayer.js +54 -45
- package/lib/module/web/TrackPlayer/PlaylistPlayer.js.map +1 -1
- package/lib/module/web/TrackPlayer/State.js.map +1 -1
- package/lib/module/web/browser/BrowserManager.js +10 -17
- package/lib/module/web/browser/BrowserManager.js.map +1 -1
- package/lib/module/web/browser/FavoriteManager.js.map +1 -1
- package/lib/module/web/browser/NavigationErrorManager.js.map +1 -1
- package/lib/module/web/browser/SearchManager.js.map +1 -1
- package/lib/module/web/http/HttpClient.js +15 -2
- package/lib/module/web/http/HttpClient.js.map +1 -1
- package/lib/module/web/http/RequestConfigBuilder.js.map +1 -1
- package/lib/module/web/player/NowPlayingManager.js +9 -0
- package/lib/module/web/player/NowPlayingManager.js.map +1 -1
- package/lib/module/web/player/OptionsManager.js +1 -1
- package/lib/module/web/player/OptionsManager.js.map +1 -1
- package/lib/module/web/util/BrowserPathHelper.js.map +1 -1
- package/lib/typescript/src/features/browser.d.ts.map +1 -1
- package/lib/typescript/src/features/equalizer.d.ts.map +1 -1
- package/lib/typescript/src/features/errors.d.ts.map +1 -1
- package/lib/typescript/src/features/favorites.d.ts.map +1 -1
- package/lib/typescript/src/features/metadata.d.ts +1 -1
- package/lib/typescript/src/features/metadata.d.ts.map +1 -1
- package/lib/typescript/src/features/nowPlaying.d.ts +1 -1
- package/lib/typescript/src/features/nowPlaying.d.ts.map +1 -1
- package/lib/typescript/src/features/output.d.ts.map +1 -1
- package/lib/typescript/src/features/playback/state.d.ts +1 -1
- package/lib/typescript/src/features/playback/state.d.ts.map +1 -1
- package/lib/typescript/src/features/player/options.d.ts +1 -1
- package/lib/typescript/src/features/player/options.d.ts.map +1 -1
- package/lib/typescript/src/features/queue/activeTrack.d.ts.map +1 -1
- package/lib/typescript/src/features/queue/queue.d.ts.map +1 -1
- package/lib/typescript/src/features/remoteControls.d.ts.map +1 -1
- package/lib/typescript/src/specs/audio-browser.nitro.d.ts.map +1 -1
- package/lib/typescript/src/utils/useDebug.d.ts +1 -1
- package/lib/typescript/src/utils/useDebug.d.ts.map +1 -1
- package/lib/typescript/src/utils/validation.d.ts +3 -0
- package/lib/typescript/src/utils/validation.d.ts.map +1 -0
- package/lib/typescript/src/web/NativeAudioBrowser.d.ts +6 -1
- package/lib/typescript/src/web/NativeAudioBrowser.d.ts.map +1 -1
- package/lib/typescript/src/web/SimpleRouter.d.ts.map +1 -1
- package/lib/typescript/src/web/TrackPlayer/Player.d.ts +7 -19
- package/lib/typescript/src/web/TrackPlayer/Player.d.ts.map +1 -1
- package/lib/typescript/src/web/TrackPlayer/PlaylistPlayer.d.ts +3 -3
- package/lib/typescript/src/web/TrackPlayer/PlaylistPlayer.d.ts.map +1 -1
- package/lib/typescript/src/web/browser/BrowserManager.d.ts.map +1 -1
- package/lib/typescript/src/web/browser/FavoriteManager.d.ts.map +1 -1
- package/lib/typescript/src/web/browser/NavigationErrorManager.d.ts.map +1 -1
- package/lib/typescript/src/web/browser/SearchManager.d.ts +1 -1
- package/lib/typescript/src/web/browser/SearchManager.d.ts.map +1 -1
- package/lib/typescript/src/web/http/HttpClient.d.ts.map +1 -1
- package/lib/typescript/src/web/http/RequestConfigBuilder.d.ts.map +1 -1
- package/lib/typescript/src/web/player/NowPlayingManager.d.ts.map +1 -1
- package/lib/typescript/src/web/player/OptionsManager.d.ts.map +1 -1
- package/lib/typescript/src/web/util/BrowserPathHelper.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/features/browser.ts +1 -1
- package/src/features/equalizer.ts +1 -1
- package/src/features/errors.ts +1 -1
- package/src/features/favorites.ts +1 -1
- package/src/features/metadata.ts +1 -1
- package/src/features/nowPlaying.ts +1 -1
- package/src/features/output.ts +1 -1
- package/src/features/playback/state.ts +1 -1
- package/src/features/player/options.ts +2 -2
- package/src/features/queue/activeTrack.ts +1 -1
- package/src/features/queue/queue.ts +2 -2
- package/src/features/remoteControls.ts +2 -2
- package/src/specs/audio-browser.nitro.ts +0 -1
- package/src/utils/useDebug.ts +6 -6
- package/src/utils/validation.ts +27 -0
- package/src/web/NativeAudioBrowser.ts +137 -58
- package/src/web/SimpleRouter.ts +24 -9
- package/src/web/TrackPlayer/Player.ts +58 -30
- package/src/web/TrackPlayer/PlaylistPlayer.ts +72 -63
- package/src/web/TrackPlayer/RepeatMode.ts +1 -1
- package/src/web/TrackPlayer/State.ts +9 -9
- package/src/web/browser/BrowserManager.ts +124 -67
- package/src/web/browser/FavoriteManager.ts +5 -3
- package/src/web/browser/NavigationErrorManager.ts +15 -8
- package/src/web/browser/SearchManager.ts +17 -11
- package/src/web/http/HttpClient.ts +25 -7
- package/src/web/http/RequestConfigBuilder.ts +29 -13
- package/src/web/player/NowPlayingManager.ts +13 -7
- package/src/web/player/OptionsManager.ts +7 -6
- package/src/web/util/BrowserPathHelper.ts +3 -2
|
@@ -53,7 +53,7 @@ export class FavoriteManager {
|
|
|
53
53
|
|
|
54
54
|
return {
|
|
55
55
|
...track,
|
|
56
|
-
favorited: true
|
|
56
|
+
favorited: true
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
@@ -68,10 +68,12 @@ export class FavoriteManager {
|
|
|
68
68
|
const children = resolvedTrack.children
|
|
69
69
|
if (!children) return resolvedTrack
|
|
70
70
|
|
|
71
|
-
const hydratedChildren = children.map(track =>
|
|
71
|
+
const hydratedChildren = children.map((track) =>
|
|
72
|
+
this.hydrateFavorite(track)
|
|
73
|
+
)
|
|
72
74
|
return {
|
|
73
75
|
...resolvedTrack,
|
|
74
|
-
children: hydratedChildren
|
|
76
|
+
children: hydratedChildren
|
|
75
77
|
}
|
|
76
78
|
}
|
|
77
79
|
}
|
|
@@ -2,7 +2,7 @@ import type {
|
|
|
2
2
|
NavigationError,
|
|
3
3
|
NavigationErrorType,
|
|
4
4
|
FormattedNavigationError,
|
|
5
|
-
NavigationErrorEvent
|
|
5
|
+
NavigationErrorEvent
|
|
6
6
|
} from '../../features'
|
|
7
7
|
import type { NativeBrowserConfiguration } from '../../types/browser-native'
|
|
8
8
|
|
|
@@ -11,7 +11,7 @@ const ERROR_TITLES: Record<NavigationErrorType, string> = {
|
|
|
11
11
|
'http-error': 'Server Error',
|
|
12
12
|
'content-not-found': 'Content Not Found',
|
|
13
13
|
'callback-error': 'Error',
|
|
14
|
-
'unknown-error': 'Error'
|
|
14
|
+
'unknown-error': 'Error'
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
/**
|
|
@@ -25,12 +25,16 @@ export class NavigationErrorManager {
|
|
|
25
25
|
|
|
26
26
|
// Event callbacks
|
|
27
27
|
onNavigationError: (data: NavigationErrorEvent) => void = () => {}
|
|
28
|
-
onFormattedNavigationError: (
|
|
28
|
+
onFormattedNavigationError: (
|
|
29
|
+
formattedError: FormattedNavigationError | undefined
|
|
30
|
+
) => void = () => {}
|
|
29
31
|
|
|
30
32
|
/**
|
|
31
33
|
* Sets the custom error formatter callback from configuration.
|
|
32
34
|
*/
|
|
33
|
-
setFormatCallback(
|
|
35
|
+
setFormatCallback(
|
|
36
|
+
callback: NativeBrowserConfiguration['formatNavigationError']
|
|
37
|
+
): void {
|
|
34
38
|
this.formatCallback = callback
|
|
35
39
|
}
|
|
36
40
|
|
|
@@ -38,7 +42,10 @@ export class NavigationErrorManager {
|
|
|
38
42
|
* Clears the current navigation error and emits clear events.
|
|
39
43
|
*/
|
|
40
44
|
clearNavigationError(): void {
|
|
41
|
-
if (
|
|
45
|
+
if (
|
|
46
|
+
this._navigationError !== undefined ||
|
|
47
|
+
this._formattedNavigationError !== undefined
|
|
48
|
+
) {
|
|
42
49
|
this._navigationError = undefined
|
|
43
50
|
this._formattedNavigationError = undefined
|
|
44
51
|
this.onNavigationError({ error: undefined })
|
|
@@ -65,7 +72,7 @@ export class NavigationErrorManager {
|
|
|
65
72
|
code,
|
|
66
73
|
message,
|
|
67
74
|
statusCode,
|
|
68
|
-
statusCodeSuccess: undefined
|
|
75
|
+
statusCodeSuccess: undefined
|
|
69
76
|
}
|
|
70
77
|
this._navigationError = navError
|
|
71
78
|
this.onNavigationError({ error: navError })
|
|
@@ -73,7 +80,7 @@ export class NavigationErrorManager {
|
|
|
73
80
|
// Default formatted error
|
|
74
81
|
const defaultFormatted: FormattedNavigationError = {
|
|
75
82
|
title: ERROR_TITLES[code],
|
|
76
|
-
message
|
|
83
|
+
message
|
|
77
84
|
}
|
|
78
85
|
|
|
79
86
|
// Call custom formatter if available
|
|
@@ -82,7 +89,7 @@ export class NavigationErrorManager {
|
|
|
82
89
|
const customFormatted = this.formatCallback({
|
|
83
90
|
error: navError,
|
|
84
91
|
defaultFormatted,
|
|
85
|
-
path
|
|
92
|
+
path
|
|
86
93
|
})
|
|
87
94
|
this._formattedNavigationError = customFormatted || defaultFormatted
|
|
88
95
|
} catch (error) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Track, SearchParams } from '../../types'
|
|
2
|
-
import type { BrowserManager } from './BrowserManager'
|
|
3
2
|
import type { HttpClient } from '../http/HttpClient'
|
|
3
|
+
import type { BrowserManager } from './BrowserManager'
|
|
4
4
|
import { RequestConfigBuilder } from '../http/RequestConfigBuilder'
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -23,7 +23,9 @@ export class SearchManager {
|
|
|
23
23
|
*/
|
|
24
24
|
async search(params: SearchParams): Promise<Track[]> {
|
|
25
25
|
// Find __search__ route entry
|
|
26
|
-
const searchRoute = this.browserManager.configuration.routes?.find(
|
|
26
|
+
const searchRoute = this.browserManager.configuration.routes?.find(
|
|
27
|
+
(r) => r.path === '__search__'
|
|
28
|
+
)
|
|
27
29
|
if (!searchRoute) {
|
|
28
30
|
return []
|
|
29
31
|
}
|
|
@@ -38,7 +40,7 @@ export class SearchManager {
|
|
|
38
40
|
else if (searchRoute.searchConfig) {
|
|
39
41
|
// Build query parameters from SearchParams (matches Android's executeSearchApiRequest)
|
|
40
42
|
const searchQueryParams: Record<string, string> = {
|
|
41
|
-
q: params.query
|
|
43
|
+
q: params.query
|
|
42
44
|
}
|
|
43
45
|
if (params.mode) searchQueryParams.mode = params.mode
|
|
44
46
|
if (params.genre) searchQueryParams.genre = params.genre
|
|
@@ -47,9 +49,12 @@ export class SearchManager {
|
|
|
47
49
|
if (params.title) searchQueryParams.title = params.title
|
|
48
50
|
if (params.playlist) searchQueryParams.playlist = params.playlist
|
|
49
51
|
|
|
50
|
-
const requestConfig = this.httpClient.mergeRequestConfig(
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
const requestConfig = this.httpClient.mergeRequestConfig(
|
|
53
|
+
searchRoute.searchConfig,
|
|
54
|
+
{
|
|
55
|
+
query: searchQueryParams
|
|
56
|
+
}
|
|
57
|
+
)
|
|
53
58
|
|
|
54
59
|
try {
|
|
55
60
|
const response = await this.httpClient.executeRequest(requestConfig)
|
|
@@ -64,11 +69,12 @@ export class SearchManager {
|
|
|
64
69
|
const artworkConfig = this.browserManager.configuration.artwork
|
|
65
70
|
if (artworkConfig) {
|
|
66
71
|
results = await Promise.all(
|
|
67
|
-
results.map(async track => {
|
|
68
|
-
const artworkSource =
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
+
results.map(async (track) => {
|
|
73
|
+
const artworkSource =
|
|
74
|
+
await RequestConfigBuilder.resolveArtworkSourceAsync(
|
|
75
|
+
track,
|
|
76
|
+
artworkConfig
|
|
77
|
+
)
|
|
72
78
|
if (artworkSource && !track.artworkSource) {
|
|
73
79
|
return { ...track, artworkSource }
|
|
74
80
|
}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
RequestConfig,
|
|
3
|
-
TransformableRequestConfig,
|
|
4
|
-
} from '../../types'
|
|
5
1
|
import type { NavigationErrorType } from '../../features'
|
|
2
|
+
import type { RequestConfig, TransformableRequestConfig } from '../../types'
|
|
6
3
|
import { RequestConfigBuilder } from './RequestConfigBuilder'
|
|
7
4
|
|
|
8
5
|
type HttpError = Error & {
|
|
@@ -21,6 +18,8 @@ function isHttpError(error: unknown): error is HttpError {
|
|
|
21
18
|
)
|
|
22
19
|
}
|
|
23
20
|
|
|
21
|
+
const TIMEOUT_MS = 30_000
|
|
22
|
+
|
|
24
23
|
/**
|
|
25
24
|
* HTTP client for making browser API requests.
|
|
26
25
|
* Mirrors Android's HttpClient.kt
|
|
@@ -54,7 +53,10 @@ export class HttpClient {
|
|
|
54
53
|
base as RequestConfig
|
|
55
54
|
)
|
|
56
55
|
// Then merge with overrides
|
|
57
|
-
return RequestConfigBuilder.mergeConfig(
|
|
56
|
+
return RequestConfigBuilder.mergeConfig(
|
|
57
|
+
withBase,
|
|
58
|
+
overrides as RequestConfig
|
|
59
|
+
)
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
/**
|
|
@@ -67,22 +69,36 @@ export class HttpClient {
|
|
|
67
69
|
const headers = config.headers ?? {}
|
|
68
70
|
const method = config.method ?? 'GET'
|
|
69
71
|
|
|
72
|
+
const controller = new AbortController()
|
|
73
|
+
const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS)
|
|
74
|
+
|
|
70
75
|
try {
|
|
71
76
|
const response = await fetch(url, {
|
|
72
77
|
method,
|
|
73
78
|
headers,
|
|
79
|
+
signal: controller.signal
|
|
74
80
|
})
|
|
75
81
|
|
|
76
82
|
if (!response.ok) {
|
|
77
|
-
const error = new Error(
|
|
83
|
+
const error = new Error(
|
|
84
|
+
`HTTP ${response.status}: ${response.statusText}`
|
|
85
|
+
) as HttpError
|
|
78
86
|
error.isHttpError = true
|
|
79
87
|
error.status = response.status
|
|
80
88
|
error.statusText = response.statusText
|
|
81
89
|
throw error
|
|
82
90
|
}
|
|
83
91
|
|
|
84
|
-
|
|
92
|
+
// await so JSON parse errors are caught by the surrounding try/catch
|
|
93
|
+
return await response.json()
|
|
85
94
|
} catch (error: unknown) {
|
|
95
|
+
if (error instanceof DOMException && error.name === 'AbortError') {
|
|
96
|
+
const navError = new Error(
|
|
97
|
+
`Request timed out after ${TIMEOUT_MS}ms`
|
|
98
|
+
) as Error & { code: NavigationErrorType }
|
|
99
|
+
navError.code = 'network-error'
|
|
100
|
+
throw navError
|
|
101
|
+
}
|
|
86
102
|
// Distinguish between network errors and HTTP errors
|
|
87
103
|
if (isHttpError(error)) {
|
|
88
104
|
const navError = new Error(error.message) as Error & {
|
|
@@ -102,6 +118,8 @@ export class HttpClient {
|
|
|
102
118
|
}
|
|
103
119
|
navError.code = 'network-error'
|
|
104
120
|
throw navError
|
|
121
|
+
} finally {
|
|
122
|
+
clearTimeout(timeoutId)
|
|
105
123
|
}
|
|
106
124
|
}
|
|
107
125
|
}
|
|
@@ -6,7 +6,7 @@ import type {
|
|
|
6
6
|
ImageSource,
|
|
7
7
|
Track,
|
|
8
8
|
ImageContext,
|
|
9
|
-
ImageQueryParams
|
|
9
|
+
ImageQueryParams
|
|
10
10
|
} from '../../types'
|
|
11
11
|
import { BrowserPathHelper } from '../util/BrowserPathHelper'
|
|
12
12
|
|
|
@@ -88,7 +88,7 @@ export const RequestConfigBuilder = {
|
|
|
88
88
|
query: this.mergeQuery(base.query, override.query),
|
|
89
89
|
body: override.body ?? base.body,
|
|
90
90
|
contentType: override.contentType ?? base.contentType,
|
|
91
|
-
userAgent: override.userAgent ?? base.userAgent
|
|
91
|
+
userAgent: override.userAgent ?? base.userAgent
|
|
92
92
|
}
|
|
93
93
|
},
|
|
94
94
|
|
|
@@ -111,7 +111,10 @@ export const RequestConfigBuilder = {
|
|
|
111
111
|
const transformed = await override.transform(base)
|
|
112
112
|
return transformed
|
|
113
113
|
} catch (e) {
|
|
114
|
-
console.error(
|
|
114
|
+
console.error(
|
|
115
|
+
'Failed to apply media transform function, using base config',
|
|
116
|
+
e
|
|
117
|
+
)
|
|
115
118
|
return base
|
|
116
119
|
}
|
|
117
120
|
}
|
|
@@ -135,7 +138,12 @@ export const RequestConfigBuilder = {
|
|
|
135
138
|
/**
|
|
136
139
|
* Converts a TransformableRequestConfig to a plain RequestConfig.
|
|
137
140
|
*/
|
|
138
|
-
toRequestConfig(
|
|
141
|
+
toRequestConfig(
|
|
142
|
+
config:
|
|
143
|
+
| TransformableRequestConfig
|
|
144
|
+
| MediaRequestConfig
|
|
145
|
+
| ArtworkRequestConfig
|
|
146
|
+
): RequestConfig {
|
|
139
147
|
return {
|
|
140
148
|
path: config.path,
|
|
141
149
|
method: config.method,
|
|
@@ -144,7 +152,7 @@ export const RequestConfigBuilder = {
|
|
|
144
152
|
query: config.query,
|
|
145
153
|
body: config.body,
|
|
146
154
|
contentType: config.contentType,
|
|
147
|
-
userAgent: config.userAgent
|
|
155
|
+
userAgent: config.userAgent
|
|
148
156
|
}
|
|
149
157
|
},
|
|
150
158
|
|
|
@@ -187,12 +195,15 @@ export const RequestConfigBuilder = {
|
|
|
187
195
|
? this.mergeArtworkConfig({ path: artworkUrl }, artworkConfig)
|
|
188
196
|
: { path: artworkUrl }
|
|
189
197
|
|
|
190
|
-
const resolvedUri = BrowserPathHelper.buildUrl(
|
|
198
|
+
const resolvedUri = BrowserPathHelper.buildUrl(
|
|
199
|
+
config.baseUrl,
|
|
200
|
+
config.path ?? artworkUrl
|
|
201
|
+
)
|
|
191
202
|
|
|
192
203
|
return {
|
|
193
204
|
uri: resolvedUri,
|
|
194
205
|
method: config.method ?? 'GET',
|
|
195
|
-
headers: config.headers
|
|
206
|
+
headers: config.headers
|
|
196
207
|
}
|
|
197
208
|
},
|
|
198
209
|
|
|
@@ -258,7 +269,7 @@ export const RequestConfigBuilder = {
|
|
|
258
269
|
if (artworkConfig.transform) {
|
|
259
270
|
mergedConfig = await artworkConfig.transform({
|
|
260
271
|
request: mergedConfig,
|
|
261
|
-
context: imageContext
|
|
272
|
+
context: imageContext
|
|
262
273
|
})
|
|
263
274
|
}
|
|
264
275
|
|
|
@@ -273,7 +284,7 @@ export const RequestConfigBuilder = {
|
|
|
273
284
|
uri: finalUri,
|
|
274
285
|
method: mergedConfig.method ?? 'GET',
|
|
275
286
|
headers: mergedConfig.headers,
|
|
276
|
-
body: mergedConfig.body
|
|
287
|
+
body: mergedConfig.body
|
|
277
288
|
}
|
|
278
289
|
} catch (error) {
|
|
279
290
|
// resolve/transform threw - log error, return undefined to avoid broken images
|
|
@@ -298,12 +309,15 @@ export const RequestConfigBuilder = {
|
|
|
298
309
|
// If artworkSource is already set, don't override it
|
|
299
310
|
if (track.artworkSource) return track
|
|
300
311
|
|
|
301
|
-
const artworkSource = this.resolveArtworkSource(
|
|
312
|
+
const artworkSource = this.resolveArtworkSource(
|
|
313
|
+
track.artwork,
|
|
314
|
+
artworkConfig
|
|
315
|
+
)
|
|
302
316
|
if (!artworkSource) return track
|
|
303
317
|
|
|
304
318
|
return {
|
|
305
319
|
...track,
|
|
306
|
-
artworkSource
|
|
320
|
+
artworkSource
|
|
307
321
|
}
|
|
308
322
|
},
|
|
309
323
|
|
|
@@ -318,7 +332,9 @@ export const RequestConfigBuilder = {
|
|
|
318
332
|
tracks: Track[],
|
|
319
333
|
artworkConfig: ArtworkRequestConfig | undefined
|
|
320
334
|
): Track[] {
|
|
321
|
-
return tracks.map(track =>
|
|
335
|
+
return tracks.map((track) =>
|
|
336
|
+
this.transformTrackArtwork(track, artworkConfig)
|
|
337
|
+
)
|
|
322
338
|
},
|
|
323
339
|
|
|
324
340
|
/**
|
|
@@ -343,5 +359,5 @@ export const RequestConfigBuilder = {
|
|
|
343
359
|
if (!base) return override
|
|
344
360
|
if (!override) return base
|
|
345
361
|
return { ...base, ...override }
|
|
346
|
-
}
|
|
362
|
+
}
|
|
347
363
|
} as const
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
NowPlayingUpdate,
|
|
3
|
-
NowPlayingMetadata,
|
|
4
|
-
} from '../../features'
|
|
1
|
+
import type { NowPlayingUpdate, NowPlayingMetadata } from '../../features'
|
|
5
2
|
import type { Track } from '../../types'
|
|
6
3
|
|
|
7
4
|
/**
|
|
@@ -38,14 +35,20 @@ export class NowPlayingManager {
|
|
|
38
35
|
artist: update.artist ?? currentTrack.artist,
|
|
39
36
|
album: currentTrack.album,
|
|
40
37
|
artwork: currentTrack.artwork,
|
|
41
|
-
|
|
38
|
+
description: currentTrack.description,
|
|
39
|
+
mediaId: currentTrack.src ?? currentTrack.url,
|
|
40
|
+
genre: currentTrack.genre,
|
|
41
|
+
duration
|
|
42
42
|
}
|
|
43
43
|
: {
|
|
44
44
|
title: currentTrack.title,
|
|
45
45
|
artist: currentTrack.artist,
|
|
46
46
|
album: currentTrack.album,
|
|
47
47
|
artwork: currentTrack.artwork,
|
|
48
|
-
|
|
48
|
+
description: currentTrack.description,
|
|
49
|
+
mediaId: currentTrack.src ?? currentTrack.url,
|
|
50
|
+
genre: currentTrack.genre,
|
|
51
|
+
duration
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
this.onNowPlayingChanged(metadata)
|
|
@@ -69,7 +72,10 @@ export class NowPlayingManager {
|
|
|
69
72
|
artist: this.override?.artist ?? currentTrack.artist,
|
|
70
73
|
album: currentTrack.album,
|
|
71
74
|
artwork: currentTrack.artwork,
|
|
72
|
-
|
|
75
|
+
description: currentTrack.description,
|
|
76
|
+
mediaId: currentTrack.src ?? currentTrack.url,
|
|
77
|
+
genre: currentTrack.genre,
|
|
78
|
+
duration
|
|
73
79
|
}
|
|
74
80
|
}
|
|
75
81
|
|
|
@@ -2,7 +2,7 @@ import type {
|
|
|
2
2
|
NativeUpdateOptions,
|
|
3
3
|
UpdateOptions,
|
|
4
4
|
Options,
|
|
5
|
-
RepeatMode as RepeatModeType
|
|
5
|
+
RepeatMode as RepeatModeType
|
|
6
6
|
} from '../../features'
|
|
7
7
|
import { RepeatMode } from '../TrackPlayer'
|
|
8
8
|
|
|
@@ -20,7 +20,7 @@ export class OptionsManager {
|
|
|
20
20
|
backwardJumpInterval: 15,
|
|
21
21
|
progressUpdateEventInterval: null,
|
|
22
22
|
repeatMode: RepeatMode.Off,
|
|
23
|
-
capabilities: {}
|
|
23
|
+
capabilities: {}
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
// Event callback
|
|
@@ -38,7 +38,7 @@ export class OptionsManager {
|
|
|
38
38
|
options.progressUpdateEventInterval !== undefined &&
|
|
39
39
|
typeof options.progressUpdateEventInterval !== 'number'
|
|
40
40
|
) {
|
|
41
|
-
throw new Error('
|
|
41
|
+
throw new Error('NullSentinel type is not valid on web.')
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
// Merge platform-agnostic options
|
|
@@ -52,7 +52,8 @@ export class OptionsManager {
|
|
|
52
52
|
progressUpdateEventInterval:
|
|
53
53
|
options.progressUpdateEventInterval === null
|
|
54
54
|
? null
|
|
55
|
-
: (options.progressUpdateEventInterval ??
|
|
55
|
+
: (options.progressUpdateEventInterval ??
|
|
56
|
+
this.options.progressUpdateEventInterval)
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
// Store merged options
|
|
@@ -65,7 +66,7 @@ export class OptionsManager {
|
|
|
65
66
|
progressUpdateEventInterval:
|
|
66
67
|
mergedOptions.progressUpdateEventInterval ?? 15,
|
|
67
68
|
capabilities: mergedOptions.capabilities ?? {},
|
|
68
|
-
repeatMode: mergedOptions.repeatMode
|
|
69
|
+
repeatMode: mergedOptions.repeatMode
|
|
69
70
|
}
|
|
70
71
|
this.onOptionsChanged(fullOptions)
|
|
71
72
|
}
|
|
@@ -78,7 +79,7 @@ export class OptionsManager {
|
|
|
78
79
|
forwardJumpInterval: this.options.forwardJumpInterval,
|
|
79
80
|
backwardJumpInterval: this.options.backwardJumpInterval,
|
|
80
81
|
progressUpdateEventInterval: this.options.progressUpdateEventInterval,
|
|
81
|
-
capabilities: this.options.capabilities
|
|
82
|
+
capabilities: this.options.capabilities
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
|
|
@@ -103,7 +103,8 @@ export const BrowserPathHelper = {
|
|
|
103
103
|
|
|
104
104
|
try {
|
|
105
105
|
// Parse the URL - handle both full URLs and paths
|
|
106
|
-
const isFullUrl =
|
|
106
|
+
const isFullUrl =
|
|
107
|
+
path.startsWith('http://') || path.startsWith('https://')
|
|
107
108
|
const urlObj = new URL(path, isFullUrl ? undefined : 'http://placeholder')
|
|
108
109
|
return urlObj.searchParams.get(this.CONTEXTUAL_TRACK_PARAM) ?? undefined
|
|
109
110
|
} catch {
|
|
@@ -143,5 +144,5 @@ export const BrowserPathHelper = {
|
|
|
143
144
|
const normalizedBase = baseUrl.replace(/\/+$/, '') + '/'
|
|
144
145
|
const normalizedPath = path.replace(/^\/+/, '')
|
|
145
146
|
return `${normalizedBase}${normalizedPath}`
|
|
146
|
-
}
|
|
147
|
+
}
|
|
147
148
|
} as const
|