From 977303506936e7ed4657e360cc60b28d104c099b Mon Sep 17 00:00:00 2001 From: Steven Crader Date: Sat, 15 Apr 2023 21:09:54 -0700 Subject: [PATCH 1/5] Fix issues with dark theme Ex: buttons staying white --- ui/images/transcript.svg | 3 +-- ui/src/components/Button/styles.scss | 3 +++ ui/src/components/EpisodeItem/index.tsx | 2 +- ui/src/components/EpisodeItem/styles.scss | 7 +++---- ui/src/components/PodcastHeader/index.tsx | 3 ++- ui/src/components/PodcastHeader/styles.scss | 1 + ui/src/components/RecentPodcasts/styles.scss | 1 + ui/src/components/ResultItem/styles.scss | 4 +--- ui/src/components/TopBar/styles.scss | 3 +-- ui/src/pages/AddFeed/index.tsx | 1 + ui/src/pages/AddFeed/styles.scss | 3 +++ ui/src/pages/Stats/StatsCard/styles.scss | 12 +++++++++++- web-ui | 1 - 13 files changed, 29 insertions(+), 15 deletions(-) delete mode 160000 web-ui diff --git a/ui/images/transcript.svg b/ui/images/transcript.svg index 3b182309..81d2de23 100644 --- a/ui/images/transcript.svg +++ b/ui/images/transcript.svg @@ -21,7 +21,6 @@ - - + diff --git a/ui/src/components/Button/styles.scss b/ui/src/components/Button/styles.scss index ecfab374..5808b0e2 100644 --- a/ui/src/components/Button/styles.scss +++ b/ui/src/components/Button/styles.scss @@ -1,9 +1,11 @@ :root { + --button-background: #F0F0F0; --button-hover-color: #f2f2f2; } @media (prefers-color-scheme: dark) { :root { + --button-background: #1a1a1a; --button-hover-color: #302d2d; } } @@ -14,6 +16,7 @@ font-family: var(--font-family-exp); font-size: 16px; color: var(--fg-main); + background-color: var(--button-background); padding: 8px 20px; text-align: center; white-space: nowrap; diff --git a/ui/src/components/EpisodeItem/index.tsx b/ui/src/components/EpisodeItem/index.tsx index cd079295..cfa15f19 100644 --- a/ui/src/components/EpisodeItem/index.tsx +++ b/ui/src/components/EpisodeItem/index.tsx @@ -143,7 +143,7 @@ export default class EpisodeItem extends React.PureComponent { {episodeEnclosure ? : "" } {feedURL ? - + : "" } diff --git a/ui/src/components/PodcastHeader/styles.scss b/ui/src/components/PodcastHeader/styles.scss index 061b741e..b311f378 100644 --- a/ui/src/components/PodcastHeader/styles.scss +++ b/ui/src/components/PodcastHeader/styles.scss @@ -26,6 +26,7 @@ img { height: 300px; width: 300px; + object-fit: contain; border-radius: 10px; border: 1px solid var(--cover-art-border-color); } diff --git a/ui/src/components/RecentPodcasts/styles.scss b/ui/src/components/RecentPodcasts/styles.scss index d9d3a562..3a9889e4 100644 --- a/ui/src/components/RecentPodcasts/styles.scss +++ b/ui/src/components/RecentPodcasts/styles.scss @@ -122,6 +122,7 @@ img { width: 450px; height: 450px; + object-fit: contain; border-radius: 14px; border: 1px solid var(--player-cover-art-border-color); } diff --git a/ui/src/components/ResultItem/styles.scss b/ui/src/components/ResultItem/styles.scss index bd812075..eeb4a5bc 100644 --- a/ui/src/components/ResultItem/styles.scss +++ b/ui/src/components/ResultItem/styles.scss @@ -43,6 +43,7 @@ img { height: 140px; width: 140px; + object-fit: contain; border-radius: 10px; border: 1px solid var(--cover-art-border-color); } @@ -140,11 +141,8 @@ } .result-category { font-size: 14px; - background: #f3f3f3; - border: 1px solid #cecece; border-radius: 5px; margin: 3px; - padding: 4px 12px; } } diff --git a/ui/src/components/TopBar/styles.scss b/ui/src/components/TopBar/styles.scss index b797d93f..72310d80 100644 --- a/ui/src/components/TopBar/styles.scss +++ b/ui/src/components/TopBar/styles.scss @@ -110,11 +110,10 @@ a, border: 1px solid lighten(#d6d6d6, 0.2); margin: 10px 10px; display: flex; - background: white; + background: var(--bg-color); flex-direction: column; border-radius: 4px; box-shadow: 0 0 9px 0 rgba(192, 192, 192, 0.5); - padding: 10px 0; .button-wrapper { width: 100%; .button { diff --git a/ui/src/pages/AddFeed/index.tsx b/ui/src/pages/AddFeed/index.tsx index cda1dfdb..d29cf3d6 100644 --- a/ui/src/pages/AddFeed/index.tsx +++ b/ui/src/pages/AddFeed/index.tsx @@ -284,6 +284,7 @@ export default class AddFeed extends React.PureComponent { diff --git a/ui/src/pages/AddFeed/styles.scss b/ui/src/pages/AddFeed/styles.scss index 22ce966c..8b6953c7 100644 --- a/ui/src/pages/AddFeed/styles.scss +++ b/ui/src/pages/AddFeed/styles.scss @@ -97,6 +97,9 @@ } } + .add-button { + margin-top: 5px; + } } } diff --git a/ui/src/pages/Stats/StatsCard/styles.scss b/ui/src/pages/Stats/StatsCard/styles.scss index b8c491fa..4037a31e 100644 --- a/ui/src/pages/Stats/StatsCard/styles.scss +++ b/ui/src/pages/Stats/StatsCard/styles.scss @@ -1,3 +1,13 @@ +:root { + --bg-color: #ffffff; +} + +@media (prefers-color-scheme: dark) { + :root { + --bg-color: #180e0e; + } +} + .kpi-card { display: inline-flex; flex-direction: row; @@ -10,7 +20,7 @@ width: inherit; padding: 30px; // box-shadow: 0 0 0 1px rgba(16, 22, 26, 0.15); - background: #f3f3f3; + background: var(--bg-color); border-radius: 12px; } .kpi-massive-title { diff --git a/web-ui b/web-ui deleted file mode 160000 index 3da61fd3..00000000 --- a/web-ui +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 3da61fd34677eaed697db91dfcd01032a87fc2a5 From 6c19532a09aa0980becc4aebb4a46927682cdcf2 Mon Sep 17 00:00:00 2001 From: Steven Crader Date: Sat, 15 Apr 2023 22:51:04 -0700 Subject: [PATCH 2/5] Fix width overflow on phones --- ui/src/components/Player/styles.scss | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ui/src/components/Player/styles.scss b/ui/src/components/Player/styles.scss index fba09882..4ee5d0f8 100644 --- a/ui/src/components/Player/styles.scss +++ b/ui/src/components/Player/styles.scss @@ -37,7 +37,7 @@ text-overflow: ellipsis; margin-bottom: 5px; - > a { + a { font-size: 16px; font-family: var(--font-family); color: var(--fg-main); @@ -91,4 +91,7 @@ .player-show-title p { max-width: 350px; } + .player-podcast-name { + max-width: 350px; + } } From 4405d546e12752aa1b359c0211f0b14ef0af1ad0 Mon Sep 17 00:00:00 2001 From: Steven Crader Date: Sat, 15 Apr 2023 22:52:06 -0700 Subject: [PATCH 3/5] Add loading placeholder for image when navigating Recent Podcasts --- ui/src/components/RecentPodcasts/index.tsx | 55 +++++++++++++++----- ui/src/components/RecentPodcasts/styles.scss | 22 +++++++- 2 files changed, 62 insertions(+), 15 deletions(-) diff --git a/ui/src/components/RecentPodcasts/index.tsx b/ui/src/components/RecentPodcasts/index.tsx index 20b37848..b84255f7 100644 --- a/ui/src/components/RecentPodcasts/index.tsx +++ b/ui/src/components/RecentPodcasts/index.tsx @@ -7,7 +7,7 @@ import NoImage from '../../../images/no-cover-art.png' import ForwardIcon from '../../../images/chevron-forward-outline.svg' import 'react-h5-audio-player/src/styles.scss' import './styles.scss' -import {Link} from "react-router-dom"; +import { Link } from "react-router-dom"; interface IProps { title?: string @@ -17,16 +17,20 @@ interface IProps { interface IState { index: number + imageLoading: boolean } export default class RecentPodcasts extends React.Component { static defaultProps = {} state = { index: 0, + imageLoading: true } constructor(props: IProps) { super(props) + // fix this in handlers + this.onImageLoad = this.onImageLoad.bind(this) } selectPodcast(index: number, evt) { @@ -35,6 +39,20 @@ export default class RecentPodcasts extends React.Component { this.setState({index}) } + getImage(selectedPodcast) { + return selectedPodcast.image || selectedPodcast.feedImage || NoImage + } + + updateIndex(newIndex: number) { + const {index} = this.state + const {podcasts} = this.props + const imageLoading = this.getImage(podcasts[index]) !== this.getImage(podcasts[newIndex]) + this.setState({ + index: newIndex, + imageLoading: imageLoading, + }) + } + onBack() { const {index} = this.state const {podcasts} = this.props @@ -42,9 +60,7 @@ export default class RecentPodcasts extends React.Component { if (backIndex < 0) { backIndex = podcasts.length - 1 } - this.setState({ - index: backIndex, - }) + this.updateIndex(backIndex) } onForward() { @@ -54,15 +70,20 @@ export default class RecentPodcasts extends React.Component { if (nextIndex >= podcasts.length) { nextIndex = 0 } + this.updateIndex(nextIndex) + } + + onImageLoad() { this.setState({ - index: nextIndex, + imageLoading: false, }) } render() { const {loading, title, podcasts} = this.props - const {index} = this.state + const {index, imageLoading} = this.state const selectedPodcast = podcasts[index] + const imageLoadingClass = imageLoading ? "image-loading" : "" return (
{loading ? ( @@ -92,13 +113,21 @@ export default class RecentPodcasts extends React.Component { )}
- { - ev.target.src = NoImage - }} - /> + <> + { + ev.target.src = NoImage + this.onImageLoad() + }} + onLoad={this.onImageLoad} + /> + {imageLoading &&
+ +
} +
diff --git a/ui/src/components/RecentPodcasts/styles.scss b/ui/src/components/RecentPodcasts/styles.scss index 3a9889e4..b89cc1e9 100644 --- a/ui/src/components/RecentPodcasts/styles.scss +++ b/ui/src/components/RecentPodcasts/styles.scss @@ -118,13 +118,28 @@ flex-direction: column; align-items: center; justify-content: center; - // padding: 25px 25px 0 25px; + img { width: 450px; height: 450px; object-fit: contain; border-radius: 14px; border: 1px solid var(--player-cover-art-border-color); + + &.image-loading { + height: 0; + position: absolute; + } + } + .image-loading-placeholder { + width: 450px; + height: 450px; + display: grid; + align-items: center; + + div { + justify-self: center; + } } z-index: 99999; } @@ -160,7 +175,10 @@ width: 275px; height: 275px; border-radius: 10px; - border: 1px solid lighten(#d6d6d6, 0.2); + } + .image-loading-placeholder { + width: 275px; + height: 275px; } } } From fbfb2a995b418450cfb956ed88d11b52d2c6e1ec Mon Sep 17 00:00:00 2001 From: Steven Crader Date: Sat, 15 Apr 2023 23:38:08 -0700 Subject: [PATCH 4/5] Add button to toggle theme between light and dark --- ui/images/dark_mode.svg | 1 + ui/images/light_mode.svg | 1 + ui/src/components/Button/styles.scss | 4 +- ui/src/components/EpisodeItem/styles.scss | 4 +- ui/src/components/KPI/styles.scss | 4 +- ui/src/components/Player/styles.scss | 14 +- ui/src/components/PodcastHeader/styles.scss | 4 +- ui/src/components/RecentPodcasts/styles.scss | 4 +- ui/src/components/ResultItem/styles.scss | 4 +- ui/src/components/SearchBar/styles.scss | 4 +- ui/src/components/ThemeButton/index.tsx | 140 ++++++++++++++++++ ui/src/components/ThemeButton/styles.scss | 21 +++ ui/src/index.tsx | 2 + ui/src/pages/AddFeed/styles.scss | 4 +- .../Apps/AppsWebPart/FilterTags/styles.scss | 4 +- .../Apps/AppsWebPart/SingleApp/styles.scss | 4 +- ui/src/pages/Podcast/Value4Value/styles.scss | 4 +- .../pages/Stats/NewFeedStatsCard/styles.scss | 4 +- ui/src/pages/Stats/StatsCard/styles.scss | 4 +- ui/src/styles.scss | 5 +- 20 files changed, 187 insertions(+), 49 deletions(-) create mode 100644 ui/images/dark_mode.svg create mode 100644 ui/images/light_mode.svg create mode 100644 ui/src/components/ThemeButton/index.tsx create mode 100644 ui/src/components/ThemeButton/styles.scss diff --git a/ui/images/dark_mode.svg b/ui/images/dark_mode.svg new file mode 100644 index 00000000..e83e1125 --- /dev/null +++ b/ui/images/dark_mode.svg @@ -0,0 +1 @@ + diff --git a/ui/images/light_mode.svg b/ui/images/light_mode.svg new file mode 100644 index 00000000..6eda6ed9 --- /dev/null +++ b/ui/images/light_mode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/src/components/Button/styles.scss b/ui/src/components/Button/styles.scss index 5808b0e2..3f8768ef 100644 --- a/ui/src/components/Button/styles.scss +++ b/ui/src/components/Button/styles.scss @@ -1,10 +1,8 @@ :root { --button-background: #F0F0F0; --button-hover-color: #f2f2f2; -} -@media (prefers-color-scheme: dark) { - :root { + &[data-theme="dark"] { --button-background: #1a1a1a; --button-hover-color: #302d2d; } diff --git a/ui/src/components/EpisodeItem/styles.scss b/ui/src/components/EpisodeItem/styles.scss index 784e6003..7f34a7b1 100644 --- a/ui/src/components/EpisodeItem/styles.scss +++ b/ui/src/components/EpisodeItem/styles.scss @@ -2,10 +2,8 @@ --bg-color: #ffffff; --border-color: #d6d6d6; --cover-art-border-color: lighten(#d6d6d6, 0.2); -} -@media (prefers-color-scheme: dark) { - :root { + &[data-theme="dark"] { --bg-color: #180e0e; --border-color: #505050; --cover-art-border-color: var(--border-color); diff --git a/ui/src/components/KPI/styles.scss b/ui/src/components/KPI/styles.scss index f2a4db31..f0c806ed 100644 --- a/ui/src/components/KPI/styles.scss +++ b/ui/src/components/KPI/styles.scss @@ -1,9 +1,7 @@ :root { --kpi-title-color: #494949; -} -@media (prefers-color-scheme: dark) { - :root { + &[data-theme="dark"] { --kpi-title-color: #cdcdcd; } } diff --git a/ui/src/components/Player/styles.scss b/ui/src/components/Player/styles.scss index 4ee5d0f8..4947cd2b 100644 --- a/ui/src/components/Player/styles.scss +++ b/ui/src/components/Player/styles.scss @@ -77,13 +77,13 @@ } } } - @media (prefers-color-scheme: dark) { - .rhap_container { - background-color: var(--bg-main); - } - .rhap_time { - color: var(--fg-main); - } +} +:root[data-theme="dark"] { + .rhap_container { + background-color: var(--bg-main); + } + .rhap_time { + color: var(--fg-main); } } diff --git a/ui/src/components/PodcastHeader/styles.scss b/ui/src/components/PodcastHeader/styles.scss index b311f378..d11b8897 100644 --- a/ui/src/components/PodcastHeader/styles.scss +++ b/ui/src/components/PodcastHeader/styles.scss @@ -2,10 +2,8 @@ --category-bg-color: #f3f3f3; --category-border-color: #cecece; --cover-art-border-color: lighten(#d6d6d6, 0.2); -} -@media (prefers-color-scheme: dark) { - :root { + &[data-theme="dark"] { --category-bg-color: #302d2d; --category-border-color: #505050; --cover-art-border-color: var(--border-color); diff --git a/ui/src/components/RecentPodcasts/styles.scss b/ui/src/components/RecentPodcasts/styles.scss index b89cc1e9..37a8d143 100644 --- a/ui/src/components/RecentPodcasts/styles.scss +++ b/ui/src/components/RecentPodcasts/styles.scss @@ -2,10 +2,8 @@ --player-bg-color: #ffffff; --player-border-color: #d6d6d6; --player-cover-art-border-color: lighten(#d6d6d6, 0.2); -} -@media (prefers-color-scheme: dark) { - :root { + &[data-theme="dark"] { --player-bg-color: var(--bg-main); --player-border-color: #302d2d; --player-cover-art-border-color: darken(#302d2d, 0.2); diff --git a/ui/src/components/ResultItem/styles.scss b/ui/src/components/ResultItem/styles.scss index eeb4a5bc..dbaedd69 100644 --- a/ui/src/components/ResultItem/styles.scss +++ b/ui/src/components/ResultItem/styles.scss @@ -4,10 +4,8 @@ --category-bg-color: #f3f3f3; --category-border-color: #cecece; --cover-art-border-color: lighten(#d6d6d6, 0.2); -} -@media (prefers-color-scheme: dark) { - :root { + &[data-theme="dark"] { --bg-color: #180e0e; --border-color: #505050; --category-bg-color: #302d2d; diff --git a/ui/src/components/SearchBar/styles.scss b/ui/src/components/SearchBar/styles.scss index 9885549f..e095e7a5 100644 --- a/ui/src/components/SearchBar/styles.scss +++ b/ui/src/components/SearchBar/styles.scss @@ -2,10 +2,8 @@ --input-bg-color: #f7f7f7; --input-border-color: #d6d6d6; --input-placeholder-color: #b6b6b6; -} -@media (prefers-color-scheme: dark) { - :root { + &[data-theme="dark"] { --input-bg-color: #000000; --input-border-color: #303030; --input-placeholder-color: #969696; diff --git a/ui/src/components/ThemeButton/index.tsx b/ui/src/components/ThemeButton/index.tsx new file mode 100644 index 00000000..e6fda17c --- /dev/null +++ b/ui/src/components/ThemeButton/index.tsx @@ -0,0 +1,140 @@ +/** + * Display button for toggling stream sync on/off + */ +import React, {ReactNode} from "react" +import DarkImage from "../../../images/dark_mode.svg" +import LightImage from "../../../images/light_mode.svg" + +import "./styles.scss" + +/** + * Theme options + */ +export enum Theme { + /** + * Use light theme + */ + light = "light", + /** + * Use dark theme + */ + dark = "dark", + /** + * Automatically detect theme + */ + auto = "auto", +} + +/** + * Arguments/properties of ThemeButton + */ +interface ThemeButtonProps { +} + +/** + * States for ThemeButton + */ +interface ThemeButtonState { + /** + * Current theme + */ + theme: Theme, +} + +export default class ThemeButton extends React.PureComponent { + STORAGE_KEY = "theme" + defaultState: ThemeButtonState = { + theme: Theme.auto, + } + state: ThemeButtonState = { + theme: Theme.auto, + } + + constructor(props) { + super(props) + + this.handleClick = this.handleClick.bind(this) + } + + componentDidMount(): void { + let {theme} = this.state + const storageTheme = localStorage.getItem(this.STORAGE_KEY) + let auto = true + + if (storageTheme) { + theme = storageTheme as Theme + } + + // check for auto theme + if (theme === Theme.auto) { + // detect + if (window.matchMedia) { + theme = window.matchMedia('(prefers-color-scheme: light)').matches ? Theme.light : Theme.dark + } else { + // can't detect + theme = Theme.dark + auto = false + } + } else { + auto = false + } + + this.setState( + { + theme: theme, + }, + () => { + document.documentElement.setAttribute("data-theme", theme) + localStorage.setItem(this.STORAGE_KEY, auto ? Theme.auto : theme) + } + ) + } + + /** + * Handle sync button onClick event + */ + private readonly handleClick = (): void => { + const {theme} = this.state + let newTheme = this.oppositeTheme(theme) + this.setState( + { + theme: newTheme, + }, + () => { + document.documentElement.setAttribute("data-theme", newTheme) + localStorage.setItem(this.STORAGE_KEY, newTheme) + } + ) + } + + /** + * Get the opposite theme + * + * @param theme current theme + * @return Opposite theme + **/ + private oppositeTheme = (theme: Theme): Theme => { + if (theme == Theme.auto) + return theme + return theme === Theme.dark ? Theme.light : Theme.dark + } + + render = (): ReactNode => { + const {theme} = this.state + + const lightMode = theme === Theme.light + const image = lightMode ? LightImage : DarkImage + const altText = lightMode ? "Switch to Dark Mode" : "Switch to Light Mode" + return ( +
+ {altText} +
+ ) + } +} diff --git a/ui/src/components/ThemeButton/styles.scss b/ui/src/components/ThemeButton/styles.scss new file mode 100644 index 00000000..09268dac --- /dev/null +++ b/ui/src/components/ThemeButton/styles.scss @@ -0,0 +1,21 @@ +.theme-button { + width: 20px; + height: 20px; + + position: fixed; + right: 15px; + bottom: 15px; + + text-align: center; + z-index: 99999; + + &:hover { + cursor: grab; + } + + img { + width: 100%; + height: 100%; + background: inherit; + } +} diff --git a/ui/src/index.tsx b/ui/src/index.tsx index b44e5ca8..a09737b8 100644 --- a/ui/src/index.tsx +++ b/ui/src/index.tsx @@ -1,5 +1,6 @@ import * as React from 'react' import * as ReactDOM from 'react-dom' +import ThemeButton from "./components/ThemeButton"; import store, { history } from './state/store' import { Provider } from 'react-redux' import { ConnectedRouter } from 'connected-react-router' @@ -34,6 +35,7 @@ const Index: React.FC = ({ store, history }) => { alt="Sidebar logo" /> + ) diff --git a/ui/src/pages/AddFeed/styles.scss b/ui/src/pages/AddFeed/styles.scss index 8b6953c7..5bd3402d 100644 --- a/ui/src/pages/AddFeed/styles.scss +++ b/ui/src/pages/AddFeed/styles.scss @@ -2,10 +2,8 @@ --input-bg-color: #f7f7f7; --input-border-color: #d6d6d6; --input-placeholder-color: #b6b6b6; -} -@media (prefers-color-scheme: dark) { - :root { + &[data-theme="dark"] { --input-bg-color: #000000; --input-border-color: #303030; --input-placeholder-color: #969696; diff --git a/ui/src/pages/Apps/AppsWebPart/FilterTags/styles.scss b/ui/src/pages/Apps/AppsWebPart/FilterTags/styles.scss index a1cb55b6..3ffcf38e 100644 --- a/ui/src/pages/Apps/AppsWebPart/FilterTags/styles.scss +++ b/ui/src/pages/Apps/AppsWebPart/FilterTags/styles.scss @@ -1,10 +1,8 @@ :root { --inactive-button-color: #c7c7c7; --inactive-button-hover-color: #b3b2b2; -} -@media (prefers-color-scheme: dark) { - :root { + &[data-theme="dark"] { --inactive-button-color: #808080; --inactive-button-hover-color: #505050; } diff --git a/ui/src/pages/Apps/AppsWebPart/SingleApp/styles.scss b/ui/src/pages/Apps/AppsWebPart/SingleApp/styles.scss index da334766..d28d7317 100644 --- a/ui/src/pages/Apps/AppsWebPart/SingleApp/styles.scss +++ b/ui/src/pages/Apps/AppsWebPart/SingleApp/styles.scss @@ -1,9 +1,7 @@ :root { --dimmed-color: #333; -} -@media (prefers-color-scheme: dark) { - :root { + &[data-theme="dark"] { --dimmed-color: #808080; } } diff --git a/ui/src/pages/Podcast/Value4Value/styles.scss b/ui/src/pages/Podcast/Value4Value/styles.scss index 1f788643..71c07dc4 100644 --- a/ui/src/pages/Podcast/Value4Value/styles.scss +++ b/ui/src/pages/Podcast/Value4Value/styles.scss @@ -1,9 +1,7 @@ :root { --selected-page-color: #f2f2f2; -} -@media (prefers-color-scheme: dark) { - :root { + &[data-theme="dark"] { --selected-page-color: #505050; } } diff --git a/ui/src/pages/Stats/NewFeedStatsCard/styles.scss b/ui/src/pages/Stats/NewFeedStatsCard/styles.scss index 0c9dd5c5..07d3dc8a 100644 --- a/ui/src/pages/Stats/NewFeedStatsCard/styles.scss +++ b/ui/src/pages/Stats/NewFeedStatsCard/styles.scss @@ -1,9 +1,7 @@ :root { --kpi-bg-color: #f3f3f3; -} -@media (prefers-color-scheme: dark) { - :root { + &[data-theme="dark"] { --kpi-bg-color: #302d2d; } } diff --git a/ui/src/pages/Stats/StatsCard/styles.scss b/ui/src/pages/Stats/StatsCard/styles.scss index 4037a31e..27d9cd4a 100644 --- a/ui/src/pages/Stats/StatsCard/styles.scss +++ b/ui/src/pages/Stats/StatsCard/styles.scss @@ -1,9 +1,7 @@ :root { --bg-color: #ffffff; -} -@media (prefers-color-scheme: dark) { - :root { + &[data-theme="dark"] { --bg-color: #180e0e; } } diff --git a/ui/src/styles.scss b/ui/src/styles.scss index 6f2ff616..f87e9961 100644 --- a/ui/src/styles.scss +++ b/ui/src/styles.scss @@ -40,9 +40,8 @@ --font-family-exp: D-DINExp, sans-serif; --font-family-exp-bold: D-DINExp-Bold, sans-serif; --font-alt: DINAlternate-Bold, sans-serif; -} -@media (prefers-color-scheme: dark) { - :root { + + &[data-theme="dark"] { --bg-main: #080808; --fg-main: #f1f1f1; --text-color: #d9d9d9; From 69498079c3ae8eef576e5a9ace87c47c8e04f73c Mon Sep 17 00:00:00 2001 From: Steven Crader Date: Sat, 15 Apr 2023 23:54:15 -0700 Subject: [PATCH 5/5] Add support to close menu list on mobile if clicking outside of menu open button --- ui/src/components/TopBar/index.tsx | 31 +++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/ui/src/components/TopBar/index.tsx b/ui/src/components/TopBar/index.tsx index 928eb3e0..e8c1740e 100644 --- a/ui/src/components/TopBar/index.tsx +++ b/ui/src/components/TopBar/index.tsx @@ -23,6 +23,7 @@ interface IState { export default class TopBar extends React.PureComponent { static defaultProps = {} + wrapperRef: React.Ref = React.createRef(); constructor(props: IProps) { super(props) @@ -34,11 +35,34 @@ export default class TopBar extends React.PureComponent { this.onSearchChange = this.onSearchChange.bind(this) this.onSearchSubmit = this.onSearchSubmit.bind(this) + this.handleClickOutside = this.handleClickOutside.bind(this); + } + + componentDidMount() { + document.addEventListener("mousedown", this.handleClickOutside); + } + + componentWillUnmount() { + document.removeEventListener("mousedown", this.handleClickOutside); } onSearchChange(evt: React.ChangeEvent) { evt.preventDefault() - this.setState({ search: evt.target.value }) + this.setState({search: evt.target.value}) + } + + /** + * Alert if clicked on outside of element + */ + handleClickOutside(event) { + // @ts-ignore + if (this.wrapperRef && !this.wrapperRef.current.contains(event.target)) { + setTimeout(() => { + this.setState({ + dropdownOpen: false, + }) + }, 100) + } } onSearchSubmit(evt: React.ChangeEvent) { @@ -54,7 +78,7 @@ export default class TopBar extends React.PureComponent { } render() { - const { search, dropdownOpen } = this.state + const {search, dropdownOpen} = this.state return (