feat: add pleroma adaptater

This commit is contained in:
2025-10-17 12:27:11 +04:00
parent 184b3d4893
commit 8fa410cfba
+133
View File
@@ -0,0 +1,133 @@
/**
* 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');
})();