134 lines
4.1 KiB
JavaScript
134 lines
4.1 KiB
JavaScript
/**
|
|
* Pleroma to Mastodon API Response Adapter
|
|
*
|
|
* This script intercepts fetch requests to Pleroma instances and adapts
|
|
* the responses to match the structure expected by mastodon-timeline.umd.js
|
|
*/
|
|
|
|
(function() {
|
|
'use strict';
|
|
|
|
// Store original fetch
|
|
const originalFetch = window.fetch;
|
|
|
|
// Override fetch globally
|
|
window.fetch = async function(...args) {
|
|
const response = await originalFetch.apply(this, args);
|
|
|
|
// Only intercept Pleroma API timeline and emoji requests
|
|
const url = args[0];
|
|
if (typeof url === 'string' &&
|
|
(url.includes('/api/v1/timelines/') ||
|
|
url.includes('/api/v1/accounts/') && url.includes('/statuses'))) {
|
|
|
|
// Clone the response so we can modify it
|
|
const clonedResponse = response.clone();
|
|
|
|
try {
|
|
const data = await clonedResponse.json();
|
|
|
|
// Adapt the response structure
|
|
const adaptedData = Array.isArray(data)
|
|
? data.map(adaptPost)
|
|
: adaptPost(data);
|
|
|
|
// Create a new response with adapted data
|
|
return new Response(JSON.stringify(adaptedData), {
|
|
status: response.status,
|
|
statusText: response.statusText,
|
|
headers: response.headers
|
|
});
|
|
} catch (error) {
|
|
console.warn('Pleroma adapter: Failed to parse response, returning original', error);
|
|
return response;
|
|
}
|
|
}
|
|
|
|
return response;
|
|
};
|
|
|
|
/**
|
|
* Adapt a single Pleroma post to Mastodon format
|
|
*/
|
|
function adaptPost(post) {
|
|
if (!post || typeof post !== 'object') {
|
|
return post;
|
|
}
|
|
|
|
// Create a copy to avoid mutating the original
|
|
const adapted = { ...post };
|
|
|
|
// Adapt media attachments
|
|
if (adapted.media_attachments && Array.isArray(adapted.media_attachments)) {
|
|
adapted.media_attachments = adapted.media_attachments.map(adaptMediaAttachment);
|
|
}
|
|
|
|
// Adapt reblog if present
|
|
if (adapted.reblog) {
|
|
adapted.reblog = adaptPost(adapted.reblog);
|
|
}
|
|
|
|
return adapted;
|
|
}
|
|
|
|
/**
|
|
* Adapt media attachment to include missing meta fields
|
|
*/
|
|
function adaptMediaAttachment(attachment) {
|
|
if (!attachment || typeof attachment !== 'object') {
|
|
return attachment;
|
|
}
|
|
|
|
// If meta already exists and has required fields, return as-is
|
|
if (attachment.meta?.original?.width && attachment.meta?.small?.aspect) {
|
|
return attachment;
|
|
}
|
|
|
|
// Create adapted attachment
|
|
const adapted = { ...attachment };
|
|
|
|
// Default dimensions (will work for most cases)
|
|
const defaultWidth = 1280;
|
|
const defaultHeight = 720;
|
|
const defaultAspect = defaultWidth / defaultHeight;
|
|
|
|
// Try to extract dimensions from Pleroma's meta if available
|
|
let width = defaultWidth;
|
|
let height = defaultHeight;
|
|
|
|
if (attachment.pleroma?.mime_type) {
|
|
// For videos, use 16:9 ratio
|
|
if (attachment.pleroma.mime_type.startsWith('video/')) {
|
|
width = 1920;
|
|
height = 1080;
|
|
}
|
|
// For images, use standard web dimensions
|
|
else if (attachment.pleroma.mime_type.startsWith('image/')) {
|
|
width = 1200;
|
|
height = 800;
|
|
}
|
|
}
|
|
|
|
// Ensure meta structure exists
|
|
adapted.meta = adapted.meta || {};
|
|
|
|
// Add original dimensions
|
|
adapted.meta.original = adapted.meta.original || {
|
|
width: width,
|
|
height: height,
|
|
aspect: width / height
|
|
};
|
|
|
|
// Add small (preview) dimensions
|
|
adapted.meta.small = adapted.meta.small || {
|
|
width: Math.floor(width / 2),
|
|
height: Math.floor(height / 2),
|
|
aspect: width / height
|
|
};
|
|
|
|
return adapted;
|
|
}
|
|
|
|
console.log('Pleroma adapter initialized: API responses will be adapted for Mastodon compatibility');
|
|
})();
|