Update background selector styles and remove

unused components
This commit is contained in:
SethBurkart123
2023-11-15 20:50:09 +11:00
parent 6ac861a424
commit f156663e84
8 changed files with 110 additions and 181 deletions
+94 -66
View File
@@ -3,12 +3,6 @@ import { downloadPresetBackground, openDB, readAllData, writeData } from "../hoo
import presetBackgrounds from "../assets/presetBackgrounds";
import "./BackgroundSelector.css";
import { disableTheme } from "../hooks/ThemeManagment";
import { DownloadProgressCircle } from "./backgroundSelector/DownloadProgressCircle";
import { BackgroundSwatch } from "./backgroundSelector/BackgroundSwatch";
import { BackgroundList } from "./backgroundSelector/BackgroundList";
import { FileUploader } from "./backgroundSelector/FileUploader";
import { RemoveButton } from "./backgroundSelector/RemoveButton";
import { useSettingsContext } from "../SettingsContext";
// Custom Types and Interfaces
export interface Background {
@@ -28,7 +22,6 @@ interface BackgroundSelectorProps {
}
export default function BackgroundSelector({ selectedType, setSelectedType, isEditMode }: BackgroundSelectorProps) {
const { setSettingsState } = useSettingsContext();
const [backgrounds, setBackgrounds] = useState<Background[]>([]);
const [selectedBackground, setSelectedBackground] = useState<string | null>(localStorage.getItem('selectedBackground'));
const [downloadedPresetIds, setDownloadedPresetIds] = useState<string[]>([]);
@@ -82,7 +75,6 @@ export default function BackgroundSelector({ selectedType, setSelectedType, isEd
const selectBackground = (fileId: string): void => {
disableTheme();
setSettingsState(prev => ({ ...prev, animatedBackground: false }));
setSelectedType('background');
setSelectedBackground(fileId);
localStorage.setItem('selectedBackground', fileId);
@@ -108,73 +100,109 @@ export default function BackgroundSelector({ selectedType, setSelectedType, isEd
localStorage.removeItem('selectedBackground');
};
const calcCircumference = (radius: number) => 2 * Math.PI * radius;
useEffect(() => {
loadBackgrounds();
}, []);
return (
<>
<RemoveButton selectedBackground={selectedBackground} selectNoBackground={selectNoBackground} />
<div className="relative">
<h2 className="pb-2 text-lg font-bold">Images</h2>
<div className="flex flex-wrap gap-4">
<FileUploader handleFileChange={handleFileChange} />
<BackgroundList
backgrounds={backgrounds.filter(bg => bg.type === 'image')}
selectBackground={selectBackground}
isEditMode={isEditMode}
deleteBackground={deleteBackground}
selectedBackground={selectedBackground}
selectedType={selectedType}
/>
{/* Preset backgrounds handling (images) */}
{presetBackgrounds
.filter(bg => bg.type === 'image' && bg.isPreset && !downloadedPresetIds.includes(bg.id))
.map(bg => (
<div key={bg.id} onClick={() => handlePresetClick(bg)} className="relative w-16 h-16">
{downloadProgress[bg.id] !== undefined && <DownloadProgressCircle progress={downloadProgress[bg.id]} />}
<BackgroundSwatch
background={bg}
selectBackground={selectBackground}
isEditMode={isEditMode}
deleteBackground={deleteBackground}
selectedBackground={selectedBackground}
selectedType={selectedType}
/>
</div>
))}
<button disabled={selectedBackground == null ? true : false} className={`w-full px-4 py-2 mb-4 dark:text-white transition ${selectedBackground == null ? 'dark:bg-zinc-900 bg-zinc-100' : 'bg-blue-500 text-white'} rounded`} onClick={() => selectNoBackground()}>
{selectedBackground == null ? 'No Background' : 'Remove Background'}
</button>
<div className="relative">
<h2 className="pb-2 text-lg font-bold">Images</h2>
<div className="flex flex-wrap gap-4">
{/* Image uploader swatch */}
<div className="relative w-16 h-16 overflow-hidden transition rounded-xl bg-zinc-100 dark:bg-zinc-900">
<div className="flex items-center justify-center w-full h-full text-3xl font-bold text-gray-400 transition font-IconFamily hover:text-gray-500">
{/* Plus icon */}
</div>
<input type="file" accept='image/*, video/*' onChange={handleFileChange} className="absolute inset-0 w-full h-full opacity-0 cursor-pointer" />
</div>
<h2 className="py-2 text-lg font-bold">Videos</h2>
<div className="flex flex-wrap gap-4">
<FileUploader handleFileChange={handleFileChange} />
<BackgroundList
backgrounds={backgrounds.filter(bg => bg.type === 'video')}
selectBackground={selectBackground}
isEditMode={isEditMode}
deleteBackground={deleteBackground}
selectedBackground={selectedBackground}
selectedType={selectedType}
/>
{/* Preset backgrounds handling (videos) */}
{presetBackgrounds
.filter(bg => bg.type === 'video' && bg.isPreset && !downloadedPresetIds.includes(bg.id))
.map(bg => (
<div key={bg.id} onClick={() => handlePresetClick(bg)} className="relative w-16 h-16">
{downloadProgress[bg.id] !== undefined && <DownloadProgressCircle progress={downloadProgress[bg.id]} />}
<BackgroundSwatch
background={bg}
selectBackground={selectBackground}
isEditMode={isEditMode}
deleteBackground={deleteBackground}
selectedBackground={selectedBackground}
selectedType={selectedType}
/>
{backgrounds.filter(bg => bg.type === 'image').map(bg => (
<div key={bg.id}
onClick={() => selectBackground(bg.id)}
className={`relative w-16 h-16 cursor-pointer rounded-xl transition ring dark:ring-white ring-zinc-300 ${isEditMode ? 'animate-shake' : ''} ${selectedBackground === bg.id && selectedType === "background" ? 'dark:ring-2 ring-4' : 'ring-0'}`}>
{isEditMode && (
<div className="absolute top-0 right-0 z-10 flex w-6 h-6 p-2 text-white translate-x-1/2 -translate-y-1/2 bg-red-600 rounded-full place-items-center"
onClick={() => deleteBackground(bg.id)}>
<div className="w-4 h-0.5 bg-white"></div>
</div>
))}
</div>
)}
<img className="object-cover w-full h-full rounded-xl" src={bg.url} alt="swatch" />
</div>
))}
{backgrounds.concat(presetBackgrounds as Background[]).filter(bg => bg.type === 'image' && bg.isPreset && !bg.isDownloaded && !downloadedPresetIds.includes(bg.id)).map(bg => (
<div key={bg.id}
onClick={() => handlePresetClick(bg)}
className={`relative w-16 h-16 transition cursor-pointer rounded-xl duration-300 ${ isEditMode ? 'opacity-0 pointer-events-none hidden' : 'opacity-100'}`}>
{bg.isPreset && downloadProgress[bg.id] !== undefined && (
<div className="absolute top-0 left-0 z-20 flex items-center justify-center w-full h-full">
<svg className="w-full h-full text-zinc-100 dark:text-zinc-700" viewBox="0 0 36 36">
<circle stroke="currentColor" fill="none" strokeWidth="4" strokeLinecap="round" cx="18" cy="18" r="10" strokeDasharray={`${calcCircumference(14)} ${calcCircumference(14)}`} strokeDashoffset="0" transform="rotate(-90 18 18)"></circle>
<circle stroke="#3B82F6" fill="none" strokeWidth="4" strokeLinecap="round" cx="18" cy="18" r="10" strokeDasharray={`${calcCircumference(14)} ${calcCircumference(14)}`} strokeDashoffset={`${calcCircumference(14) * (1 - (downloadProgress[bg.id] / 100))}`} transform="rotate(-90 18 18)"></circle>
</svg>
</div>
)}
<div className={`relative transition top-0 z-10 flex justify-center w-full h-full text-white rounded-xl group place-items-center ${downloadProgress[bg.id] === undefined ? 'hover:bg-black/20' : ''}`}>
<span className="absolute z-10 text-3xl transition opacity-0 font-IconFamily group-hover:opacity-100">
{downloadProgress[bg.id] === undefined ? '' : ''}
</span>
</div>
<img
className="absolute top-0 object-cover w-full h-full rounded-xl"
src={bg.isPreset ? bg.previewUrl : bg.url} // Use preview for preset backgrounds
alt="swatch" />
</div>
))}
</div>
<h2 className="py-2 text-lg font-bold">Videos</h2>
<div className="flex flex-wrap gap-4">
{/* Video uploader swatch */}
<div className="relative w-16 h-16 overflow-hidden transition rounded-xl bg-zinc-100 dark:bg-zinc-900">
<div className="flex items-center justify-center w-full h-full text-3xl font-bold text-gray-400 transition font-IconFamily hover:text-gray-500">
{/* Plus icon */}
</div>
<input type="file" accept='image/*, video/*' onChange={handleFileChange} className="absolute inset-0 w-full h-full opacity-0 cursor-pointer" />
</div>
{backgrounds.filter(bg => bg.type === 'video').map(bg => (
<div key={bg.id} onClick={() => selectBackground(bg.id)} className={`relative w-16 h-16 cursor-pointer rounded-xl transition ring dark:ring-white ring-zinc-300 ${isEditMode ? 'animate-shake' : ''} ${selectedBackground === bg.id && selectedType === "background" ? 'dark:ring-2 ring-4' : 'ring-0'}`}>
{isEditMode && (
<div className="absolute top-0 right-0 z-10 flex w-6 h-6 p-2 text-white translate-x-1/2 -translate-y-1/2 bg-red-600 rounded-full place-items-center"
onClick={() => deleteBackground(bg.id)}>
<div className="w-4 h-0.5 bg-white"></div>
</div>
)}
<video muted loop autoPlay src={bg.url} className="object-cover w-full h-full rounded-xl" />
</div>
))}
{backgrounds.concat(presetBackgrounds as Background[]).filter(bg => bg.type === 'video' && bg.isPreset && !bg.isDownloaded && !downloadedPresetIds.includes(bg.id)).map(bg => (
<div key={bg.id}
onClick={() => handlePresetClick(bg)}
className={`relative w-16 h-16 transition cursor-pointer rounded-xl duration-300 ${ isEditMode ? 'opacity-0 pointer-events-none hidden' : 'opacity-100'}`}>
{bg.isPreset && downloadProgress[bg.id] !== undefined && (
<div className="absolute top-0 left-0 z-20 flex items-center justify-center w-full h-full">
<svg className="w-full h-full text-zinc-100 dark:text-zinc-700" viewBox="0 0 36 36">
<circle stroke="currentColor" fill="none" strokeWidth="4" strokeLinecap="round" cx="18" cy="18" r="10" strokeDasharray={`${calcCircumference(14)} ${calcCircumference(14)}`} strokeDashoffset="0" transform="rotate(-90 18 18)"></circle>
<circle stroke="#3B82F6" fill="none" strokeWidth="4" strokeLinecap="round" cx="18" cy="18" r="10" strokeDasharray={`${calcCircumference(14)} ${calcCircumference(14)}`} strokeDashoffset={`${calcCircumference(14) * (1 - (downloadProgress[bg.id] / 100))}`} transform="rotate(-90 18 18)"></circle>
</svg>
</div>
)}
<div className={`relative transition top-0 z-10 flex justify-center w-full h-full text-white rounded-xl group place-items-center ${downloadProgress[bg.id] === undefined ? 'hover:bg-black/20' : ''}`}>
<span className="absolute z-10 text-3xl transition opacity-0 font-IconFamily group-hover:opacity-100">
{downloadProgress[bg.id] === undefined ? '' : ''}
</span>
</div>
<video muted loop autoPlay src={bg.isPreset ? bg.previewUrl : bg.url} className="absolute top-0 object-cover w-full h-full rounded-xl" />
</div>
))}
</div>
</div>
</>
);
}
+15 -1
View File
@@ -12,8 +12,22 @@ export default function Picker() {
'linear-gradient(30deg, rgba(229,209,218,1) 0%, RGBA(235,169,202,1) 46%, rgba(214,155,162,1) 100%)',
'linear-gradient(40deg, rgba(201,61,0,1) 0%, RGBA(170, 5, 58, 1) 100%)',
'linear-gradient(40deg, rgba(0, 141, 201, 0.76) 0%, rgba(8, 5, 170, 0.66) 100%)',
'linear-gradient(40deg, rgba(0, 201, 20, 0.76) 0%, rgba(4, 160, 105, 0.66) 100%)',
'linear-gradient(40deg, rgba(199, 20, 55, 0.76) 0%, rgba(95, 11, 160, 0.66) 100%)',
'linear-gradient(40deg, rgba(24, 20, 199, 0.76) 0%, rgba(23, 173, 65, 0.66) 100%)',
'radial-gradient(circle, rgba(20, 199, 178, 0.76) 32%, rgba(3, 120, 57, 0.66) 100%)',
'radial-gradient(circle, rgba(13, 15, 145, 0.76) 12%, rgba(103, 3, 120, 0.66) 100%)',
'linear-gradient(20deg, rgb(230, 21, 21) 0%, rgb(230, 109, 21) 12%, rgb(230, 34, 21) 26%, rgb(230, 21, 21) 39%, rgb(230, 84, 21) 48%, rgb(230, 34, 21) 58%, rgb(230, 96, 21) 69%, rgb(230, 34, 21) 80%, rgb(230, 71, 21) 89%, rgb(230, 21, 21) 100%)',
'rgba(114, 1, 170, 0.89)',
'rgba(93, 135, 63, 0.89)',
'rgba(4, 4, 138, 0.77)',
'rgba(21, 20, 20, 0.89)',
'linear-gradient(340deg, rgb(205, 74, 82) 18%, rgba(132, 8, 8, 0.89) 46%, rgb(204, 78, 85) 72%)',
'radial-gradient(circle, rgb(74, 205, 158) 0%, rgba(8, 72, 132, 0.89) 99%)',
'rgba(17, 94, 89, 1)',
'rgba(30, 64, 175, 0.89)',
'rgba(134, 25, 143, 1)',
'rgba(14, 165, 233, 0.9)'
];
const [presets, setPresets] = useState(() => {
const savedPresets = localStorage.getItem('colorPickerPresets');
@@ -1,30 +0,0 @@
import React from 'react';
import { BackgroundSwatch } from './BackgroundSwatch';
import { Background } from '../BackgroundSelector'; // Import the Background interface
interface BackgroundListProps {
backgrounds: Background[];
selectBackground: (fileId: string) => void;
isEditMode: boolean;
deleteBackground: (fileId: string) => Promise<void>;
selectedBackground: string | null;
selectedType: 'background' | 'theme';
}
export const BackgroundList: React.FC<BackgroundListProps> = ({ backgrounds, selectBackground, isEditMode, deleteBackground, selectedBackground, selectedType }) => {
return (
<>
{backgrounds.map(bg => (
<BackgroundSwatch
key={bg.id}
background={bg}
selectBackground={selectBackground}
isEditMode={isEditMode}
deleteBackground={deleteBackground}
selectedBackground={selectedBackground}
selectedType={selectedType}
/>
))}
</>
);
};
@@ -1,36 +0,0 @@
import React from 'react';
interface BackgroundSwatchProps {
background: {
id: string;
type: string;
url: string;
previewUrl: string;
isPreset: boolean;
};
selectBackground: (fileId: string) => void;
isEditMode: boolean;
deleteBackground: (fileId: string) => Promise<void>;
selectedBackground: string | null;
selectedType: 'background' | 'theme';
}
export const BackgroundSwatch: React.FC<BackgroundSwatchProps> = ({ background, selectBackground, isEditMode, deleteBackground, selectedBackground, selectedType }) => {
const { id, url, type } = background;
const isSelected = selectedBackground === id && selectedType === "background";
return (
<div key={id} onClick={() => selectBackground(id)} className={`relative w-16 h-16 cursor-pointer rounded-xl transition ring dark:ring-white ring-zinc-300 ${isEditMode ? 'animate-shake' : ''} ${isSelected ? 'dark:ring-2 ring-4' : 'ring-0'}`}>
{isEditMode && (
<div className="absolute top-0 right-0 z-10 flex w-6 h-6 p-2 text-white translate-x-1/2 -translate-y-1/2 bg-red-600 rounded-full place-items-center"
onClick={() => deleteBackground(id)}>
<div className="w-4 h-0.5 bg-white"></div>
</div>
)}
{type === 'image' ?
<img className="object-cover w-full h-full rounded-xl" src={url} alt="swatch" /> :
<video muted loop autoPlay src={url} className="object-cover w-full h-full rounded-xl" />
}
</div>
);
};
@@ -1,16 +0,0 @@
import React from 'react';
interface DownloadProgressCircleProps {
progress: number;
}
export const DownloadProgressCircle: React.FC<DownloadProgressCircleProps> = ({ progress }) => {
const calcCircumference = (radius: number) => 2 * Math.PI * radius;
return (
<svg className="absolute z-10 w-full h-full text-zinc-100 dark:text-zinc-700" viewBox="0 0 36 36">
<circle stroke="currentColor" fill="none" strokeWidth="4" strokeLinecap="round" cx="18" cy="18" r="10" strokeDasharray={`${calcCircumference(14)} ${calcCircumference(14)}`} strokeDashoffset="0" transform="rotate(-90 18 18)"></circle>
<circle stroke="#3B82F6" fill="none" strokeWidth="4" strokeLinecap="round" cx="18" cy="18" r="10" strokeDasharray={`${calcCircumference(14)} ${calcCircumference(14)}`} strokeDashoffset={`${calcCircumference(14) * (1 - (progress / 100))}`} transform="rotate(-90 18 18)"></circle>
</svg>
);
};
@@ -1,17 +0,0 @@
import React, { ChangeEvent } from 'react';
interface FileUploaderProps {
handleFileChange: (e: ChangeEvent<HTMLInputElement>) => Promise<void>;
}
export const FileUploader: React.FC<FileUploaderProps> = ({ handleFileChange }) => {
return (
<div className="relative w-16 h-16 overflow-hidden transition rounded-xl bg-zinc-100 dark:bg-zinc-900">
<div className="flex items-center justify-center w-full h-full text-3xl font-bold text-gray-400 transition font-IconFamily hover:text-gray-500">
{/* Plus icon */}
</div>
<input type="file" accept='image/*, video/*' onChange={handleFileChange} className="absolute inset-0 w-full h-full opacity-0 cursor-pointer" />
</div>
);
};
@@ -1,14 +0,0 @@
import React from 'react';
interface RemoveButtonProps {
selectedBackground: string | null;
selectNoBackground: () => void;
}
export const RemoveButton: React.FC<RemoveButtonProps> = ({ selectedBackground, selectNoBackground }) => {
return (
<button disabled={selectedBackground == null} className={`w-full px-4 py-2 mb-4 dark:text-white transition ${selectedBackground == null ? 'dark:bg-zinc-900 bg-zinc-100' : 'bg-blue-500 text-white'} rounded`} onClick={selectNoBackground}>
{selectedBackground == null ? 'No Background' : 'Remove Background'}
</button>
);
};
+1 -1
View File
@@ -1419,7 +1419,7 @@ ul.singleSelect, ul.buttonChecklist, ul.buttonMenu, ul.colourButtonOptions, ul.u
color: var(--text-primary);
}
body {
background: var(--better-light);
background: var(--theme-primary);
overflow: hidden;
}
#main > .notices > .notice {