mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-06 03:34:40 +00:00
add pocketbase theme uploading
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { CustomTheme } from '../types/CustomThemes';
|
import { CustomTheme } from '../types/CustomThemes';
|
||||||
import browser from 'webextension-polyfill';
|
import browser from 'webextension-polyfill';
|
||||||
import { PencilIcon } from '@heroicons/react/24/outline';
|
import { ArrowUpOnSquareIcon, PencilIcon, ShareIcon } from '@heroicons/react/24/outline';
|
||||||
|
|
||||||
type ThemeCoverProps = {
|
type ThemeCoverProps = {
|
||||||
theme: Omit<CustomTheme, 'CustomImages'>;
|
theme: Omit<CustomTheme, 'CustomImages'>;
|
||||||
@@ -45,12 +45,21 @@ export const ThemeCover: React.FC<ThemeCoverProps> = ({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{ isEditMode ? <></> :
|
{ isEditMode ? <></> :
|
||||||
|
<>
|
||||||
<div
|
<div
|
||||||
className="absolute z-20 flex w-8 h-8 p-2 text-white transition-all rounded-full opacity-0 top-1 right-2 dark:bg-black/50 place-items-center group-hover:opacity-100 group-hover:top-2"
|
className="absolute z-20 flex w-8 h-8 p-2 text-white transition-all rounded-full delay-[20ms] opacity-0 top-1 right-2 dark:bg-black/50 place-items-center group-hover:opacity-100 group-hover:top-[1.25rem]"
|
||||||
onClick={() => browser.runtime.sendMessage({ type: 'currentTab', info: 'OpenThemeCreator', body: { themeID: theme.id } })}
|
onClick={(event) => { event?.preventDefault(), browser.runtime.sendMessage({ type: 'currentTab', info: 'OpenThemeCreator', body: { themeID: theme.id } }) }}
|
||||||
>
|
>
|
||||||
<PencilIcon className="w-4 h-4" />
|
<PencilIcon className="w-4 h-4" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className="absolute z-20 flex w-8 h-8 p-2 text-white transition-all rounded-full opacity-0 top-1 right-12 dark:bg-black/50 place-items-center group-hover:opacity-100 group-hover:top-[1.25rem]"
|
||||||
|
onClick={(event) => { event?.preventDefault(), browser.runtime.sendMessage({ type: 'currentTab', info: 'ShareTheme', body: { themeID: theme.id } }) }}
|
||||||
|
>
|
||||||
|
<ArrowUpOnSquareIcon className="w-4 h-4" />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
}
|
}
|
||||||
|
|
||||||
<div className="relative top-0 z-10 flex justify-center w-full h-full overflow-hidden transition dark:text-white rounded-xl group place-items-center bg-zinc-100 dark:bg-zinc-900">
|
<div className="relative top-0 z-10 flex justify-center w-full h-full overflow-hidden transition dark:text-white rounded-xl group place-items-center bg-zinc-100 dark:bg-zinc-900">
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ const ThemeSelector: ForwardRefExoticComponent<Omit<ThemeSelectorProps, "ref"> &
|
|||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={() => Browser.tabs.create({ url: Browser.runtime.getURL('src/interface/index.html#store')})}
|
onClick={() => Browser.tabs.create({ url: Browser.runtime.getURL('src/interface/index.html#store')})}
|
||||||
className="flex items-center justify-center w-full mt-2 transition aspect-theme rounded-xl bg-zinc-100 dark:bg-zinc-900 dark:text-white"
|
className="flex items-center justify-center w-full transition aspect-theme rounded-xl bg-zinc-100 dark:bg-zinc-900 dark:text-white"
|
||||||
>
|
>
|
||||||
<span className="text-xl font-IconFamily">{'\uecc5'}</span>
|
<span className="text-xl font-IconFamily">{'\uecc5'}</span>
|
||||||
<span className="ml-2">Theme Store</span>
|
<span className="ml-2">Theme Store</span>
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import PocketBase from 'pocketbase';
|
||||||
|
import { getTheme } from './getTheme';
|
||||||
|
|
||||||
|
const pb = new PocketBase('https://betterseqta.pockethost.io');
|
||||||
|
|
||||||
|
const shareTheme = async (themeID: string) => {
|
||||||
|
try {
|
||||||
|
// Use getTheme to retrieve the theme data
|
||||||
|
const themeData = await getTheme(themeID);
|
||||||
|
if (!themeData) {
|
||||||
|
console.error('Failed to retrieve theme data');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract images and coverImage from themeData, if they exist
|
||||||
|
const { CustomImages = [], coverImage, ...themeWithoutImages } = themeData;
|
||||||
|
|
||||||
|
const finalCoverImage = await fetch(coverImage as string).then((res) => res.blob());
|
||||||
|
let finalImages: { id: string, data: Blob }[] = [];
|
||||||
|
|
||||||
|
for (const image of CustomImages) {
|
||||||
|
const finalImage = await fetch(image.url as string).then((res) => res.blob());
|
||||||
|
|
||||||
|
finalImages.push({
|
||||||
|
id: image.id,
|
||||||
|
data: finalImage,
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Prepare the non-file data for uploading
|
||||||
|
const data = {
|
||||||
|
name: themeData.name || 'Unnamed Theme',
|
||||||
|
description: themeData.description || 'No description',
|
||||||
|
downloads: '0', // Assuming initial value as 0
|
||||||
|
theme: JSON.stringify({
|
||||||
|
...themeWithoutImages,
|
||||||
|
images: [
|
||||||
|
...CustomImages.map((image) => ({
|
||||||
|
id: image.id,
|
||||||
|
variableName: image.variableName,
|
||||||
|
})),
|
||||||
|
],
|
||||||
|
}), // Convert theme data (excluding images) to JSON string
|
||||||
|
submitted: true,
|
||||||
|
coverImage: new File([finalCoverImage], 'coverImage.png'),
|
||||||
|
images: [ ...finalImages.map((image) => new File([image.data], `${image.id}.png`)) ],
|
||||||
|
};
|
||||||
|
|
||||||
|
const record = await pb.collection('themes').create(data);
|
||||||
|
|
||||||
|
console.debug('record', record);
|
||||||
|
|
||||||
|
return record.id;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error sharing theme:', error);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default shareTheme;
|
||||||
@@ -9,6 +9,7 @@ import { getTheme } from '../../ui/themes/getTheme';
|
|||||||
import { setTheme } from '../../ui/themes/setTheme';
|
import { setTheme } from '../../ui/themes/setTheme';
|
||||||
import { disableTheme } from '../../ui/themes/disableTheme';
|
import { disableTheme } from '../../ui/themes/disableTheme';
|
||||||
import { CloseThemeCreator, OpenThemeCreator } from '../../ui/ThemeCreator';
|
import { CloseThemeCreator, OpenThemeCreator } from '../../ui/ThemeCreator';
|
||||||
|
import ShareTheme from '../../ui/themes/shareTheme';
|
||||||
|
|
||||||
export class MessageHandler {
|
export class MessageHandler {
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -81,6 +82,12 @@ export class MessageHandler {
|
|||||||
sendResponse({ status: 'success' });
|
sendResponse({ status: 'success' });
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'ShareTheme':
|
||||||
|
ShareTheme(request.body.themeID).then((id) => {
|
||||||
|
sendResponse({ status: 'success', id });
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
|
||||||
case 'CloseThemeCreator':
|
case 'CloseThemeCreator':
|
||||||
CloseThemeCreator();
|
CloseThemeCreator();
|
||||||
sendResponse({ status: 'success' });
|
sendResponse({ status: 'success' });
|
||||||
|
|||||||
Reference in New Issue
Block a user