mrow
This commit is contained in:
parent
22774e2ab8
commit
825e6ec5c7
|
|
@ -118,6 +118,41 @@ export function emojiUrl(id: string, animated: boolean): string {
|
|||
return `${CDN}/emojis/${id}.${animated ? "gif" : "png"}?size=32`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a Rich Presence activity asset (`activity.assets.large_image` /
|
||||
* `small_image`) to an actual image URL. Discord prefixes these with a
|
||||
* scheme for "external" assets (streaming previews, proxied media); a bare
|
||||
* hash with no prefix is a normal app-asset on the CDN.
|
||||
*/
|
||||
|
||||
// asset URL scheme handling adapted from pxseu/lanyard-ui, MPL-2.0
|
||||
export function activityAssetUrl(raw: string | undefined | null, applicationId?: string | null): string | null {
|
||||
if (!raw) return null;
|
||||
|
||||
const split = raw.split(":");
|
||||
if (split.length < 2) {
|
||||
// Plain hash — standard Rich Presence app-asset, needs the app id.
|
||||
return applicationId ? `${CDN}/app-assets/${applicationId}/${raw}.png` : null;
|
||||
}
|
||||
|
||||
switch (split[0]) {
|
||||
case "mp":
|
||||
// External Discord-proxied asset (e.g. attachment, embed image).
|
||||
return `https://media.discordapp.net/${split.slice(1).join(":")}`;
|
||||
case "twitch":
|
||||
// Twitch stream preview.
|
||||
return `https://static-cdn.jtvnw.net/previews-ttv/live_user_${split[1]}.png`;
|
||||
case "youtube":
|
||||
// YouTube live-stream thumbnail.
|
||||
return `https://i.ytimg.com/vi/${split[1]}/hqdefault_live.jpg`;
|
||||
case "spotify":
|
||||
// Spotify album/cover art.
|
||||
return `https://i.scdn.co/image/${split[1]}`;
|
||||
default:
|
||||
return applicationId ? `${CDN}/app-assets/${applicationId}/${raw}.png` : null;
|
||||
}
|
||||
}
|
||||
|
||||
// ---- collectibles (Shop wishlist) ---------------------------------------
|
||||
// Discord product type ids -> our human-readable kind. See Userdoccers
|
||||
// "Collectible Product Type". 1000/2000/3000 are bundle/variants/external.
|
||||
|
|
@ -156,4 +191,4 @@ export function nameplateStaticUrl(asset: string): string {
|
|||
}
|
||||
export function nameplateVideoUrl(asset: string): string {
|
||||
return `${CDN}/assets/collectibles/${asset}asset.webm`;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
* ===================================================================== */
|
||||
|
||||
import type { DiscordStatus, UnifiedCustomStatus, UnifiedPresence, UnifiedSpotify } from "./types";
|
||||
import { emojiUrl } from "./discord/constants";
|
||||
import { activityAssetUrl, emojiUrl } from "./discord/constants";
|
||||
|
||||
export interface RawPresence {
|
||||
user: { id: string };
|
||||
|
|
@ -54,8 +54,29 @@ function extractCustomStatus(activities: any[]): UnifiedCustomStatus | null {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve an activity's `assets.large_image`/`small_image` (which can be a
|
||||
* bare app-asset hash, or a scheme-prefixed external reference like
|
||||
* "twitch:username" for streams) into actual, directly-loadable URLs.
|
||||
* Leaves the original asset fields untouched and just adds the resolved
|
||||
* `*_url` companions, so this is purely additive.
|
||||
*/
|
||||
function enrichActivityAssets(a: any): any {
|
||||
if (!a || !a.assets) return a;
|
||||
const appId = a.application_id ?? null;
|
||||
return {
|
||||
...a,
|
||||
assets: {
|
||||
...a.assets,
|
||||
large_image_url: activityAssetUrl(a.assets.large_image, appId),
|
||||
small_image_url: activityAssetUrl(a.assets.small_image, appId),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function buildPresence(raw: RawPresence): UnifiedPresence {
|
||||
const activities = Array.isArray(raw.activities) ? raw.activities : [];
|
||||
const rawActivities = Array.isArray(raw.activities) ? raw.activities : [];
|
||||
const activities = rawActivities.map(enrichActivityAssets);
|
||||
const status: DiscordStatus = raw.status ?? "offline";
|
||||
const cs = raw.client_status || {};
|
||||
const spotify = extractSpotify(activities);
|
||||
|
|
@ -90,4 +111,4 @@ export function offlinePresence(userId: string): UnifiedPresence {
|
|||
spotify: null,
|
||||
updated_at: Date.now(),
|
||||
};
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue