Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version 2.3.0 #334

Merged
merged 16 commits into from
Mar 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .dev/build_dev.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
docker build -t flame:dev -f .docker/Dockerfile .
2 changes: 1 addition & 1 deletion .dev/build_latest.sh
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
docker build -t pawelmalak/flame -t "pawelmalak/flame:$1" -f .docker/Dockerfile "$2" \
docker build -t pawelmalak/flame -t "pawelmalak/flame:$1" -f .docker/Dockerfile . \
&& docker push pawelmalak/flame && docker push "pawelmalak/flame:$1"
2 changes: 1 addition & 1 deletion .dev/build_multiarch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ docker buildx build \
-f .docker/Dockerfile.multiarch \
-t pawelmalak/flame:multiarch \
-t "pawelmalak/flame:multiarch$1" \
--push "$2"
--push .
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.2.2
VERSION=2.3.0
PASSWORD=flame_password
SECRET=e02eb43d69953658c6d07311d6313f2d4467672cb881f96b29368ba1f3f4da4b
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
### v2.3.0 (2022-03-25)
- Added custom theme editor ([#246](https://github.com/pawelmalak/flame/issues/246))
- Added option to set secondary search provider ([#295](https://github.com/pawelmalak/flame/issues/295))
- Fixed bug where pressing Enter with empty search bar would redirect to search results ([#325](https://github.com/pawelmalak/flame/issues/325))
- Fixed bug where user could create empty app or bookmark which was causing page to go blank ([#332](https://github.com/pawelmalak/flame/issues/332))
- Added new theme: Mint

### v2.2.2 (2022-03-21)
- Added option to get user location directly from the app ([#287](https://github.com/pawelmalak/flame/issues/287))
- Fixed bug with local search not working when using prefix ([#289](https://github.com/pawelmalak/flame/issues/289))
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 options 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, 15 built-in color themes and custom theme builder
- ☀️ 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
1 change: 1 addition & 0 deletions api.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ api.use('/api/categories', require('./routes/category'));
api.use('/api/bookmarks', require('./routes/bookmark'));
api.use('/api/queries', require('./routes/queries'));
api.use('/api/auth', require('./routes/auth'));
api.use('/api/themes', require('./routes/themes'));

// Custom error handler
api.use(errorHandler);
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.2.2
REACT_APP_VERSION=2.3.0
11 changes: 7 additions & 4 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { actionCreators, store } from './store';
import { State } from './store/reducers';

// Utils
import { checkVersion, decodeToken } from './utility';
import { checkVersion, decodeToken, parsePABToTheme } from './utility';

// Routes
import { Home } from './components/Home/Home';
Expand All @@ -31,7 +31,7 @@ export const App = (): JSX.Element => {
const { config, loading } = useSelector((state: State) => state.config);

const dispath = useDispatch();
const { fetchQueries, setTheme, logout, createNotification } =
const { fetchQueries, setTheme, logout, createNotification, fetchThemes } =
bindActionCreators(actionCreators, dispath);

useEffect(() => {
Expand All @@ -51,9 +51,12 @@ export const App = (): JSX.Element => {
}
}, 1000);

// load themes
fetchThemes();

// set user theme if present
if (localStorage.theme) {
setTheme(localStorage.theme);
setTheme(parsePABToTheme(localStorage.theme));
}

// check for updated
Expand All @@ -68,7 +71,7 @@ export const App = (): JSX.Element => {
// If there is no user theme, set the default one
useEffect(() => {
if (!loading && !localStorage.theme) {
setTheme(config.defaultTheme, false);
setTheme(parsePABToTheme(config.defaultTheme), false);
}
}, [loading]);

Expand Down
17 changes: 13 additions & 4 deletions client/src/components/Apps/AppForm/AppForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@ export const AppForm = ({ modalHandler }: Props): JSX.Element => {
const { appInUpdate } = useSelector((state: State) => state.apps);

const dispatch = useDispatch();
const { addApp, updateApp, setEditApp } = bindActionCreators(
actionCreators,
dispatch
);
const { addApp, updateApp, setEditApp, createNotification } =
bindActionCreators(actionCreators, dispatch);

const [useCustomIcon, toggleUseCustomIcon] = useState<boolean>(false);
const [customIcon, setCustomIcon] = useState<File | null>(null);
Expand Down Expand Up @@ -58,6 +56,17 @@ export const AppForm = ({ modalHandler }: Props): JSX.Element => {
const formSubmitHandler = (e: SyntheticEvent<HTMLFormElement>): void => {
e.preventDefault();

for (let field of ['name', 'url', 'icon'] as const) {
if (/^ +$/.test(formData[field])) {
createNotification({
title: 'Error',
message: `Field cannot be empty: ${field}`,
});

return;
}
}

const createFormData = (): FormData => {
const data = new FormData();

Expand Down
11 changes: 11 additions & 0 deletions client/src/components/Bookmarks/Form/BookmarksForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,17 @@ export const BookmarksForm = ({
const formSubmitHandler = (e: FormEvent): void => {
e.preventDefault();

for (let field of ['name', 'url', 'icon'] as const) {
if (/^ +$/.test(formData[field])) {
createNotification({
title: 'Error',
message: `Field cannot be empty: ${field}`,
});

return;
}
}

const createFormData = (): FormData => {
const data = new FormData();
if (customIcon) {
Expand Down
34 changes: 21 additions & 13 deletions client/src/components/SearchBar/SearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,22 @@ export const SearchBar = (props: Props): JSX.Element => {
};

const searchHandler = (e: KeyboardEvent<HTMLInputElement>) => {
const { isLocal, search, query, isURL, sameTab } = searchParser(
inputRef.current.value
);
const {
isLocal,
encodedURL,
primarySearch,
secondarySearch,
isURL,
sameTab,
rawQuery,
} = searchParser(inputRef.current.value);

if (isLocal) {
setLocalSearch(search);
setLocalSearch(encodedURL);
}

if (e.code === 'Enter' || e.code === 'NumpadEnter') {
if (!query.prefix) {
if (!primarySearch.prefix) {
// Prefix not found -> emit notification
createNotification({
title: 'Error',
Expand All @@ -90,19 +96,21 @@ export const SearchBar = (props: Props): JSX.Element => {
} else if (bookmarkSearchResult?.[0]?.bookmarks?.length) {
redirectUrl(bookmarkSearchResult[0].bookmarks[0].url, sameTab);
} else {
// no local results -> search the internet with the default search provider
let template = query.template;
// no local results -> search the internet with the default search provider if query is not empty
if (!/^ *$/.test(rawQuery)) {
let template = primarySearch.template;

if (query.prefix === 'l') {
template = 'https://duckduckgo.com/?q=';
}
if (primarySearch.prefix === 'l') {
template = secondarySearch.template;
}

const url = `${template}${search}`;
redirectUrl(url, sameTab);
const url = `${template}${encodedURL}`;
redirectUrl(url, sameTab);
}
}
} else {
// Valid query -> redirect to search results
const url = `${query.template}${search}`;
const url = `${primarySearch.template}${encodedURL}`;
redirectUrl(url, sameTab);
}
} else if (e.code === 'Escape') {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,8 @@ import { actionCreators } from '../../../../store';
// Typescript
import { Query } from '../../../../interfaces';

// CSS
import classes from './CustomQueries.module.css';

// UI
import { Modal, Icon, Button } from '../../../UI';
import { Modal, Icon, Button, CompactTable, ActionIcons } from '../../../UI';

// Components
import { QueriesForm } from './QueriesForm';
Expand Down Expand Up @@ -67,33 +64,27 @@ export const CustomQueries = (): JSX.Element => {
)}
</Modal>

<div>
<div className={classes.QueriesGrid}>
{customQueries.length > 0 && (
<Fragment>
<span>Name</span>
<span>Prefix</span>
<span>Actions</span>

<div className={classes.Separator}></div>
</Fragment>
)}

{customQueries.map((q: Query, idx) => (
<Fragment key={idx}>
<span>{q.name}</span>
<span>{q.prefix}</span>
<span className={classes.ActionIcons}>
<span onClick={() => updateHandler(q)}>
<Icon icon="mdiPencil" />
</span>
<span onClick={() => deleteHandler(q)}>
<Icon icon="mdiDelete" />
</span>
</span>
</Fragment>
))}
</div>
<section>
{customQueries.length ? (
<CompactTable headers={['Name', 'Prefix', 'Actions']}>
{customQueries.map((q: Query, idx) => (
<Fragment key={idx}>
<span>{q.name}</span>
<span>{q.prefix}</span>
<ActionIcons>
<span onClick={() => updateHandler(q)}>
<Icon icon="mdiPencil" />
</span>
<span onClick={() => deleteHandler(q)}>
<Icon icon="mdiDelete" />
</span>
</ActionIcons>
</Fragment>
))}
</CompactTable>
) : (
<></>
)}

<Button
click={() => {
Expand All @@ -103,7 +94,7 @@ export const CustomQueries = (): JSX.Element => {
>
Add new search provider
</Button>
</div>
</section>
</Fragment>
);
};
32 changes: 30 additions & 2 deletions client/src/components/Settings/GeneralSettings/GeneralSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,10 @@ export const GeneralSettings = (): JSX.Element => {
</select>
</InputGroup>

{/* SEARCH SETTINGS */}
{/* === SEARCH OPTIONS === */}
<SettingsHeadline text="Search" />
<InputGroup>
<label htmlFor="defaultSearchProvider">Default search provider</label>
<label htmlFor="defaultSearchProvider">Primary search provider</label>
<select
id="defaultSearchProvider"
name="defaultSearchProvider"
Expand All @@ -186,6 +186,34 @@ export const GeneralSettings = (): JSX.Element => {
</select>
</InputGroup>

{formData.defaultSearchProvider === 'l' && (
<InputGroup>
<label htmlFor="secondarySearchProvider">
Secondary search provider
</label>
<select
id="secondarySearchProvider"
name="secondarySearchProvider"
value={formData.secondarySearchProvider}
onChange={(e) => inputChangeHandler(e)}
>
{[...queries, ...customQueries].map((query: Query, idx) => {
const isCustom = idx >= queries.length;

return (
<option key={idx} value={query.prefix}>
{isCustom && '+'} {query.name}
</option>
);
})}
</select>
<span>
Will be used when "Local search" is primary search provider and
there are not any local results
</span>
</InputGroup>
)}

<InputGroup>
<label htmlFor="searchSameTab">
Open search results in the same tab
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.ThemeBuilder {
margin-bottom: 30px;
}

.Buttons button:not(:last-child) {
margin-right: 10px;
}
Loading