mirror of
https://github.com/pawelmalak/flame.git
synced 2025-07-21 20:39:36 +02:00
Added support for setting icons via URL
This commit is contained in:
parent
d83e3056c6
commit
f5ed85427e
5 changed files with 46 additions and 14 deletions
|
@ -1,6 +1,6 @@
|
||||||
import classes from './AppCard.module.css';
|
import classes from './AppCard.module.css';
|
||||||
import { Icon } from '../../UI';
|
import { Icon } from '../../UI';
|
||||||
import { iconParser, urlParser } from '../../../utility';
|
import { iconParser, isImage, isSvg, isUrl, urlParser } from '../../../utility';
|
||||||
|
|
||||||
import { App } from '../../../interfaces';
|
import { App } from '../../../interfaces';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
|
@ -19,19 +19,23 @@ export const AppCard = (props: Props): JSX.Element => {
|
||||||
let iconEl: JSX.Element;
|
let iconEl: JSX.Element;
|
||||||
const { icon } = props.app;
|
const { icon } = props.app;
|
||||||
|
|
||||||
if (/.(jpeg|jpg|png)$/i.test(icon)) {
|
if (isImage(icon)) {
|
||||||
|
const source = isUrl(icon) ? icon : `/uploads/${icon}`;
|
||||||
|
|
||||||
iconEl = (
|
iconEl = (
|
||||||
<img
|
<img
|
||||||
src={`/uploads/${icon}`}
|
src={source}
|
||||||
alt={`${props.app.name} icon`}
|
alt={`${props.app.name} icon`}
|
||||||
className={classes.CustomIcon}
|
className={classes.CustomIcon}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
} else if (/.(svg)$/i.test(icon)) {
|
} else if (isSvg(icon)) {
|
||||||
|
const source = isUrl(icon) ? icon : `/uploads/${icon}`;
|
||||||
|
|
||||||
iconEl = (
|
iconEl = (
|
||||||
<div className={classes.CustomIcon}>
|
<div className={classes.CustomIcon}>
|
||||||
<svg
|
<svg
|
||||||
data-src={`/uploads/${icon}`}
|
data-src={source}
|
||||||
fill="var(--color-primary)"
|
fill="var(--color-primary)"
|
||||||
className={classes.CustomIcon}
|
className={classes.CustomIcon}
|
||||||
></svg>
|
></svg>
|
||||||
|
|
|
@ -9,7 +9,7 @@ import classes from './BookmarkCard.module.css';
|
||||||
|
|
||||||
import { Icon } from '../../UI';
|
import { Icon } from '../../UI';
|
||||||
|
|
||||||
import { iconParser, urlParser } from '../../../utility';
|
import { iconParser, isImage, isSvg, isUrl, urlParser } from '../../../utility';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
category: Category;
|
category: Category;
|
||||||
|
@ -30,21 +30,25 @@ export const BookmarkCard = (props: Props): JSX.Element => {
|
||||||
if (bookmark.icon) {
|
if (bookmark.icon) {
|
||||||
const { icon, name } = bookmark;
|
const { icon, name } = bookmark;
|
||||||
|
|
||||||
if (/.(jpeg|jpg|png)$/i.test(icon)) {
|
if (isImage(icon)) {
|
||||||
|
const source = isUrl(icon) ? icon : `/uploads/${icon}`;
|
||||||
|
|
||||||
iconEl = (
|
iconEl = (
|
||||||
<div className={classes.BookmarkIcon}>
|
<div className={classes.BookmarkIcon}>
|
||||||
<img
|
<img
|
||||||
src={`/uploads/${icon}`}
|
src={source}
|
||||||
alt={`${name} icon`}
|
alt={`${name} icon`}
|
||||||
className={classes.CustomIcon}
|
className={classes.CustomIcon}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else if (/.(svg)$/i.test(icon)) {
|
} else if (isSvg(icon)) {
|
||||||
|
const source = isUrl(icon) ? icon : `/uploads/${icon}`;
|
||||||
|
|
||||||
iconEl = (
|
iconEl = (
|
||||||
<div className={classes.BookmarkIcon}>
|
<div className={classes.BookmarkIcon}>
|
||||||
<svg
|
<svg
|
||||||
data-src={`/uploads/${icon}`}
|
data-src={source}
|
||||||
fill="var(--color-primary)"
|
fill="var(--color-primary)"
|
||||||
className={classes.BookmarkIconSvg}
|
className={classes.BookmarkIconSvg}
|
||||||
></svg>
|
></svg>
|
||||||
|
|
|
@ -7,3 +7,4 @@ export * from './redirectUrl';
|
||||||
export * from './templateObjects';
|
export * from './templateObjects';
|
||||||
export * from './inputHandler';
|
export * from './inputHandler';
|
||||||
export * from './storeUIConfig';
|
export * from './storeUIConfig';
|
||||||
|
export * from './validators';
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { queries } from './searchQueries.json';
|
import { queries } from './searchQueries.json';
|
||||||
import { Query, SearchResult } from '../interfaces';
|
import { Query, SearchResult } from '../interfaces';
|
||||||
import { store } from '../store/store';
|
import { store } from '../store/store';
|
||||||
|
import { isUrlOrIp } from '.';
|
||||||
|
|
||||||
export const searchParser = (searchQuery: string): SearchResult => {
|
export const searchParser = (searchQuery: string): SearchResult => {
|
||||||
const result: SearchResult = {
|
const result: SearchResult = {
|
||||||
|
@ -18,10 +19,7 @@ export const searchParser = (searchQuery: string): SearchResult => {
|
||||||
const { customQueries, config } = store.getState().config;
|
const { customQueries, config } = store.getState().config;
|
||||||
|
|
||||||
// Check if url or ip was passed
|
// Check if url or ip was passed
|
||||||
const urlRegex =
|
result.isURL = isUrlOrIp(searchQuery);
|
||||||
/^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?|^((http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/i;
|
|
||||||
|
|
||||||
result.isURL = urlRegex.test(searchQuery);
|
|
||||||
|
|
||||||
// Match prefix and query
|
// Match prefix and query
|
||||||
const splitQuery = searchQuery.match(/^\/([a-z]+)[ ](.+)$/i);
|
const splitQuery = searchQuery.match(/^\/([a-z]+)[ ](.+)$/i);
|
||||||
|
|
25
client/src/utility/validators.ts
Normal file
25
client/src/utility/validators.ts
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
export const isUrlOrIp = (data: string): boolean => {
|
||||||
|
const regex =
|
||||||
|
/^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?|^((http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/i;
|
||||||
|
|
||||||
|
return regex.test(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isUrl = (data: string): boolean => {
|
||||||
|
const regex =
|
||||||
|
/(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/i;
|
||||||
|
|
||||||
|
return regex.test(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isImage = (data: string): boolean => {
|
||||||
|
const regex = /.(jpeg|jpg|png)$/i;
|
||||||
|
|
||||||
|
return regex.test(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isSvg = (data: string): boolean => {
|
||||||
|
const regex = /.(svg)$/i;
|
||||||
|
|
||||||
|
return regex.test(data);
|
||||||
|
};
|
Loading…
Add table
Add a link
Reference in a new issue