Skip to content

Commit

Permalink
Merge pull request #334 from pawelmalak/feature
Browse files Browse the repository at this point in the history
Version 2.3.0
  • Loading branch information
pawelmalak authored Mar 25, 2022
2 parents baac780 + 2b5b349 commit 446b409
Show file tree
Hide file tree
Showing 66 changed files with 1,309 additions and 222 deletions.
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

0 comments on commit 446b409

Please sign in to comment.