mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2026-06-10 23:38:34 -04:00
60 lines
1.9 KiB
JavaScript
60 lines
1.9 KiB
JavaScript
import { Capacitor } from '@capacitor/core'
|
|
import { FastAverageColor } from 'fast-average-color'
|
|
import { imageHttpDataToBlob } from '@/utils/imageHttpBlob'
|
|
|
|
/**
|
|
* True when the cover URL is http(s) and not same-origin with the WebView (or browser tab).
|
|
* Same-origin URLs (e.g. Capacitor file bridge on localhost) can use FastAverageColor directly.
|
|
*/
|
|
export function shouldFetchCoverViaNativeHttp(coverUrl) {
|
|
if (!coverUrl || typeof coverUrl !== 'string') return false
|
|
if (!coverUrl.startsWith('http://') && !coverUrl.startsWith('https://')) return false
|
|
try {
|
|
return new URL(coverUrl).origin !== window.location.origin
|
|
} catch {
|
|
return false
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Average color for a cover image. On native, cross-origin http(s) covers are loaded with
|
|
* CapacitorHttp (no WebView CORS), then sampled via a same-origin blob URL.
|
|
* @param {*} vm - component instance with $nativeHttp (this)
|
|
* @param {string} fullCoverUrl
|
|
* @returns {Promise<{ rgba: string, isLight: boolean }|null>}
|
|
*/
|
|
export async function getAverageColorFromCoverUrl(vm, fullCoverUrl) {
|
|
if (!fullCoverUrl) return null
|
|
|
|
const fac = new FastAverageColor()
|
|
let objectUrl = null
|
|
try {
|
|
let resource = fullCoverUrl
|
|
|
|
if (Capacitor.isNativePlatform() && shouldFetchCoverViaNativeHttp(fullCoverUrl)) {
|
|
const raw = await vm.$nativeHttp.get(fullCoverUrl, {
|
|
responseType: 'blob',
|
|
connectTimeout: 15000,
|
|
readTimeout: 30000
|
|
})
|
|
const blob = imageHttpDataToBlob(raw)
|
|
if (!blob) {
|
|
throw new Error('Cover image response could not be converted to a blob')
|
|
}
|
|
objectUrl = URL.createObjectURL(blob)
|
|
resource = objectUrl
|
|
}
|
|
|
|
const color = await fac.getColorAsync(resource)
|
|
return { rgba: color.rgba, isLight: color.isLight }
|
|
} catch (e) {
|
|
console.error('[coverAverageColor]', e)
|
|
return null
|
|
} finally {
|
|
if (objectUrl) {
|
|
URL.revokeObjectURL(objectUrl)
|
|
}
|
|
fac.destroy()
|
|
}
|
|
}
|