2/n Fixing dark mode bugs

This commit is contained in:
Igor Katson 2023-12-16 11:09:51 +00:00
parent 8d886e0961
commit 33c8b11c6e
No known key found for this signature in database
GPG key ID: B4EC22B66D61A3F5
15 changed files with 78 additions and 96 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -4,14 +4,14 @@
"src": "assets/logo.svg" "src": "assets/logo.svg"
}, },
"index.css": { "index.css": {
"file": "assets/index-6a152703.css", "file": "assets/index-7996684a.css",
"src": "index.css" "src": "index.css"
}, },
"index.html": { "index.html": {
"css": [ "css": [
"assets/index-6a152703.css" "assets/index-7996684a.css"
], ],
"file": "assets/index-ba274e55.js", "file": "assets/index-b4a910b9.js",
"isEntry": true, "isEntry": true,
"src": "index.html" "src": "index.html"
} }

View file

@ -36,7 +36,7 @@ export const ErrorComponent = (props: {
{error.details?.statusText && ( {error.details?.statusText && (
<div className="pb-2 text-md">{error.details?.statusText}</div> <div className="pb-2 text-md">{error.details?.statusText}</div>
)} )}
<div className="whitespace-pre-line text-sm">{error.details?.text}</div> <div className="whitespace-pre text-sm">{error.details?.text}</div>
</AlertDanger> </AlertDanger>
); );
}; };

View file

@ -1,9 +1,9 @@
export const Spinner = () => { export const Spinner = ({ label }: { label?: string }) => {
return ( return (
<div role="status"> <div className="flex gap-2 items-center w-full justify-center">
<svg <svg
aria-hidden="true" aria-hidden="true"
className="inline w-8 h-8 text-gray-200 animate-spin fill-blue-600" className="w-8 h-8 text-gray-200 animate-spin dark:text-gray-600 fill-blue-600"
viewBox="0 0 100 101" viewBox="0 0 100 101"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@ -17,7 +17,11 @@ export const Spinner = () => {
fill="currentFill" fill="currentFill"
/> />
</svg> </svg>
<span className="sr-only">Loading...</span> {label ? (
<span className="text-sm">{label} ...</span>
) : (
<span className="sr-only">Loading...</span>
)}
</div> </div>
); );
}; };

View file

@ -6,26 +6,21 @@ export const TorrentsList = (props: {
torrents: Array<TorrentId> | null; torrents: Array<TorrentId> | null;
loading: boolean; loading: boolean;
}) => { }) => {
if (props.torrents === null && props.loading) {
return <Spinner />;
}
// The app either just started, or there was an error loading torrents.
if (props.torrents === null) {
return;
}
if (props.torrents.length === 0) {
return (
<div className="text-center">
<p>No existing torrents found.</p>
</div>
);
}
return ( return (
<div className="flex flex-col gap-2 mx-2"> <div className="flex flex-col gap-2 mx-2 pb-3 sm:px-7">
{props.torrents.map((t: TorrentId) => ( {props.torrents === null ? (
<Torrent id={t.id} key={t.id} torrent={t} /> props.loading ? (
))} <Spinner label="Loading torrent list" />
) : null
) : props.torrents.length === 0 ? (
<p className="text-center">No existing torrents found.</p>
) : (
props.torrents.map((t: TorrentId) => (
<>
<Torrent id={t.id} key={t.id} torrent={t} />
</>
))
)}
</div> </div>
); );
}; };

View file

@ -24,7 +24,11 @@ export const FormCheckbox: React.FC<{
</div> </div>
<div className="text-sm flex flex-col gap-1"> <div className="text-sm flex flex-col gap-1">
<label htmlFor={name}>{label}</label> <label htmlFor={name}>{label}</label>
{help && <div className="text-xs text-slate-500 mb-3">{help}</div>} {help && (
<div className="text-xs text-slate-500 dark:text-slate-300 mb-3">
{help}
</div>
)}
</div> </div>
</div> </div>
); );

View file

@ -25,7 +25,7 @@ export const FormInput: React.FC<{
}) => { }) => {
return ( return (
<div className="flex flex-col gap-2 text-sm mb-2"> <div className="flex flex-col gap-2 text-sm mb-2">
<label htmlFor={name} className="dark:text-slate-500"> <label htmlFor={name} className="dark:text-white">
{label} {label}
</label> </label>
<input <input
@ -40,7 +40,9 @@ export const FormInput: React.FC<{
onKeyDown={onKeyDown} onKeyDown={onKeyDown}
onChange={onChange} onChange={onChange}
/> />
{help && <div className="text-xs text-slate-500">{help}</div>} {help && (
<div className="text-xs text-slate-500 dark:text-slate-300">{help}</div>
)}
</div> </div>
); );
}; };

View file

