mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
feat(media hosting): add imgbb provider
This commit is contained in:
@@ -5,6 +5,7 @@ describe('direct-url', () => {
|
||||
describe('isDirectMediaUrl', () => {
|
||||
it('returns true for image extensions', () => {
|
||||
expect(isDirectMediaUrl('https://example.com/photo.jpg')).toBe(true);
|
||||
expect(isDirectMediaUrl('https://i.ibb.co/example/photo.jpg')).toBe(true);
|
||||
expect(isDirectMediaUrl('https://example.com/photo.jpeg')).toBe(true);
|
||||
expect(isDirectMediaUrl('https://example.com/photo.png')).toBe(true);
|
||||
expect(isDirectMediaUrl('https://example.com/photo.gif')).toBe(true);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { orchestrateElectronUpload } from '../upload-orchestrator';
|
||||
import { uploadToCatbox } from '../../utils/catbox-utils';
|
||||
import type { ProviderId } from '../types';
|
||||
|
||||
vi.mock('../../utils/catbox-utils', () => ({
|
||||
uploadToCatbox: vi.fn(),
|
||||
@@ -11,7 +12,7 @@ function createElectronApiMock() {
|
||||
isElectron: true,
|
||||
copyToClipboard: vi.fn(async () => ({ success: true })),
|
||||
getPlatform: vi.fn(async () => ({ platform: 'darwin' as NodeJS.Platform, arch: 'x64', version: 'v20.0.0' })),
|
||||
automateUploadMedia: vi.fn(async () => ({ url: 'https://i.imgur.com/abc.png', provider: 'imgur' as const })),
|
||||
automateUploadMedia: vi.fn(async (options: { provider: ProviderId }) => ({ url: 'https://i.imgur.com/abc.png', provider: options.provider })),
|
||||
getPathForFile: vi.fn((): string | null => '/tmp/image.png'),
|
||||
};
|
||||
}
|
||||
@@ -48,6 +49,21 @@ describe('orchestrateElectronUpload', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('routes ImgBB through Electron automation', async () => {
|
||||
const electronApi = createElectronApiMock();
|
||||
electronApi.automateUploadMedia = vi.fn(async () => ({ url: 'https://i.ibb.co/example/image.png', provider: 'imgbb' as const }));
|
||||
window.electronApi = electronApi;
|
||||
|
||||
const file = new File(['x'], 'x.png', { type: 'image/png' });
|
||||
const url = await orchestrateElectronUpload(file, ['imgbb']);
|
||||
|
||||
expect(url).toBe('https://i.ibb.co/example/image.png');
|
||||
expect(electronApi.automateUploadMedia).toHaveBeenCalledWith({
|
||||
provider: 'imgbb',
|
||||
filePath: '/tmp/image.png',
|
||||
});
|
||||
});
|
||||
|
||||
it('fails with provider attempt details if no file path can be resolved', async () => {
|
||||
const electronApi = createElectronApiMock();
|
||||
electronApi.getPathForFile = vi.fn((): string | null => null);
|
||||
|
||||
@@ -4,6 +4,8 @@ interface ProviderDefinition {
|
||||
id: ProviderId;
|
||||
label: string;
|
||||
homepageUrl: string;
|
||||
/** Image URLs used to detect whether this provider is reachable from the user's network. */
|
||||
availabilityProbeUrls: readonly string[];
|
||||
/** Runtimes where automated upload is supported (non-web = no interactive fallback) */
|
||||
supportedRuntimes: readonly MediaHostingRuntime[];
|
||||
}
|
||||
@@ -14,12 +16,21 @@ export const MEDIA_HOSTING_PROVIDERS: readonly ProviderDefinition[] = [
|
||||
id: 'catbox',
|
||||
label: 'Catbox',
|
||||
homepageUrl: 'https://catbox.moe',
|
||||
availabilityProbeUrls: ['https://catbox.moe/pictures/logo.png', 'https://files.catbox.moe/8ten4y.png'],
|
||||
supportedRuntimes: ['web', 'electron', 'android'],
|
||||
},
|
||||
{
|
||||
id: 'imgur',
|
||||
label: 'Imgur',
|
||||
homepageUrl: 'https://imgur.com',
|
||||
availabilityProbeUrls: ['https://s.imgur.com/images/favicon-32x32.png', 'https://i.imgur.com/YpB7qfa.jpg'],
|
||||
supportedRuntimes: ['electron'],
|
||||
},
|
||||
{
|
||||
id: 'imgbb',
|
||||
label: 'ImgBB',
|
||||
homepageUrl: 'https://imgbb.com',
|
||||
availabilityProbeUrls: ['https://simgbb.com/images/logo.png', 'https://i.ibb.co/7Jsq00V5/spoiler.png'],
|
||||
supportedRuntimes: ['electron', 'android'],
|
||||
},
|
||||
] as const;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/** Supported media hosting provider identifiers */
|
||||
export type ProviderId = 'catbox' | 'imgur';
|
||||
export type ProviderId = 'catbox' | 'imgur' | 'imgbb';
|
||||
|
||||
/** User-facing upload mode */
|
||||
export type UploadMode = 'random' | 'preferred' | 'none';
|
||||
|
||||
@@ -58,11 +58,11 @@ function resolveElectronFilePath(file: File): string | null {
|
||||
|
||||
/**
|
||||
* Uploads a file via a single provider. Catbox uses the web API;
|
||||
* imgur uses Electron automation when available.
|
||||
* imgur/imgbb use Electron automation when available.
|
||||
*/
|
||||
async function uploadViaProvider(provider: ProviderId, file: File): Promise<string> {
|
||||
if (provider === 'catbox') return uploadToCatbox(file);
|
||||
if (provider === 'imgur') {
|
||||
if (provider === 'imgur' || provider === 'imgbb') {
|
||||
const fn = typeof window !== 'undefined' && window.electronApi?.automateUploadMedia;
|
||||
if (fn) {
|
||||
const filePath = resolveElectronFilePath(file);
|
||||
|
||||
Reference in New Issue
Block a user