From e7482e8fe6e487d4d7fdb4beb1c687a8a99f7150 Mon Sep 17 00:00:00 2001 From: alexsparkes Date: Wed, 29 May 2024 16:44:40 +0100 Subject: [PATCH] refactor: weather and app to functional components --- src/App.jsx | 91 ++-- .../weather/options/WeatherOptions.jsx | 387 +++++++++--------- 2 files changed, 242 insertions(+), 236 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 9ee6cab0..f20d1023 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,56 +1,75 @@ -import variables from 'config/variables'; -import { PureComponent } from 'react'; +import { useEffect, useState } from 'react'; import { ToastContainer } from 'react-toastify'; - import Background from 'features/background/Background'; import Widgets from 'features/misc/views/Widgets'; import Modals from 'features/misc/modals/Modals'; - import { loadSettings, moveSettings } from 'utils/settings'; - import EventBus from 'utils/eventbus'; +import variables from 'config/variables'; -export default class App extends PureComponent { - componentDidMount() { - // 4.0 -> 5.0 (the key below is only on 5.0) - // now featuring 5.0 -> 5.1 - // the firstRun check was moved here because the old function was useless - if (!localStorage.getItem('firstRun') || !localStorage.getItem('stats')) { +const useAppSetup = () => { + useEffect(() => { + const firstRun = localStorage.getItem('firstRun'); + const stats = localStorage.getItem('stats'); + + if (!firstRun || !stats) { moveSettings(); window.location.reload(); } loadSettings(); - EventBus.on('refresh', (data) => { + const refreshHandler = (data) => { if (data === 'other') { loadSettings(true); } - }); + }; + + EventBus.on('refresh', refreshHandler); variables.stats.tabLoad(); - } - componentWillUnmount() { - EventBus.off('refresh'); - } + return () => { + EventBus.off('refresh', refreshHandler); + }; + }, []); +}; - render() { - return ( - <> - {localStorage.getItem('background') === 'true' && } - -
- - -
- - ); - } -} +const App = () => { + const [toastDisplayTime, setToastDisplayTime] = useState(2500); + const [showBackground, setShowBackground] = useState(false); + + useEffect(() => { + const storedToastDisplayTime = localStorage.getItem('toastDisplayTime'); + const storedBackground = localStorage.getItem('background'); + + if (storedToastDisplayTime) { + setToastDisplayTime(parseInt(storedToastDisplayTime, 10)); + } + + if (storedBackground === 'true') { + setShowBackground(true); + } + }, []); + + useAppSetup(); + + return ( + <> + {showBackground && } + +
+ + +
+ + ); +}; + +export default App; diff --git a/src/features/weather/options/WeatherOptions.jsx b/src/features/weather/options/WeatherOptions.jsx index f6c3bb73..ca4205f6 100644 --- a/src/features/weather/options/WeatherOptions.jsx +++ b/src/features/weather/options/WeatherOptions.jsx @@ -1,224 +1,211 @@ -import variables from 'config/variables'; -import { PureComponent } from 'react'; - +import { useState, useEffect, useCallback } from 'react'; import { MdAutoAwesome } from 'react-icons/md'; - import { Header, Row, Content, Action, PreferencesWrapper } from 'components/Layout/Settings'; import { Radio, Dropdown, Checkbox } from 'components/Form/Settings'; import { TextField } from '@mui/material'; +import variables from 'config/variables'; -class WeatherOptions extends PureComponent { - constructor() { - super(); - this.state = { - location: localStorage.getItem('location') || '', - windSpeed: localStorage.getItem('windspeed') !== 'true', - }; - } +const useLocalStorageState = (key, initialValue) => { + const [state, setState] = useState(() => localStorage.getItem(key) || initialValue); - componentDidUpdate() { - localStorage.setItem('location', this.state.location); - } + useEffect(() => { + localStorage.setItem(key, state); + }, [key, state]); - showReminder() { + return [state, setState]; +}; + +const useWeatherSettings = () => { + const [location, setLocation] = useLocalStorageState('location', ''); + const [windSpeed, setWindSpeed] = useLocalStorageState('windspeed', 'true'); + + const showReminder = useCallback(() => { document.querySelector('.reminder-info').style.display = 'flex'; localStorage.setItem('showReminder', true); - } + }, []); - changeLocation(e) { + const changeLocation = (e) => { localStorage.removeItem('currentWeather'); - this.setState({ - location: e.target.value, - }); + setLocation(e.target.value); + showReminder(); + }; - this.showReminder(); - } + const getAutoLocation = useCallback(() => { + setLocation(variables.getMessage('modals.main.loading')); - render() { - const weatherType = localStorage.getItem('weatherType'); - const WEATHER_SECTION = 'modals.main.settings.sections.weather'; + navigator.geolocation.getCurrentPosition( + async (position) => { + const data = await ( + await fetch( + `${variables.constants.API_URL}/gps?latitude=${position.coords.latitude}&longitude=${position.coords.longitude}` + ) + ).json(); + setLocation(data[0].name); + showReminder(); + }, + (error) => { + console.error(error); + }, + { + enableHighAccuracy: true, + } + ); + }, [setLocation, showReminder]); - const WidgetType = () => { - return ( - - - - this.forceUpdate()} - items={[ - { value: '1', text: variables.getMessage(`${WEATHER_SECTION}.options.basic`) }, - { - value: '2', - text: variables.getMessage(`${WEATHER_SECTION}.options.standard`), - }, - { - value: '3', - text: variables.getMessage(`${WEATHER_SECTION}.options.expanded`), - }, - { value: '4', text: variables.getMessage(`${WEATHER_SECTION}.options.custom`) }, - ]} - /> - - - ); - }; + return { + location, + windSpeed: windSpeed !== 'true', + setWindSpeed, + changeLocation, + getAutoLocation, + }; +}; - const LocationSetting = () => { - const getAuto = () => { - this.setState({ - location: variables.getMessage('modals.main.loading'), - }); +const WeatherOptions = () => { + const { location, windSpeed, setWindSpeed, changeLocation, getAutoLocation } = useWeatherSettings(); + const weatherType = localStorage.getItem('weatherType'); + const WEATHER_SECTION = 'modals.main.settings.sections.weather'; - navigator.geolocation.getCurrentPosition( - async (position) => { - const data = await ( - await fetch( - `${variables.constants.API_URL}/gps?latitude=${position.coords.latitude}&longitude=${position.coords.longitude}`, - ) - ).json(); - this.setState({ - location: data[0].name, - }); + const WidgetType = () => ( + + + + this.forceUpdate()} + items={[ + { value: '1', text: variables.getMessage(`${WEATHER_SECTION}.options.basic`) }, + { value: '2', text: variables.getMessage(`${WEATHER_SECTION}.options.standard`) }, + { value: '3', text: variables.getMessage(`${WEATHER_SECTION}.options.expanded`) }, + { value: '4', text: variables.getMessage(`${WEATHER_SECTION}.options.custom`) }, + ]} + /> + + + ); - this.showReminder(); - }, - (error) => { - // firefox requires this 2nd function - console.error(error); - }, - { - enableHighAccuracy: true, - }, - ); - }; - return ( - - - - this.changeLocation(e)} - placeholder="London" - varient="outlined" - InputLabelProps={{ shrink: true }} - /> - - - {variables.getMessage(`${WEATHER_SECTION}.auto`)} - - - - ); - }; + const LocationSetting = () => ( + + + + + + + {variables.getMessage(`${WEATHER_SECTION}.auto`)} + + + + ); - const TemperatureFormat = () => { - return ( - - - - - - - ); - }; + const TemperatureFormat = () => ( + + + + + + + ); - const CustomOptions = () => { - const weatherOptions = [ - { - name: 'weatherdescription', - textKey: `${WEATHER_SECTION}.extra_info.show_description`, - }, - { - name: 'cloudiness', - textKey: `${WEATHER_SECTION}.extra_info.cloudiness`, - }, - { name: 'humidity', textKey: `${WEATHER_SECTION}.extra_info.humidity` }, - { - name: 'visibility', - textKey: `${WEATHER_SECTION}.extra_info.visibility`, - }, - { - name: 'windspeed', - textKey: `${WEATHER_SECTION}.extra_info.wind_speed`, - onChange: () => - this.setState({ windSpeed: localStorage.getItem('windspeed') !== 'true' }), - }, - { - name: 'windDirection', - textKey: `${WEATHER_SECTION}.extra_info.wind_direction`, - disabled: this.state.windSpeed, - }, - { - name: 'atmosphericpressure', - textKey: `${WEATHER_SECTION}.extra_info.atmospheric_pressure`, - }, - ]; - - return ( - - - - {weatherOptions.map((item) => ( - - ))} - - - ); - }; + const CustomOptions = () => { + const weatherOptions = [ + { + name: 'weatherdescription', + textKey: `${WEATHER_SECTION}.extra_info.show_description`, + }, + { + name: 'cloudiness', + textKey: `${WEATHER_SECTION}.extra_info.cloudiness`, + }, + { name: 'humidity', textKey: `${WEATHER_SECTION}.extra_info.humidity` }, + { + name: 'visibility', + textKey: `${WEATHER_SECTION}.extra_info.visibility`, + }, + { + name: 'windspeed', + textKey: `${WEATHER_SECTION}.extra_info.wind_speed`, + onChange: () => setWindSpeed(localStorage.getItem('windspeed') !== 'true'), + }, + { + name: 'windDirection', + textKey: `${WEATHER_SECTION}.extra_info.wind_direction`, + disabled: windSpeed, + }, + { + name: 'atmosphericpressure', + textKey: `${WEATHER_SECTION}.extra_info.atmospheric_pressure`, + }, + ]; return ( - <> -
- - - {/* https://stackoverflow.com/a/65328486 when using inputs it may defocus so we do the {} instead of <> */} - {LocationSetting()} - - {weatherType === '4' && } - - + + + + {weatherOptions.map((item) => ( + + ))} + + ); - } -} + }; + + return ( + <> +
+ + + {/* https://stackoverflow.com/a/65328486 when using inputs it may defocus so we do the {} instead of <> */} + {LocationSetting()} + + {weatherType === '4' && } + + + ); +}; export { WeatherOptions as default, WeatherOptions };