Skip to content

Commit

Permalink
Merge pull request #206 from pawelmalak/feature
Browse files Browse the repository at this point in the history
Version 2.0.1
  • Loading branch information
pawelmalak authored Nov 19, 2021
2 parents 1220c56 + 55b70ee commit fd7d8e6
Show file tree
Hide file tree
Showing 44 changed files with 477 additions and 229 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
PORT=5005
NODE_ENV=development
VERSION=2.0.0
VERSION=2.0.1
PASSWORD=flame_password
SECRET=e02eb43d69953658c6d07311d6313f2d4467672cb881f96b29368ba1f3f4da4b
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
### 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 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)
- Added authentication system:
- Only logged in user can access settings ([#33](https://github.com/pawelmalak/flame/issues/33))
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion client/.env
Original file line number Diff line number Diff line change
@@ -1 +1 @@
REACT_APP_VERSION=2.0.0
REACT_APP_VERSION=2.0.1
22 changes: 17 additions & 5 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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<any>(getConfig());
Expand All @@ -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);
Expand All @@ -46,7 +51,7 @@ export const App = (): JSX.Element => {
}
}, 1000);

// set theme
// set user theme if present
if (localStorage.theme) {
setTheme(localStorage.theme);
}
Expand All @@ -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, false);
}
}, [loading]);

return (
<>
<BrowserRouter>
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/Apps/AppForm/AppForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/Bookmarks/Form/BookmarksForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down
22 changes: 17 additions & 5 deletions client/src/components/Home/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -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<string>(getDateTime());
const [greeting, setGreeting] = useState<string>(greeter());

Expand All @@ -28,14 +36,18 @@ export const Header = (): JSX.Element => {

return (
<header className={classes.Header}>
<p>{dateTime}</p>
{(!hideDate || showTime) && <p>{dateTime}</p>}

<Link to="/settings" className={classes.SettingsLink}>
Go to Settings
</Link>
<span className={classes.HeaderMain}>
<h1>{greeting}</h1>
<WeatherWidget />
</span>

{!hideHeader && (
<span className={classes.HeaderMain}>
<h1>{greeting}</h1>
<WeatherWidget />
</span>
)}
</header>
);
};
44 changes: 32 additions & 12 deletions client/src/components/Home/Header/functions/getDateTime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,42 @@ export const getDateTime = (): string => {

const useAmericanDate = localStorage.useAmericanDate === 'true';
const showTime = localStorage.showTime === 'true';
const hideDate = localStorage.hideDate === 'true';

// Date
let dateEl = '';

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 = '';

const time = `${p(now.getHours())}:${p(now.getMinutes())}:${p(
now.getSeconds()
)}`;
if (showTime) {
const time = `${p(now.getHours())}:${p(now.getMinutes())}:${p(
now.getSeconds()
)}`;

const timeEl = showTime ? ` - ${time}` : '';
timeEl = time;
}

// Separator
let separator = '';

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 && showTime) {
separator = ' - ';
}

// Output
return `${dateEl}${separator}${timeEl}`;
};
2 changes: 1 addition & 1 deletion client/src/components/Home/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export const Home = (): JSX.Element => {
<div></div>
)}

{!config.hideHeader ? <Header /> : <div></div>}
<Header />

{!config.hideApps ? (
<Fragment>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export const DockerSettings = (): JSX.Element => {
<SettingsHeadline text="Docker" />
{/* CUSTOM DOCKER SOCKET HOST */}
<InputGroup>
<label htmlFor="dockerHost">Docker Host</label>
<label htmlFor="dockerHost">Docker host</label>
<input
type="text"
id="dockerHost"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export const SearchSettings = (): JSX.Element => {
>
<SettingsHeadline text="General" />
<InputGroup>
<label htmlFor="defaultSearchProvider">Default Search Provider</label>
<label htmlFor="defaultSearchProvider">Default search provider</label>
<select
id="defaultSearchProvider"
name="defaultSearchProvider"
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/Settings/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Route as SettingsRoute } from '../../interfaces';
import classes from './Settings.module.css';

// Components
import { Themer } from '../Themer/Themer';
import { Themer } from './Themer/Themer';
import { WeatherSettings } from './WeatherSettings/WeatherSettings';
import { UISettings } from './UISettings/UISettings';
import { AppDetails } from './AppDetails/AppDetails';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
text-transform: capitalize;
margin: 8px 0;
color: var(--color-primary);
/* align-self: flex-start; */
}

.ColorsPreview {
Expand All @@ -32,4 +31,4 @@
width: 40px;
height: 40px;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Theme } from '../../interfaces/Theme';
import { Theme } from '../../../interfaces/Theme';
import classes from './ThemePreview.module.css';

interface Props {
Expand Down
101 changes: 101 additions & 0 deletions client/src/components/Settings/Themer/Themer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { ChangeEvent, FormEvent, Fragment, useEffect, useState } from 'react';

// Redux
import { useDispatch, useSelector } from 'react-redux';
import { bindActionCreators } from 'redux';
import { actionCreators } from '../../../store';

// Typescript
import { Theme, ThemeSettingsForm } from '../../../interfaces';

// Components
import { ThemePreview } from './ThemePreview';
import { Button, InputGroup, SettingsHeadline } from '../../UI';

// Other
import classes from './Themer.module.css';
import { themes } from './themes.json';
import { State } from '../../../store/reducers';
import { inputHandler, themeSettingsTemplate } from '../../../utility';

export const Themer = (): JSX.Element => {
const {
auth: { isAuthenticated },
config: { loading, config },
} = useSelector((state: State) => state);

const dispatch = useDispatch();
const { setTheme, updateConfig } = bindActionCreators(
actionCreators,
dispatch
);

// Initial state
const [formData, setFormData] = useState<ThemeSettingsForm>(
themeSettingsTemplate
);

// Get config
useEffect(() => {
setFormData({
...config,
});
}, [loading]);

// Form handler
const formSubmitHandler = async (e: FormEvent) => {
e.preventDefault();

// Save settings
await updateConfig(formData);
};

// Input handler
const inputChangeHandler = (
e: ChangeEvent<HTMLInputElement | HTMLSelectElement>,
options?: { isNumber?: boolean; isBool?: boolean }
) => {
inputHandler<ThemeSettingsForm>({
e,
options,
setStateHandler: setFormData,
state: formData,
});
};

return (
<Fragment>
<SettingsHeadline text="Set theme" />
<div className={classes.ThemerGrid}>
{themes.map(
(theme: Theme, idx: number): JSX.Element => (
<ThemePreview key={idx} theme={theme} applyTheme={setTheme} />
)
)}
</div>

{isAuthenticated && (
<form onSubmit={formSubmitHandler}>
<SettingsHeadline text="Other settings" />
<InputGroup>
<label htmlFor="defaultTheme">Default theme (for new users)</label>
<select
id="defaultTheme"
name="defaultTheme"
value={formData.defaultTheme}
onChange={(e) => inputChangeHandler(e)}
>
{themes.map((theme: Theme, idx) => (
<option key={idx} value={theme.name}>
{theme.name}
</option>
))}
</select>
</InputGroup>

<Button>Save changes</Button>
</form>
)}
</Fragment>
);
};
File renamed without changes.
Loading

0 comments on commit fd7d8e6

Please sign in to comment.