From 426766225b8e46e4da2dd60f470f3bf87b1c2027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Malak?= Date: Thu, 18 Nov 2021 13:05:32 +0100 Subject: [PATCH 1/9] Fixed bug with custom icons not working with apps --- CHANGELOG.md | 3 +++ README.md | 2 +- controllers/apps/createApp.js | 21 ++++++++------------- controllers/apps/updateApp.js | 10 +++++----- controllers/bookmarks/createBookmark.js | 10 +++++----- controllers/bookmarks/updateBookmark.js | 10 +++++----- controllers/categories/createCategory.js | 14 ++++---------- 7 files changed, 31 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b755d2..9f66a48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### v2.0.1 (TBA) +- Fixed bug with custom icons not working with apps when "pin by default" was disabled + ### v2.0.0 (2021-11-15) - Added authentication system: - Only logged in user can access settings ([#33](https://github.com/pawelmalak/flame/issues/33)) diff --git a/README.md b/README.md index 6995444..a53474e 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Flame is self-hosted startpage for your server. Its design is inspired (heavily) - 📌 Pin your favourite items to the homescreen for quick and easy access - 🔍 Integrated search bar with local filtering, 11 web search providers and ability to add your own - 🔑 Authentication system to protect your settings, apps and bookmarks -- 🔨 Dozens of option to customize Flame interface to your needs, including support for custom CSS and 15 built-in color themes +- 🔨 Dozens of options to customize Flame interface to your needs, including support for custom CSS and 15 built-in color themes - ☀️ Weather widget with current temperature, cloud coverage and animated weather status - 🐳 Docker integration to automatically pick and add apps based on their labels diff --git a/controllers/apps/createApp.js b/controllers/apps/createApp.js index a8208fa..4e0c887 100644 --- a/controllers/apps/createApp.js +++ b/controllers/apps/createApp.js @@ -8,25 +8,20 @@ const loadConfig = require('../../utils/loadConfig'); const createApp = asyncWrapper(async (req, res, next) => { const { pinAppsByDefault } = await loadConfig(); - let app; - let _body = { ...req.body }; + let body = { ...req.body }; - if (_body.icon) { - _body.icon = _body.icon.trim(); + if (body.icon) { + body.icon = body.icon.trim(); } if (req.file) { - _body.icon = req.file.filename; + body.icon = req.file.filename; } - if (pinAppsByDefault) { - app = await App.create({ - ..._body, - isPinned: true, - }); - } else { - app = await App.create(req.body); - } + const app = await App.create({ + ...body, + isPinned: pinAppsByDefault, + }); res.status(201).json({ success: true, diff --git a/controllers/apps/updateApp.js b/controllers/apps/updateApp.js index 290e4ef..cc626e4 100644 --- a/controllers/apps/updateApp.js +++ b/controllers/apps/updateApp.js @@ -18,17 +18,17 @@ const updateApp = asyncWrapper(async (req, res, next) => { ); } - let _body = { ...req.body }; + let body = { ...req.body }; - if (_body.icon) { - _body.icon = _body.icon.trim(); + if (body.icon) { + body.icon = body.icon.trim(); } if (req.file) { - _body.icon = req.file.filename; + body.icon = req.file.filename; } - app = await app.update(_body); + app = await app.update(body); res.status(200).json({ success: true, diff --git a/controllers/bookmarks/createBookmark.js b/controllers/bookmarks/createBookmark.js index 7bf6a01..4b5fb18 100644 --- a/controllers/bookmarks/createBookmark.js +++ b/controllers/bookmarks/createBookmark.js @@ -7,20 +7,20 @@ const Bookmark = require('../../models/Bookmark'); const createBookmark = asyncWrapper(async (req, res, next) => { let bookmark; - let _body = { + let body = { ...req.body, categoryId: parseInt(req.body.categoryId), }; - if (_body.icon) { - _body.icon = _body.icon.trim(); + if (body.icon) { + body.icon = body.icon.trim(); } if (req.file) { - _body.icon = req.file.filename; + body.icon = req.file.filename; } - bookmark = await Bookmark.create(_body); + bookmark = await Bookmark.create(body); res.status(201).json({ success: true, diff --git a/controllers/bookmarks/updateBookmark.js b/controllers/bookmarks/updateBookmark.js index 2899364..448b16c 100644 --- a/controllers/bookmarks/updateBookmark.js +++ b/controllers/bookmarks/updateBookmark.js @@ -19,20 +19,20 @@ const updateBookmark = asyncWrapper(async (req, res, next) => { ); } - let _body = { + let body = { ...req.body, categoryId: parseInt(req.body.categoryId), }; - if (_body.icon) { - _body.icon = _body.icon.trim(); + if (body.icon) { + body.icon = body.icon.trim(); } if (req.file) { - _body.icon = req.file.filename; + body.icon = req.file.filename; } - bookmark = await bookmark.update(_body); + bookmark = await bookmark.update(body); res.status(200).json({ success: true, diff --git a/controllers/categories/createCategory.js b/controllers/categories/createCategory.js index f25b57f..ada5645 100644 --- a/controllers/categories/createCategory.js +++ b/controllers/categories/createCategory.js @@ -8,16 +8,10 @@ const loadConfig = require('../../utils/loadConfig'); const createCategory = asyncWrapper(async (req, res, next) => { const { pinCategoriesByDefault: pinCategories } = await loadConfig(); - let category; - - if (pinCategories) { - category = await Category.create({ - ...req.body, - isPinned: true, - }); - } else { - category = await Category.create(req.body); - } + const category = await Category.create({ + ...req.body, + isPinned: pinCategories, + }); res.status(201).json({ success: true, From e2285e2deb8d554193a3a85a03703459389c2e71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Malak?= Date: Thu, 18 Nov 2021 13:47:27 +0100 Subject: [PATCH 2/9] Moved Themer to Settings. Added option to set default theme --- CHANGELOG.md | 1 + client/src/App.tsx | 22 +++- .../DockerSettings/DockerSettings.tsx | 2 +- .../SearchSettings/SearchSettings.tsx | 2 +- client/src/components/Settings/Settings.tsx | 2 +- .../Themer/ThemePreview.module.css | 3 +- .../{ => Settings}/Themer/ThemePreview.tsx | 2 +- .../{ => Settings}/Themer/Themer.module.css | 0 .../src/components/Settings/Themer/Themer.tsx | 101 ++++++++++++++++++ .../{ => Settings}/Themer/themes.json | 0 client/src/components/Themer/Themer.tsx | 29 ----- client/src/interfaces/Config.ts | 1 + client/src/interfaces/Forms.ts | 4 + client/src/store/action-creators/config.ts | 15 +-- client/src/store/action-creators/theme.ts | 2 +- client/src/types/ConfigFormData.ts | 14 +++ client/src/types/index.ts | 1 + .../utility/templateObjects/configTemplate.ts | 1 + .../templateObjects/settingsTemplate.ts | 5 + utils/init/initialConfig.json | 3 +- 20 files changed, 156 insertions(+), 54 deletions(-) rename client/src/components/{ => Settings}/Themer/ThemePreview.module.css (93%) rename client/src/components/{ => Settings}/Themer/ThemePreview.tsx (94%) rename client/src/components/{ => Settings}/Themer/Themer.module.css (100%) create mode 100644 client/src/components/Settings/Themer/Themer.tsx rename client/src/components/{ => Settings}/Themer/themes.json (100%) delete mode 100644 client/src/components/Themer/Themer.tsx create mode 100644 client/src/types/ConfigFormData.ts create mode 100644 client/src/types/index.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f66a48..940e9dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ ### v2.0.1 (TBA) +- Added option to set default theme for all new users ([#165](https://github.com/pawelmalak/flame/issues/165)) - Fixed bug with custom icons not working with apps when "pin by default" was disabled ### v2.0.0 (2021-11-15) diff --git a/client/src/App.tsx b/client/src/App.tsx index 2e4c72e..d9e8717 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -1,7 +1,13 @@ +import { useEffect } from 'react'; import { BrowserRouter, Route, Switch } from 'react-router-dom'; +import 'external-svg-loader'; + +// Redux +import { useDispatch, useSelector } from 'react-redux'; +import { bindActionCreators } from 'redux'; import { autoLogin, getConfig } from './store/action-creators'; import { actionCreators, store } from './store'; -import 'external-svg-loader'; +import { State } from './store/reducers'; // Utils import { checkVersion, decodeToken } from './utility'; @@ -12,9 +18,6 @@ import { Apps } from './components/Apps/Apps'; import { Settings } from './components/Settings/Settings'; import { Bookmarks } from './components/Bookmarks/Bookmarks'; import { NotificationCenter } from './components/NotificationCenter/NotificationCenter'; -import { useDispatch } from 'react-redux'; -import { bindActionCreators } from 'redux'; -import { useEffect } from 'react'; // Get config store.dispatch(getConfig()); @@ -25,6 +28,8 @@ if (localStorage.token) { } export const App = (): JSX.Element => { + const { config, loading } = useSelector((state: State) => state.config); + const dispath = useDispatch(); const { fetchQueries, setTheme, logout, createNotification } = bindActionCreators(actionCreators, dispath); @@ -46,7 +51,7 @@ export const App = (): JSX.Element => { } }, 1000); - // set theme + // set user theme if present if (localStorage.theme) { setTheme(localStorage.theme); } @@ -60,6 +65,13 @@ export const App = (): JSX.Element => { return () => window.clearInterval(tokenIsValid); }, []); + // If there is no user theme, set the default one + useEffect(() => { + if (!loading && !localStorage.theme) { + setTheme(config.defaultTheme); + } + }, [loading]); + return ( <> diff --git a/client/src/components/Settings/DockerSettings/DockerSettings.tsx b/client/src/components/Settings/DockerSettings/DockerSettings.tsx index 54410d8..d950501 100644 --- a/client/src/components/Settings/DockerSettings/DockerSettings.tsx +++ b/client/src/components/Settings/DockerSettings/DockerSettings.tsx @@ -59,7 +59,7 @@ export const DockerSettings = (): JSX.Element => { {/* CUSTOM DOCKER SOCKET HOST */} - + { > - + inputChangeHandler(e)} + > + {themes.map((theme: Theme, idx) => ( + + ))} + + + + + + )} + + ); +}; diff --git a/client/src/components/Themer/themes.json b/client/src/components/Settings/Themer/themes.json similarity index 100% rename from client/src/components/Themer/themes.json rename to client/src/components/Settings/Themer/themes.json diff --git a/client/src/components/Themer/Themer.tsx b/client/src/components/Themer/Themer.tsx deleted file mode 100644 index 9c53f58..0000000 --- a/client/src/components/Themer/Themer.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { Fragment } from 'react'; -import { useDispatch } from 'react-redux'; -import { bindActionCreators } from 'redux'; -import { actionCreators } from '../../store'; - -import classes from './Themer.module.css'; - -import { themes } from './themes.json'; -import { Theme } from '../../interfaces/Theme'; -import { ThemePreview } from './ThemePreview'; - -export const Themer = (): JSX.Element => { - const dispatch = useDispatch(); - const { setTheme } = bindActionCreators(actionCreators, dispatch); - - return ( - -
-
- {themes.map( - (theme: Theme, idx: number): JSX.Element => ( - - ) - )} -
-
-
- ); -}; diff --git a/client/src/interfaces/Config.ts b/client/src/interfaces/Config.ts index 7302d36..b0e2908 100644 --- a/client/src/interfaces/Config.ts +++ b/client/src/interfaces/Config.ts @@ -25,4 +25,5 @@ export interface Config { daySchema: string; monthSchema: string; showTime: boolean; + defaultTheme: string; } diff --git a/client/src/interfaces/Forms.ts b/client/src/interfaces/Forms.ts index 7272f21..03f8ae7 100644 --- a/client/src/interfaces/Forms.ts +++ b/client/src/interfaces/Forms.ts @@ -35,3 +35,7 @@ export interface DockerSettingsForm { kubernetesApps: boolean; unpinStoppedApps: boolean; } + +export interface ThemeSettingsForm { + defaultTheme: string; +} diff --git a/client/src/store/action-creators/config.ts b/client/src/store/action-creators/config.ts index bcc41e4..079faac 100644 --- a/client/src/store/action-creators/config.ts +++ b/client/src/store/action-creators/config.ts @@ -8,17 +8,10 @@ import { UpdateQueryAction, } from '../actions/config'; import axios from 'axios'; -import { - ApiResponse, - Config, - DockerSettingsForm, - OtherSettingsForm, - Query, - SearchForm, - WeatherForm, -} from '../../interfaces'; +import { ApiResponse, Config, Query } from '../../interfaces'; import { ActionType } from '../action-types'; import { storeUIConfig, applyAuth } from '../../utility'; +import { ConfigFormData } from '../../types'; const keys: (keyof Config)[] = [ 'useAmericanDate', @@ -50,9 +43,7 @@ export const getConfig = () => async (dispatch: Dispatch) => { }; export const updateConfig = - ( - formData: WeatherForm | OtherSettingsForm | SearchForm | DockerSettingsForm - ) => + (formData: ConfigFormData) => async (dispatch: Dispatch) => { try { const res = await axios.put>( diff --git a/client/src/store/action-creators/theme.ts b/client/src/store/action-creators/theme.ts index ba52d27..6209523 100644 --- a/client/src/store/action-creators/theme.ts +++ b/client/src/store/action-creators/theme.ts @@ -2,7 +2,7 @@ import { Dispatch } from 'redux'; import { SetThemeAction } from '../actions/theme'; import { ActionType } from '../action-types'; import { Theme } from '../../interfaces/Theme'; -import { themes } from '../../components/Themer/themes.json'; +import { themes } from '../../components/Settings/Themer/themes.json'; export const setTheme = (name: string) => (dispatch: Dispatch) => { diff --git a/client/src/types/ConfigFormData.ts b/client/src/types/ConfigFormData.ts new file mode 100644 index 0000000..a67d8af --- /dev/null +++ b/client/src/types/ConfigFormData.ts @@ -0,0 +1,14 @@ +import { + DockerSettingsForm, + OtherSettingsForm, + SearchForm, + ThemeSettingsForm, + WeatherForm, +} from '../interfaces'; + +export type ConfigFormData = + | WeatherForm + | SearchForm + | DockerSettingsForm + | OtherSettingsForm + | ThemeSettingsForm; diff --git a/client/src/types/index.ts b/client/src/types/index.ts new file mode 100644 index 0000000..ad5b423 --- /dev/null +++ b/client/src/types/index.ts @@ -0,0 +1 @@ +export * from './ConfigFormData'; diff --git a/client/src/utility/templateObjects/configTemplate.ts b/client/src/utility/templateObjects/configTemplate.ts index 6f51305..5cb34e9 100644 --- a/client/src/utility/templateObjects/configTemplate.ts +++ b/client/src/utility/templateObjects/configTemplate.ts @@ -28,4 +28,5 @@ export const configTemplate: Config = { monthSchema: 'January;February;March;April;May;June;July;August;September;October;November;December', showTime: false, + defaultTheme: 'tron', }; diff --git a/client/src/utility/templateObjects/settingsTemplate.ts b/client/src/utility/templateObjects/settingsTemplate.ts index f175318..06afd9e 100644 --- a/client/src/utility/templateObjects/settingsTemplate.ts +++ b/client/src/utility/templateObjects/settingsTemplate.ts @@ -2,6 +2,7 @@ import { DockerSettingsForm, OtherSettingsForm, SearchForm, + ThemeSettingsForm, WeatherForm, } from '../../interfaces'; @@ -43,3 +44,7 @@ export const dockerSettingsTemplate: DockerSettingsForm = { kubernetesApps: true, unpinStoppedApps: true, }; + +export const themeSettingsTemplate: ThemeSettingsForm = { + defaultTheme: 'tron', +}; diff --git a/utils/init/initialConfig.json b/utils/init/initialConfig.json index 8f9b2f8..c815d11 100644 --- a/utils/init/initialConfig.json +++ b/utils/init/initialConfig.json @@ -24,5 +24,6 @@ "greetingsSchema": "Good evening!;Good afternoon!;Good morning!;Good night!", "daySchema": "Sunday;Monday;Tuesday;Wednesday;Thursday;Friday;Saturday", "monthSchema": "January;February;March;April;May;June;July;August;September;October;November;December", - "showTime": false + "showTime": false, + "defaultTheme": "tron" } From a5491494525d25ee85a1588575ccec71e6cd74eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Malak?= Date: Thu, 18 Nov 2021 14:16:57 +0100 Subject: [PATCH 3/9] Database migration to support more weather properties --- db/migrations/03_weather.js | 35 +++++++++++++++++++++++++++++++++++ models/Weather.js | 31 +++++++++++++++++++------------ utils/getExternalWeather.js | 3 +++ utils/init/initialConfig.json | 4 +++- 4 files changed, 60 insertions(+), 13 deletions(-) create mode 100644 db/migrations/03_weather.js diff --git a/db/migrations/03_weather.js b/db/migrations/03_weather.js new file mode 100644 index 0000000..bba45df --- /dev/null +++ b/db/migrations/03_weather.js @@ -0,0 +1,35 @@ +const { DataTypes } = require('sequelize'); +const { INTEGER, FLOAT } = DataTypes; +const loadConfig = require('../../utils/loadConfig'); +const getExternalWeather = require('../../utils/getExternalWeather'); + +const up = async (query) => { + await query.addColumn('weather', 'humidity', { + type: INTEGER, + }); + + await query.addColumn('weather', 'windK', { + type: FLOAT, + }); + + await query.addColumn('weather', 'windM', { + type: FLOAT, + }); + + const { WEATHER_API_KEY: secret } = await loadConfig(); + + if (secret) { + await getExternalWeather(); + } +}; + +const down = async (query) => { + await query.removeColumn('weather', 'humidity'); + await query.removeColumn('weather', 'windK'); + await query.removeColumn('weather', 'windM'); +}; + +module.exports = { + up, + down, +}; diff --git a/models/Weather.js b/models/Weather.js index c85c29f..2ac7961 100644 --- a/models/Weather.js +++ b/models/Weather.js @@ -1,16 +1,23 @@ const { DataTypes } = require('sequelize'); const { sequelize } = require('../db'); -const Weather = sequelize.define('Weather', { - externalLastUpdate: DataTypes.STRING, - tempC: DataTypes.FLOAT, - tempF: DataTypes.FLOAT, - isDay: DataTypes.INTEGER, - cloud: DataTypes.INTEGER, - conditionText: DataTypes.TEXT, - conditionCode: DataTypes.INTEGER -}, { - tableName: 'weather' -}); +const Weather = sequelize.define( + 'Weather', + { + externalLastUpdate: DataTypes.STRING, + tempC: DataTypes.FLOAT, + tempF: DataTypes.FLOAT, + isDay: DataTypes.INTEGER, + cloud: DataTypes.INTEGER, + conditionText: DataTypes.TEXT, + conditionCode: DataTypes.INTEGER, + humidity: DataTypes.INTEGER, + windK: DataTypes.FLOAT, + windM: DataTypes.FLOAT, + }, + { + tableName: 'weather', + } +); -module.exports = Weather; \ No newline at end of file +module.exports = Weather; diff --git a/utils/getExternalWeather.js b/utils/getExternalWeather.js index 20edac4..8171807 100644 --- a/utils/getExternalWeather.js +++ b/utils/getExternalWeather.js @@ -21,6 +21,9 @@ const getExternalWeather = async () => { cloud: cursor.cloud, conditionText: cursor.condition.text, conditionCode: cursor.condition.code, + humidity: cursor.humidity, + windK: cursor.wind_kph, + windM: cursor.wind_mph, }); return weatherData; } catch (err) { diff --git a/utils/init/initialConfig.json b/utils/init/initialConfig.json index c815d11..897b43e 100644 --- a/utils/init/initialConfig.json +++ b/utils/init/initialConfig.json @@ -25,5 +25,7 @@ "daySchema": "Sunday;Monday;Tuesday;Wednesday;Thursday;Friday;Saturday", "monthSchema": "January;February;March;April;May;June;July;August;September;October;November;December", "showTime": false, - "defaultTheme": "tron" + "defaultTheme": "tron", + "isKilometer": true, + "weatherData": "cloud" } From 5cf7708ab816f20b91c32f8a99157b780c394e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Malak?= Date: Thu, 18 Nov 2021 15:14:53 +0100 Subject: [PATCH 4/9] Added humidity option to weather widget --- CHANGELOG.md | 1 + .../WeatherSettings/WeatherSettings.tsx | 27 ++++++++++++++++--- .../Widgets/WeatherWidget/WeatherWidget.tsx | 26 +++++++----------- client/src/interfaces/Config.ts | 4 +++ client/src/interfaces/Forms.ts | 3 +++ client/src/interfaces/Weather.ts | 5 +++- client/src/types/WeatherData.ts | 1 + client/src/types/index.ts | 1 + .../utility/templateObjects/configTemplate.ts | 2 ++ .../templateObjects/settingsTemplate.ts | 1 + .../templateObjects/weatherTemplate.ts | 17 ++++++++++++ 11 files changed, 68 insertions(+), 20 deletions(-) create mode 100644 client/src/types/WeatherData.ts create mode 100644 client/src/utility/templateObjects/weatherTemplate.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 940e9dc..efc1635 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ ### v2.0.1 (TBA) +- Added option to display humidity in the weather widget ([#136](https://github.com/pawelmalak/flame/issues/136)) - Added option to set default theme for all new users ([#165](https://github.com/pawelmalak/flame/issues/165)) - Fixed bug with custom icons not working with apps when "pin by default" was disabled diff --git a/client/src/components/Settings/WeatherSettings/WeatherSettings.tsx b/client/src/components/Settings/WeatherSettings/WeatherSettings.tsx index c587517..19ba7d4 100644 --- a/client/src/components/Settings/WeatherSettings/WeatherSettings.tsx +++ b/client/src/components/Settings/WeatherSettings/WeatherSettings.tsx @@ -11,7 +11,7 @@ import { State } from '../../../store/reducers'; import { ApiResponse, Weather, WeatherForm } from '../../../interfaces'; // UI -import { InputGroup, Button } from '../../UI'; +import { InputGroup, Button, SettingsHeadline } from '../../UI'; // Utils import { inputHandler, weatherSettingsTemplate } from '../../../utility'; @@ -84,6 +84,8 @@ export const WeatherSettings = (): JSX.Element => { return (
formSubmitHandler(e)}> + + {/* API KEY */} { + + {/* LAT */} - + { + {/* LONG */} - + { /> + + {/* TEMPERATURE */} + {/* WEATHER DATA */} + + + + + ); diff --git a/client/src/components/Widgets/WeatherWidget/WeatherWidget.tsx b/client/src/components/Widgets/WeatherWidget/WeatherWidget.tsx index 7b84da8..1664eff 100644 --- a/client/src/components/Widgets/WeatherWidget/WeatherWidget.tsx +++ b/client/src/components/Widgets/WeatherWidget/WeatherWidget.tsx @@ -13,22 +13,14 @@ import classes from './WeatherWidget.module.css'; // UI import { WeatherIcon } from '../../UI'; import { State } from '../../../store/reducers'; +import { weatherTemplate } from '../../../utility/templateObjects/weatherTemplate'; export const WeatherWidget = (): JSX.Element => { - const { loading, config } = useSelector((state: State) => state.config); + const { loading: configLoading, config } = useSelector( + (state: State) => state.config + ); - const [weather, setWeather] = useState({ - externalLastUpdate: '', - tempC: 0, - tempF: 0, - isDay: 1, - cloud: 0, - conditionText: '', - conditionCode: 1000, - id: -1, - createdAt: new Date(), - updatedAt: new Date(), - }); + const [weather, setWeather] = useState(weatherTemplate); const [isLoading, setIsLoading] = useState(true); // Initial request to get data @@ -65,8 +57,7 @@ export const WeatherWidget = (): JSX.Element => { return (
- {isLoading || - loading || + {configLoading || (config.WEATHER_API_KEY && weather.id > 0 && (
@@ -76,12 +67,15 @@ export const WeatherWidget = (): JSX.Element => { />
+ {/* TEMPERATURE */} {config.isCelsius ? ( {weather.tempC}°C ) : ( {weather.tempF}°F )} - {weather.cloud}% + + {/* ADDITIONAL DATA */} + {weather[config.weatherData]}%
))} diff --git a/client/src/interfaces/Config.ts b/client/src/interfaces/Config.ts index b0e2908..f3d9334 100644 --- a/client/src/interfaces/Config.ts +++ b/client/src/interfaces/Config.ts @@ -1,3 +1,5 @@ +import { WeatherData } from '../types'; + export interface Config { WEATHER_API_KEY: string; lat: number; @@ -26,4 +28,6 @@ export interface Config { monthSchema: string; showTime: boolean; defaultTheme: string; + isKilometer: boolean; + weatherData: WeatherData; } diff --git a/client/src/interfaces/Forms.ts b/client/src/interfaces/Forms.ts index 03f8ae7..878013b 100644 --- a/client/src/interfaces/Forms.ts +++ b/client/src/interfaces/Forms.ts @@ -1,8 +1,11 @@ +import { WeatherData } from '../types'; + export interface WeatherForm { WEATHER_API_KEY: string; lat: number; long: number; isCelsius: boolean; + weatherData: WeatherData; } export interface SearchForm { diff --git a/client/src/interfaces/Weather.ts b/client/src/interfaces/Weather.ts index c71ac48..143ebf8 100644 --- a/client/src/interfaces/Weather.ts +++ b/client/src/interfaces/Weather.ts @@ -8,4 +8,7 @@ export interface Weather extends Model { cloud: number; conditionText: string; conditionCode: number; -} \ No newline at end of file + humidity: number; + windK: number; + windM: number; +} diff --git a/client/src/types/WeatherData.ts b/client/src/types/WeatherData.ts new file mode 100644 index 0000000..81a5863 --- /dev/null +++ b/client/src/types/WeatherData.ts @@ -0,0 +1 @@ +export type WeatherData = 'cloud' | 'humidity'; diff --git a/client/src/types/index.ts b/client/src/types/index.ts index ad5b423..6ea0efd 100644 --- a/client/src/types/index.ts +++ b/client/src/types/index.ts @@ -1 +1,2 @@ export * from './ConfigFormData'; +export * from './WeatherData'; diff --git a/client/src/utility/templateObjects/configTemplate.ts b/client/src/utility/templateObjects/configTemplate.ts index 5cb34e9..6906973 100644 --- a/client/src/utility/templateObjects/configTemplate.ts +++ b/client/src/utility/templateObjects/configTemplate.ts @@ -29,4 +29,6 @@ export const configTemplate: Config = { 'January;February;March;April;May;June;July;August;September;October;November;December', showTime: false, defaultTheme: 'tron', + isKilometer: true, + weatherData: 'cloud', }; diff --git a/client/src/utility/templateObjects/settingsTemplate.ts b/client/src/utility/templateObjects/settingsTemplate.ts index 06afd9e..8752859 100644 --- a/client/src/utility/templateObjects/settingsTemplate.ts +++ b/client/src/utility/templateObjects/settingsTemplate.ts @@ -29,6 +29,7 @@ export const weatherSettingsTemplate: WeatherForm = { lat: 0, long: 0, isCelsius: true, + weatherData: 'cloud', }; export const searchSettingsTemplate: SearchForm = { diff --git a/client/src/utility/templateObjects/weatherTemplate.ts b/client/src/utility/templateObjects/weatherTemplate.ts new file mode 100644 index 0000000..1f8dfd6 --- /dev/null +++ b/client/src/utility/templateObjects/weatherTemplate.ts @@ -0,0 +1,17 @@ +import { Weather } from '../../interfaces'; + +export const weatherTemplate: Weather = { + externalLastUpdate: '', + tempC: 0, + tempF: 0, + isDay: 1, + cloud: 0, + conditionText: '', + conditionCode: 1000, + id: -1, + createdAt: new Date(), + updatedAt: new Date(), + humidity: 0, + windK: 0, + windM: 0, +}; From 85a65aef52b41fd476bb404991bc0d01fcbef207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Malak?= Date: Thu, 18 Nov 2021 16:03:44 +0100 Subject: [PATCH 5/9] Added option to hide header greetings and date separately --- CHANGELOG.md | 1 + client/src/components/Home/Header/Header.tsx | 22 ++- .../Home/Header/functions/getDateTime.ts | 50 ++++-- client/src/components/Home/Home.tsx | 2 +- .../Settings/UISettings/UISettings.tsx | 170 ++++++++++-------- client/src/interfaces/Config.ts | 1 + client/src/interfaces/Forms.ts | 1 + client/src/store/action-creators/config.ts | 1 + .../utility/templateObjects/configTemplate.ts | 1 + .../templateObjects/settingsTemplate.ts | 1 + utils/init/initialConfig.json | 3 +- 11 files changed, 153 insertions(+), 100 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efc1635..f5fc9df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ### v2.0.1 (TBA) - Added option to display humidity in the weather widget ([#136](https://github.com/pawelmalak/flame/issues/136)) - Added option to set default theme for all new users ([#165](https://github.com/pawelmalak/flame/issues/165)) +- Added option to hide header greetings and date separately ([#200](https://github.com/pawelmalak/flame/issues/200)) - Fixed bug with custom icons not working with apps when "pin by default" was disabled ### v2.0.0 (2021-11-15) diff --git a/client/src/components/Home/Header/Header.tsx b/client/src/components/Home/Header/Header.tsx index f059b49..84da280 100644 --- a/client/src/components/Home/Header/Header.tsx +++ b/client/src/components/Home/Header/Header.tsx @@ -1,6 +1,10 @@ import { useEffect, useState } from 'react'; import { Link } from 'react-router-dom'; +// Redux +import { useSelector } from 'react-redux'; +import { State } from '../../../store/reducers'; + // CSS import classes from './Header.module.css'; @@ -12,6 +16,10 @@ import { getDateTime } from './functions/getDateTime'; import { greeter } from './functions/greeter'; export const Header = (): JSX.Element => { + const { hideHeader, hideDate, showTime } = useSelector( + (state: State) => state.config.config + ); + const [dateTime, setDateTime] = useState(getDateTime()); const [greeting, setGreeting] = useState(greeter()); @@ -28,14 +36,18 @@ export const Header = (): JSX.Element => { return (
-

{dateTime}

+ {(!hideDate || showTime) &&

{dateTime}

} + Go to Settings - -

{greeting}

- -
+ + {!hideHeader && ( + +

{greeting}

+ +
+ )}
); }; diff --git a/client/src/components/Home/Header/functions/getDateTime.ts b/client/src/components/Home/Header/functions/getDateTime.ts index 69cd78b..45ffc9d 100644 --- a/client/src/components/Home/Header/functions/getDateTime.ts +++ b/client/src/components/Home/Header/functions/getDateTime.ts @@ -30,22 +30,42 @@ export const getDateTime = (): string => { const useAmericanDate = localStorage.useAmericanDate === 'true'; const showTime = localStorage.showTime === 'true'; + const hideDate = localStorage.hideDate === 'true'; - const p = parseTime; + // Date + let dateEl = ''; - const time = `${p(now.getHours())}:${p(now.getMinutes())}:${p( - now.getSeconds() - )}`; - - const timeEl = showTime ? ` - ${time}` : ''; - - if (!useAmericanDate) { - return `${days[now.getDay()]}, ${now.getDate()} ${ - months[now.getMonth()] - } ${now.getFullYear()}${timeEl}`; - } else { - return `${days[now.getDay()]}, ${ - months[now.getMonth()] - } ${now.getDate()} ${now.getFullYear()}${timeEl}`; + if (!hideDate) { + if (!useAmericanDate) { + dateEl = `${days[now.getDay()]}, ${now.getDate()} ${ + months[now.getMonth()] + } ${now.getFullYear()}`; + } else { + dateEl = `${days[now.getDay()]}, ${ + months[now.getMonth()] + } ${now.getDate()} ${now.getFullYear()}`; + } } + + // Time + const p = parseTime; + let timeEl = ''; + + if (showTime) { + const time = `${p(now.getHours())}:${p(now.getMinutes())}:${p( + now.getSeconds() + )}`; + + timeEl = time; + } + + // Separator + let separator = ''; + + if (!hideDate && showTime) { + separator = ' - '; + } + + // Output + return `${dateEl}${separator}${timeEl}`; }; diff --git a/client/src/components/Home/Home.tsx b/client/src/components/Home/Home.tsx index 43b2373..d7f3872 100644 --- a/client/src/components/Home/Home.tsx +++ b/client/src/components/Home/Home.tsx @@ -98,7 +98,7 @@ export const Home = (): JSX.Element => {
)} - {!config.hideHeader ?
:
} +
{!config.hideApps ? ( diff --git a/client/src/components/Settings/UISettings/UISettings.tsx b/client/src/components/Settings/UISettings/UISettings.tsx index 78d8b14..b0de452 100644 --- a/client/src/components/Settings/UISettings/UISettings.tsx +++ b/client/src/components/Settings/UISettings/UISettings.tsx @@ -66,7 +66,7 @@ export const UISettings = (): JSX.Element => { return (
formSubmitHandler(e)}> - {/* OTHER OPTIONS */} + {/* === OTHER OPTIONS === */} {/* PAGE TITLE */} @@ -81,6 +81,50 @@ export const UISettings = (): JSX.Element => { /> + {/* === HEADER OPTIONS === */} + + {/* HIDE HEADER */} + + + + + + {/* HIDE DATE */} + + + + + + {/* HIDE TIME */} + + + + + {/* DATE FORMAT */} @@ -95,7 +139,52 @@ export const UISettings = (): JSX.Element => { - {/* BEAHVIOR OPTIONS */} + {/* CUSTOM GREETINGS */} + + + inputChangeHandler(e)} + /> + + Greetings must be separated with semicolon. Only 4 messages can be + used + + + + {/* CUSTOM DAYS */} + + + inputChangeHandler(e)} + /> + Names must be separated with semicolon + + + {/* CUSTOM MONTHS */} + + + inputChangeHandler(e)} + /> + Names must be separated with semicolon + + + {/* === BEAHVIOR OPTIONS === */} {/* PIN APPS */} @@ -172,82 +261,7 @@ export const UISettings = (): JSX.Element => { - {/* HEADER OPTIONS */} - - {/* HIDE HEADER */} - - - - - - {/* CUSTOM GREETINGS */} - - - inputChangeHandler(e)} - /> - - Greetings must be separated with semicolon. Only 4 messages can be - used - - - - {/* CUSTOM DAYS */} - - - inputChangeHandler(e)} - /> - Names must be separated with semicolon - - - {/* CUSTOM MONTHS */} - - - inputChangeHandler(e)} - /> - Names must be separated with semicolon - - - {/* SHOW TIME */} - - - - - - {/* MODULES OPTIONS */} + {/* === MODULES OPTIONS === */} {/* HIDE APPS */} diff --git a/client/src/interfaces/Config.ts b/client/src/interfaces/Config.ts index f3d9334..cab413f 100644 --- a/client/src/interfaces/Config.ts +++ b/client/src/interfaces/Config.ts @@ -30,4 +30,5 @@ export interface Config { defaultTheme: string; isKilometer: boolean; weatherData: WeatherData; + hideDate: boolean; } diff --git a/client/src/interfaces/Forms.ts b/client/src/interfaces/Forms.ts index 878013b..ad3763f 100644 --- a/client/src/interfaces/Forms.ts +++ b/client/src/interfaces/Forms.ts @@ -30,6 +30,7 @@ export interface OtherSettingsForm { daySchema: string; monthSchema: string; showTime: boolean; + hideDate: boolean; } export interface DockerSettingsForm { diff --git a/client/src/store/action-creators/config.ts b/client/src/store/action-creators/config.ts index 079faac..6b516f7 100644 --- a/client/src/store/action-creators/config.ts +++ b/client/src/store/action-creators/config.ts @@ -19,6 +19,7 @@ const keys: (keyof Config)[] = [ 'daySchema', 'monthSchema', 'showTime', + 'hideDate', ]; export const getConfig = () => async (dispatch: Dispatch) => { diff --git a/client/src/utility/templateObjects/configTemplate.ts b/client/src/utility/templateObjects/configTemplate.ts index 6906973..8d58153 100644 --- a/client/src/utility/templateObjects/configTemplate.ts +++ b/client/src/utility/templateObjects/configTemplate.ts @@ -31,4 +31,5 @@ export const configTemplate: Config = { defaultTheme: 'tron', isKilometer: true, weatherData: 'cloud', + hideDate: false, }; diff --git a/client/src/utility/templateObjects/settingsTemplate.ts b/client/src/utility/templateObjects/settingsTemplate.ts index 8752859..a122830 100644 --- a/client/src/utility/templateObjects/settingsTemplate.ts +++ b/client/src/utility/templateObjects/settingsTemplate.ts @@ -22,6 +22,7 @@ export const otherSettingsTemplate: OtherSettingsForm = { monthSchema: 'January;February;March;April;May;June;July;August;September;October;November;December', showTime: false, + hideDate: false, }; export const weatherSettingsTemplate: WeatherForm = { diff --git a/utils/init/initialConfig.json b/utils/init/initialConfig.json index 897b43e..575a2e7 100644 --- a/utils/init/initialConfig.json +++ b/utils/init/initialConfig.json @@ -27,5 +27,6 @@ "showTime": false, "defaultTheme": "tron", "isKilometer": true, - "weatherData": "cloud" + "weatherData": "cloud", + "hideDate": false } From e13f6f261200811837c213179eb90cd34adb087f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Malak?= Date: Fri, 19 Nov 2021 12:41:32 +0100 Subject: [PATCH 6/9] Changed auth header --- client/src/utility/applyAuth.ts | 2 +- middleware/auth.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/utility/applyAuth.ts b/client/src/utility/applyAuth.ts index 95dcfb2..cf79efe 100644 --- a/client/src/utility/applyAuth.ts +++ b/client/src/utility/applyAuth.ts @@ -1,4 +1,4 @@ export const applyAuth = () => { const token = localStorage.getItem('token') || ''; - return { Authorization: `Bearer ${token}` }; + return { Authorization_Flame: `Bearer ${token}` }; }; diff --git a/middleware/auth.js b/middleware/auth.js index c73d0ca..137c78d 100644 --- a/middleware/auth.js +++ b/middleware/auth.js @@ -1,7 +1,7 @@ const jwt = require('jsonwebtoken'); const auth = (req, res, next) => { - const authHeader = req.header('Authorization'); + const authHeader = req.header('Authorization_Flame'); let token; let tokenIsValid = false; From c2e9f82cd62eed5f4798b8479c3387494b1d6f61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Malak?= Date: Fri, 19 Nov 2021 13:24:07 +0100 Subject: [PATCH 7/9] Improved default theme setting. Pushed version 2.0.1 --- .env | 2 +- CHANGELOG.md | 3 ++- client/.env | 2 +- client/src/App.tsx | 2 +- client/src/store/action-creators/theme.ts | 8 ++++++-- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.env b/.env index 4390587..9f1bd80 100644 --- a/.env +++ b/.env @@ -1,5 +1,5 @@ PORT=5005 NODE_ENV=development -VERSION=2.0.0 +VERSION=2.0.1 PASSWORD=flame_password SECRET=e02eb43d69953658c6d07311d6313f2d4467672cb881f96b29368ba1f3f4da4b \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index f5fc9df..ef1b433 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ -### v2.0.1 (TBA) +### v2.0.1 (2021-11-19) - Added option to display humidity in the weather widget ([#136](https://github.com/pawelmalak/flame/issues/136)) - Added option to set default theme for all new users ([#165](https://github.com/pawelmalak/flame/issues/165)) - Added option to hide header greetings and date separately ([#200](https://github.com/pawelmalak/flame/issues/200)) +- Fixed bug with broken basic auth ([#202](https://github.com/pawelmalak/flame/issues/202)) - Fixed bug with custom icons not working with apps when "pin by default" was disabled ### v2.0.0 (2021-11-15) diff --git a/client/.env b/client/.env index 6a5c8f3..aac1ed1 100644 --- a/client/.env +++ b/client/.env @@ -1 +1 @@ -REACT_APP_VERSION=2.0.0 \ No newline at end of file +REACT_APP_VERSION=2.0.1 \ No newline at end of file diff --git a/client/src/App.tsx b/client/src/App.tsx index d9e8717..68faaea 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -68,7 +68,7 @@ export const App = (): JSX.Element => { // If there is no user theme, set the default one useEffect(() => { if (!loading && !localStorage.theme) { - setTheme(config.defaultTheme); + setTheme(config.defaultTheme, false); } }, [loading]); diff --git a/client/src/store/action-creators/theme.ts b/client/src/store/action-creators/theme.ts index 6209523..8eb6fef 100644 --- a/client/src/store/action-creators/theme.ts +++ b/client/src/store/action-creators/theme.ts @@ -5,11 +5,15 @@ import { Theme } from '../../interfaces/Theme'; import { themes } from '../../components/Settings/Themer/themes.json'; export const setTheme = - (name: string) => (dispatch: Dispatch) => { + (name: string, remeberTheme: boolean = true) => + (dispatch: Dispatch) => { const theme = themes.find((theme) => theme.name === name); if (theme) { - localStorage.setItem('theme', name); + if (remeberTheme) { + localStorage.setItem('theme', name); + } + loadTheme(theme); dispatch({ From d13b890e16ae0d128793f1329416ba034f04fc47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Malak?= Date: Fri, 19 Nov 2021 14:06:38 +0100 Subject: [PATCH 8/9] Fixed bug with value parsing if custom icon was used --- client/src/components/Apps/AppForm/AppForm.tsx | 2 +- client/src/components/Bookmarks/Form/BookmarksForm.tsx | 2 +- client/src/utility/applyAuth.ts | 2 +- middleware/auth.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/src/components/Apps/AppForm/AppForm.tsx b/client/src/components/Apps/AppForm/AppForm.tsx index bdfa170..0b94465 100644 --- a/client/src/components/Apps/AppForm/AppForm.tsx +++ b/client/src/components/Apps/AppForm/AppForm.tsx @@ -61,7 +61,7 @@ export const AppForm = ({ app, modalHandler }: Props): JSX.Element => { } data.append('name', formData.name); data.append('url', formData.url); - data.append('isPublic', `${formData.isPublic}`); + data.append('isPublic', `${formData.isPublic ? 1 : 0}`); return data; }; diff --git a/client/src/components/Bookmarks/Form/BookmarksForm.tsx b/client/src/components/Bookmarks/Form/BookmarksForm.tsx index e5f790b..f0a3a43 100644 --- a/client/src/components/Bookmarks/Form/BookmarksForm.tsx +++ b/client/src/components/Bookmarks/Form/BookmarksForm.tsx @@ -77,7 +77,7 @@ export const BookmarksForm = ({ data.append('name', formData.name); data.append('url', formData.url); data.append('categoryId', `${formData.categoryId}`); - data.append('isPublic', `${formData.isPublic}`); + data.append('isPublic', `${formData.isPublic ? 1 : 0}`); return data; }; diff --git a/client/src/utility/applyAuth.ts b/client/src/utility/applyAuth.ts index cf79efe..8ec0776 100644 --- a/client/src/utility/applyAuth.ts +++ b/client/src/utility/applyAuth.ts @@ -1,4 +1,4 @@ export const applyAuth = () => { const token = localStorage.getItem('token') || ''; - return { Authorization_Flame: `Bearer ${token}` }; + return { 'Authorization-Flame': `Bearer ${token}` }; }; diff --git a/middleware/auth.js b/middleware/auth.js index 137c78d..334eeeb 100644 --- a/middleware/auth.js +++ b/middleware/auth.js @@ -1,7 +1,7 @@ const jwt = require('jsonwebtoken'); const auth = (req, res, next) => { - const authHeader = req.header('Authorization_Flame'); + const authHeader = req.header('Authorization-Flame'); let token; let tokenIsValid = false; From 55b70eebbd3bba9fac5859da59edd7bb7fc5ce6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Malak?= Date: Fri, 19 Nov 2021 15:02:33 +0100 Subject: [PATCH 9/9] Updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef1b433..8543534 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - Added option to set default theme for all new users ([#165](https://github.com/pawelmalak/flame/issues/165)) - Added option to hide header greetings and date separately ([#200](https://github.com/pawelmalak/flame/issues/200)) - Fixed bug with broken basic auth ([#202](https://github.com/pawelmalak/flame/issues/202)) +- Fixed bug with parsing visibility value for apps and bookmarks when custom icon was used ([#203](https://github.com/pawelmalak/flame/issues/203)) - Fixed bug with custom icons not working with apps when "pin by default" was disabled ### v2.0.0 (2021-11-15)