Capturing pack and cover
This commit is contained in:
180
page-probe.js
180
page-probe.js
@@ -2,6 +2,7 @@
|
||||
|
||||
(function initPageProbe() {
|
||||
const EVENT_SOURCE = "S3_CAPTURE_PROBE";
|
||||
const GRAPHQL_URL_FRAGMENT = "surfaces-graphql.splice.com/graphql";
|
||||
let lastAudioResponseUrl = "";
|
||||
|
||||
function emit(kind, payload) {
|
||||
@@ -23,6 +24,156 @@
|
||||
return typeof value === "string" ? value : "";
|
||||
}
|
||||
|
||||
function normalizeUrl(rawUrl) {
|
||||
try {
|
||||
return new URL(rawUrl, window.location.href).toString();
|
||||
} catch (error) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeFileName(raw) {
|
||||
if (typeof raw !== "string") {
|
||||
return "";
|
||||
}
|
||||
const trimmed = raw.trim();
|
||||
if (!trimmed) {
|
||||
return "";
|
||||
}
|
||||
const parts = trimmed.split("/");
|
||||
return parts[parts.length - 1] || trimmed;
|
||||
}
|
||||
|
||||
function extractSampleIdFromUrl(url) {
|
||||
try {
|
||||
const parsed = new URL(url);
|
||||
const marker = "/audio_samples/";
|
||||
const idx = parsed.pathname.indexOf(marker);
|
||||
if (idx < 0) {
|
||||
return "";
|
||||
}
|
||||
const rest = parsed.pathname.slice(idx + marker.length);
|
||||
const parts = rest.split("/").filter(Boolean);
|
||||
const first = (parts[0] || "").replace(/-scrambled$/i, "");
|
||||
const second = (parts[1] || "").split(".")[0];
|
||||
const hashRe = /^[a-f0-9]{64}$/i;
|
||||
if (hashRe.test(first)) {
|
||||
return first.toLowerCase();
|
||||
}
|
||||
if (hashRe.test(second)) {
|
||||
return second.toLowerCase();
|
||||
}
|
||||
return "";
|
||||
} catch (error) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
function extractCoverImageFromGraphqlItem(item) {
|
||||
if (!item || typeof item !== "object") {
|
||||
return "";
|
||||
}
|
||||
const ownFiles = Array.isArray(item.files) ? item.files : [];
|
||||
for (const file of ownFiles) {
|
||||
if (!file || typeof file !== "object") {
|
||||
continue;
|
||||
}
|
||||
if (String(file.asset_file_type_slug || "").toLowerCase() !== "cover_image") {
|
||||
continue;
|
||||
}
|
||||
const url = normalizeUrl(file.url || "");
|
||||
if (url) {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
const parents = item.parents && Array.isArray(item.parents.items) ? item.parents.items : [];
|
||||
for (const parent of parents) {
|
||||
const files = parent && Array.isArray(parent.files) ? parent.files : [];
|
||||
for (const file of files) {
|
||||
if (!file || typeof file !== "object") {
|
||||
continue;
|
||||
}
|
||||
if (String(file.asset_file_type_slug || "").toLowerCase() !== "cover_image") {
|
||||
continue;
|
||||
}
|
||||
const url = normalizeUrl(file.url || "");
|
||||
if (url) {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function extractPackNameFromGraphqlItem(item) {
|
||||
if (!item || typeof item !== "object" || !item.parents || !Array.isArray(item.parents.items)) {
|
||||
return "";
|
||||
}
|
||||
for (const parent of item.parents.items) {
|
||||
if (!parent || typeof parent !== "object") {
|
||||
continue;
|
||||
}
|
||||
const name = typeof parent.name === "string" ? parent.name.trim() : "";
|
||||
if (name) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function extractPreviewContextsFromGraphql(json) {
|
||||
const contexts = [];
|
||||
const items = json &&
|
||||
json.data &&
|
||||
json.data.assetsSearch &&
|
||||
Array.isArray(json.data.assetsSearch.items)
|
||||
? json.data.assetsSearch.items
|
||||
: [];
|
||||
for (const item of items) {
|
||||
if (!item || typeof item !== "object") {
|
||||
continue;
|
||||
}
|
||||
const sampleId = typeof item.uuid === "string" ? item.uuid.toLowerCase() : "";
|
||||
const itemName = normalizeFileName(String(item.name || ""));
|
||||
const itemKey = typeof item.key === "string" ? item.key.trim().toUpperCase() : "";
|
||||
const itemBpm = item.bpm == null ? "" : String(item.bpm).trim();
|
||||
const itemTags = Array.isArray(item.tags)
|
||||
? Array.from(new Set(item.tags.map((tag) => (tag && tag.label ? String(tag.label).trim() : "")).filter(Boolean)))
|
||||
: [];
|
||||
const itemCoverImageUrl = extractCoverImageFromGraphqlItem(item);
|
||||
const itemPackName = extractPackNameFromGraphqlItem(item);
|
||||
const files = Array.isArray(item.files) ? item.files : [];
|
||||
for (const file of files) {
|
||||
if (!file || typeof file !== "object") {
|
||||
continue;
|
||||
}
|
||||
const typeSlug = String(file.asset_file_type_slug || "").toLowerCase();
|
||||
const fileUrl = normalizeUrl(file.url || "");
|
||||
if (typeSlug !== "preview_mp3" || !fileUrl) {
|
||||
continue;
|
||||
}
|
||||
contexts.push({
|
||||
sampleId: sampleId || extractSampleIdFromUrl(fileUrl),
|
||||
previewUrl: fileUrl,
|
||||
fileName: itemName,
|
||||
key: itemKey,
|
||||
bpm: itemBpm,
|
||||
tags: itemTags,
|
||||
coverImageUrl: itemCoverImageUrl,
|
||||
packName: itemPackName
|
||||
});
|
||||
}
|
||||
}
|
||||
return contexts;
|
||||
}
|
||||
|
||||
function emitGraphqlContextsFromJson(json) {
|
||||
const contexts = extractPreviewContextsFromGraphql(json);
|
||||
if (contexts.length) {
|
||||
emit("graphql-contexts", { contexts });
|
||||
}
|
||||
}
|
||||
|
||||
function markLastAudioUrl(url, contentType) {
|
||||
const maybeUrl = safeString(url);
|
||||
const maybeType = safeString(contentType).toLowerCase();
|
||||
@@ -64,6 +215,13 @@
|
||||
status: response ? response.status : 0,
|
||||
contentType: contentType || ""
|
||||
});
|
||||
if (requestUrl && requestUrl.includes(GRAPHQL_URL_FRAGMENT) && response && typeof response.clone === "function") {
|
||||
response.clone().json().then((json) => {
|
||||
emitGraphqlContextsFromJson(json);
|
||||
}).catch(() => {
|
||||
// Ignore non-JSON GraphQL edge cases.
|
||||
});
|
||||
}
|
||||
return response;
|
||||
},
|
||||
(error) => {
|
||||
@@ -117,6 +275,28 @@
|
||||
status: xhr.status || 0,
|
||||
contentType
|
||||
});
|
||||
const requestUrl = safeString(xhr.__s3CaptureRequestUrl);
|
||||
if (!requestUrl || !requestUrl.includes(GRAPHQL_URL_FRAGMENT)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
let json = null;
|
||||
if (xhr.responseType === "json" && xhr.response && typeof xhr.response === "object") {
|
||||
json = xhr.response;
|
||||
} else {
|
||||
if (xhr.responseType && xhr.responseType !== "text" && xhr.responseType !== "") {
|
||||
return;
|
||||
}
|
||||
const text = safeString(xhr.responseText);
|
||||
if (!text) {
|
||||
return;
|
||||
}
|
||||
json = JSON.parse(text);
|
||||
}
|
||||
emitGraphqlContextsFromJson(json);
|
||||
} catch (error) {
|
||||
// Ignore non-JSON GraphQL edge cases.
|
||||
}
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user