@ -101,7 +101,7 @@ export const FileSelectionModal = (props: {
const getBody = () => { const getBody = () => {
if (listTorrentLoading) { if (listTorrentLoading) {
return <Spinner />; return <Spinner label="Loading torrent contents" />;
} else if (listTorrentError) { } else if (listTorrentError) {
return <ErrorComponent error={listTorrentError}></ErrorComponent>; return <ErrorComponent error={listTorrentError}></ErrorComponent>;
} else if (listTorrentResponse) { } else if (listTorrentResponse) {

View file

@ -40,7 +40,7 @@ export const Modal: React.FC<ModalProps> = ({
}) => { }) => {
const renderBackdrop = () => { const renderBackdrop = () => {
return ( return (
<div className="fixed inset-0 bg-black/30 z-[300] dark:bg-black/60"></div> <div className="fixed inset-0 bg-black/30 z-[300] dark:bg-black/60 backdrop-blur"></div>
); );
}; };
return ( return (
@ -51,7 +51,7 @@ export const Modal: React.FC<ModalProps> = ({
className="fixed z-[301] top-0 left-0 w-full h-full block overflow-x-hidden overflow-y-auto" className="fixed z-[301] top-0 left-0 w-full h-full block overflow-x-hidden overflow-y-auto"
> >
<div <div
className={`bg-white shadow-lg my-8 mx-auto max-w-2xl rounded ${className} dark:bg-slate-800`} className={`bg-white shadow-lg my-8 mx-auto max-w-2xl rounded ${className} dark:bg-slate-800 dark:text-zinc-50`}
> >
<ModalHeader onClose={onClose} title={title} /> <ModalHeader onClose={onClose} title={title} />
{children} {children}

View file

@ -1,8 +1,3 @@
@tailwind base; @tailwind base;
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
.dark {
@apply bg-gray-800 text-zinc-50
}

View file

@ -67,29 +67,34 @@ export const RqbitWebUI = (props: {
return ( return (
<AppContext.Provider value={context}> <AppContext.Provider value={context}>
<Header title={props.title} /> <div className="dark:bg-gray-900 dark:text-zinc-50 min-h-screen">
<div className="relative dark:bg-gray-900"> <Header title={props.title} />
{/* Menu buttons */} <div className="relative">
<div className="absolute top-0 start-0 pl-2 z-10"> {/* Menu buttons */}
{props.menuButtons && <div className="absolute top-0 start-0 pl-2 z-10">
props.menuButtons.map((b, i) => <span key={i}>{b}</span>)} {props.menuButtons &&
<IconButton onClick={() => setLogsOpened(true)}> props.menuButtons.map((b, i) => <span key={i}>{b}</span>)}
<BsBodyText /> <IconButton onClick={() => setLogsOpened(true)}>
</IconButton> <BsBodyText />
<IconButton onClick={DarkMode.toggle}> </IconButton>
<BsMoon /> <IconButton onClick={DarkMode.toggle}>
</IconButton> <BsMoon />
</IconButton>
</div>
<RootContent
closeableError={closeableError}
otherError={otherError}
torrents={torrents}
torrentsLoading={torrentsLoading}
/>
</div> </div>
<RootContent <LogStreamModal
closeableError={closeableError} show={logsOpened}
otherError={otherError} onClose={() => setLogsOpened(false)}
torrents={torrents}
torrentsLoading={torrentsLoading}
/> />
</div> </div>
<LogStreamModal show={logsOpened} onClose={() => setLogsOpened(false)} />
</AppContext.Provider> </AppContext.Provider>
); );
}; };

View file

@ -1,26 +1,5 @@
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
export default { export default {
content: [ content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
"./index.html", darkMode: "class",
"./src/**/*.{js,ts,jsx,tsx}", };
],
theme: {
extend: {
fadeIn: {
from: { opacity: 0 },
to: { opacity: 1 },
},
fadeOut: {
from: { opacity: 1 },
to: { opacity: 0 },
},
},
animation: {
'fade-in': 'fadeIn 0.3s ease-in-out',
'fade-out': 'fadeOut 0.3s ease-in-out',
},
},
darkMode: 'class',
plugins: [],
}

View file

@ -184,7 +184,8 @@ export const ConfigModal: React.FC<{
const isActive = t === tab; const isActive = t === tab;
let classNames = "text-slate-300"; let classNames = "text-slate-300";
if (isActive) { if (isActive) {
classNames = "text-slate-800 border-b-2 border-blue-800"; classNames =
"text-slate-800 border-b-2 border-blue-800 dark:border-blue-200 dark:text-white";
} }
return ( return (
<button <button

View file

@ -4,8 +4,5 @@ export default {
"./src/**/*.{js,ts,jsx,tsx,mdx}", "./src/**/*.{js,ts,jsx,tsx,mdx}",
"../crates/librqbit/webui/src/**/*.{js,ts,jsx,tsx,mdx}", "../crates/librqbit/webui/src/**/*.{js,ts,jsx,tsx,mdx}",
], ],
theme: { darkMode: "class",
extend: {},
},
plugins: [],
}; };