mirror of
https://github.com/pawelmalak/flame.git
synced 2025-07-27 14:59:37 +02:00
Add custom icons to bookmarks (#5)
* allow custom icons for bookmarks * update docker-image action to tag images based on source branch
This commit is contained in:
parent
28ea50676a
commit
c0d3ea2c4a
8 changed files with 77 additions and 91 deletions
6
.github/workflows/docker-image.yml
vendored
6
.github/workflows/docker-image.yml
vendored
|
@ -20,10 +20,10 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
DOCKER_IMAGE=ghcr.io/${{ github.repository }}
|
DOCKER_IMAGE=ghcr.io/${{ github.repository }}
|
||||||
VERSION=latest
|
VERSION=latest
|
||||||
if [[ $GITHUB_REF == refs/tags/* ]]; then
|
if [[ '${{ github.head_ref }}' != 'master' ]]; then
|
||||||
VERSION=${GITHUB_REF#refs/tags/v}
|
VERSION=${{github.head_ref}}
|
||||||
fi
|
fi
|
||||||
TAGS="${DOCKER_IMAGE}:latest,${DOCKER_IMAGE}:${{ steps.date.outputs.date }}"
|
TAGS="${DOCKER_IMAGE}:${VERSION},${DOCKER_IMAGE}:${{ steps.date.outputs.date }}"
|
||||||
echo ::set-output name=tags::${TAGS}
|
echo ::set-output name=tags::${TAGS}
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
|
|
|
@ -30,7 +30,7 @@ interface ComponentProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
const AppForm = (props: ComponentProps): JSX.Element => {
|
const AppForm = (props: ComponentProps): JSX.Element => {
|
||||||
const [useCustomIcon, toggleUseCustomIcon] = useState<boolean>(false);
|
const [useCustomIcon, setUseCustomIcon] = useState<boolean>(false);
|
||||||
const [customIcon, setCustomIcon] = useState<File | null>(null);
|
const [customIcon, setCustomIcon] = useState<File | null>(null);
|
||||||
const [categoryData, setCategoryData] = useState<NewCategory>({
|
const [categoryData, setCategoryData] = useState<NewCategory>({
|
||||||
name: '',
|
name: '',
|
||||||
|
@ -77,13 +77,12 @@ const AppForm = (props: ComponentProps): JSX.Element => {
|
||||||
|
|
||||||
const createFormData = (): FormData => {
|
const createFormData = (): FormData => {
|
||||||
const data = new FormData();
|
const data = new FormData();
|
||||||
|
Object.entries(appData).forEach((entry: [string, any]) => {
|
||||||
|
data.append(entry[0], entry[1]);
|
||||||
|
});
|
||||||
if (customIcon) {
|
if (customIcon) {
|
||||||
data.append('icon', customIcon);
|
data.append('icon', customIcon);
|
||||||
}
|
}
|
||||||
data.append('name', appData.name);
|
|
||||||
data.append('url', appData.url);
|
|
||||||
data.append('categoryId', appData.categoryId.toString());
|
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
@ -151,6 +150,11 @@ const AppForm = (props: ComponentProps): JSX.Element => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const toggleUseCustomIcon = (): void => {
|
||||||
|
setUseCustomIcon(!useCustomIcon);
|
||||||
|
setCustomIcon(null);
|
||||||
|
};
|
||||||
|
|
||||||
const fileChangeHandler = (e: ChangeEvent<HTMLInputElement>): void => {
|
const fileChangeHandler = (e: ChangeEvent<HTMLInputElement>): void => {
|
||||||
if (e.target.files) {
|
if (e.target.files) {
|
||||||
setCustomIcon(e.target.files[0]);
|
setCustomIcon(e.target.files[0]);
|
||||||
|
@ -272,7 +276,7 @@ const AppForm = (props: ComponentProps): JSX.Element => {
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
onClick={() => toggleUseCustomIcon(!useCustomIcon)}
|
onClick={() => toggleUseCustomIcon()}
|
||||||
className={classes.Switch}>
|
className={classes.Switch}>
|
||||||
Switch to custom icon upload
|
Switch to custom icon upload
|
||||||
</span>
|
</span>
|
||||||
|
@ -286,10 +290,10 @@ const AppForm = (props: ComponentProps): JSX.Element => {
|
||||||
id='icon'
|
id='icon'
|
||||||
required
|
required
|
||||||
onChange={(e) => fileChangeHandler(e)}
|
onChange={(e) => fileChangeHandler(e)}
|
||||||
accept=".jpg,.jpeg,.png,.svg"
|
accept='.jpg,.jpeg,.png,.svg'
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
onClick={() => toggleUseCustomIcon(!useCustomIcon)}
|
onClick={() => toggleUseCustomIcon()}
|
||||||
className={classes.Switch}>
|
className={classes.Switch}>
|
||||||
Switch to MDI
|
Switch to MDI
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -7,7 +7,7 @@ import classes from './BookmarkCard.module.css';
|
||||||
|
|
||||||
interface ComponentProps {
|
interface ComponentProps {
|
||||||
category: Category;
|
category: Category;
|
||||||
bookmarks: Bookmark[]
|
bookmarks: Bookmark[];
|
||||||
pinHandler?: Function;
|
pinHandler?: Function;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,10 +28,8 @@ interface ComponentProps {
|
||||||
updateBookmark: (
|
updateBookmark: (
|
||||||
id: number,
|
id: number,
|
||||||
formData: NewBookmark | FormData,
|
formData: NewBookmark | FormData,
|
||||||
category: {
|
previousCategoryId: number
|
||||||
prev: number,
|
) => void;
|
||||||
curr: number
|
|
||||||
}) => void;
|
|
||||||
createNotification: (notification: NewNotification) => void;
|
createNotification: (notification: NewNotification) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,13 +37,13 @@ const BookmarkForm = (props: ComponentProps): JSX.Element => {
|
||||||
const [useCustomIcon, setUseCustomIcon] = useState<boolean>(false);
|
const [useCustomIcon, setUseCustomIcon] = useState<boolean>(false);
|
||||||
const [customIcon, setCustomIcon] = useState<File | null>(null);
|
const [customIcon, setCustomIcon] = useState<File | null>(null);
|
||||||
const [categoryData, setCategoryData] = useState<NewCategory>({
|
const [categoryData, setCategoryData] = useState<NewCategory>({
|
||||||
name: '',
|
name: "",
|
||||||
type: 'bookmarks'
|
type: "bookmarks",
|
||||||
})
|
});
|
||||||
|
|
||||||
const [bookmarkData, setBookmarkData] = useState<NewBookmark>({
|
const [bookmarkData, setBookmarkData] = useState<NewBookmark>({
|
||||||
name: '',
|
name: "",
|
||||||
url: '',
|
url: "",
|
||||||
categoryId: -1,
|
categoryId: -1,
|
||||||
icon: '',
|
icon: '',
|
||||||
});
|
});
|
||||||
|
@ -55,7 +53,7 @@ const BookmarkForm = (props: ComponentProps): JSX.Element => {
|
||||||
if (props.category) {
|
if (props.category) {
|
||||||
setCategoryData({ name: props.category.name, type: props.category.type });
|
setCategoryData({ name: props.category.name, type: props.category.type });
|
||||||
} else {
|
} else {
|
||||||
setCategoryData({ name: '', type: "bookmarks" });
|
setCategoryData({ name: "", type: "bookmarks" });
|
||||||
}
|
}
|
||||||
}, [props.category]);
|
}, [props.category]);
|
||||||
|
|
||||||
|
@ -70,8 +68,8 @@ const BookmarkForm = (props: ComponentProps): JSX.Element => {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setBookmarkData({
|
setBookmarkData({
|
||||||
name: '',
|
name: "",
|
||||||
url: '',
|
url: "",
|
||||||
categoryId: -1,
|
categoryId: -1,
|
||||||
icon: '',
|
icon: '',
|
||||||
});
|
});
|
||||||
|
@ -86,9 +84,9 @@ const BookmarkForm = (props: ComponentProps): JSX.Element => {
|
||||||
if (customIcon) {
|
if (customIcon) {
|
||||||
data.append('icon', customIcon);
|
data.append('icon', customIcon);
|
||||||
}
|
}
|
||||||
data.append('name', bookmarkData.name);
|
Object.entries(bookmarkData).forEach((entry: [string, any]) => {
|
||||||
data.append('url', bookmarkData.url);
|
data.append(entry[0], entry[1]);
|
||||||
data.append('categoryId', `${bookmarkData.categoryId}`);
|
});
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
@ -98,7 +96,7 @@ const BookmarkForm = (props: ComponentProps): JSX.Element => {
|
||||||
if (props.contentType === ContentType.category) {
|
if (props.contentType === ContentType.category) {
|
||||||
// Add category
|
// Add category
|
||||||
props.addBookmarkCategory(categoryData);
|
props.addBookmarkCategory(categoryData);
|
||||||
setCategoryData({ name: '', type: 'bookmarks' });
|
setCategoryData({ name: "", type: "bookmarks" });
|
||||||
} else if (props.contentType === ContentType.bookmark) {
|
} else if (props.contentType === ContentType.bookmark) {
|
||||||
// Add bookmark
|
// Add bookmark
|
||||||
if (bookmarkData.categoryId === -1) {
|
if (bookmarkData.categoryId === -1) {
|
||||||
|
@ -117,8 +115,8 @@ const BookmarkForm = (props: ComponentProps): JSX.Element => {
|
||||||
}
|
}
|
||||||
|
|
||||||
setBookmarkData({
|
setBookmarkData({
|
||||||
name: '',
|
name: "",
|
||||||
url: '',
|
url: "",
|
||||||
categoryId: bookmarkData.categoryId,
|
categoryId: bookmarkData.categoryId,
|
||||||
icon: ''
|
icon: ''
|
||||||
});
|
});
|
||||||
|
@ -130,33 +128,18 @@ const BookmarkForm = (props: ComponentProps): JSX.Element => {
|
||||||
if (props.contentType === ContentType.category && props.category) {
|
if (props.contentType === ContentType.category && props.category) {
|
||||||
// Update category
|
// Update category
|
||||||
props.updateBookmarkCategory(props.category.id, categoryData);
|
props.updateBookmarkCategory(props.category.id, categoryData);
|
||||||
setCategoryData({ name: '', type: 'bookmarks' });
|
setCategoryData({ name: "", type: "bookmarks" });
|
||||||
} else if (props.contentType === ContentType.bookmark && props.bookmark) {
|
} else if (props.contentType === ContentType.bookmark && props.bookmark) {
|
||||||
// Update bookmark
|
// Update bookmark
|
||||||
if (customIcon) {
|
|
||||||
const data = createFormData();
|
|
||||||
props.updateBookmark(
|
props.updateBookmark(
|
||||||
props.bookmark.id,
|
props.bookmark.id,
|
||||||
data,
|
createFormData(),
|
||||||
{
|
props.bookmark.categoryId
|
||||||
prev: props.bookmark.categoryId,
|
|
||||||
curr: bookmarkData.categoryId
|
|
||||||
}
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
props.updateBookmark(
|
|
||||||
props.bookmark.id,
|
|
||||||
bookmarkData,
|
|
||||||
{
|
|
||||||
prev: props.bookmark.categoryId,
|
|
||||||
curr: bookmarkData.categoryId
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
setBookmarkData({
|
setBookmarkData({
|
||||||
name: '',
|
name: "",
|
||||||
url: '',
|
url: "",
|
||||||
categoryId: -1,
|
categoryId: -1,
|
||||||
icon: '',
|
icon: '',
|
||||||
});
|
});
|
||||||
|
|
|
@ -50,10 +50,10 @@ const Bookmarks = (props: ComponentProps): JSX.Element => {
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
});
|
});
|
||||||
const [bookmarkInUpdate, setBookmarkInUpdate] = useState<Bookmark>({
|
const [bookmarkInUpdate, setBookmarkInUpdate] = useState<Bookmark>({
|
||||||
name: "",
|
name: "string",
|
||||||
url: "",
|
url: "string",
|
||||||
categoryId: -1,
|
categoryId: -1,
|
||||||
icon: "",
|
icon: "string",
|
||||||
isPinned: false,
|
isPinned: false,
|
||||||
orderId: 0,
|
orderId: 0,
|
||||||
id: 0,
|
id: 0,
|
||||||
|
@ -113,10 +113,7 @@ const Bookmarks = (props: ComponentProps): JSX.Element => {
|
||||||
<Container>
|
<Container>
|
||||||
<Modal isOpen={modalIsOpen} setIsOpen={toggleModal}>
|
<Modal isOpen={modalIsOpen} setIsOpen={toggleModal}>
|
||||||
{!isInUpdate ? (
|
{!isInUpdate ? (
|
||||||
<BookmarkForm
|
<BookmarkForm modalHandler={toggleModal} contentType={formContentType} />
|
||||||
modalHandler={toggleModal}
|
|
||||||
contentType={formContentType}
|
|
||||||
/>
|
|
||||||
) : formContentType === ContentType.category ? (
|
) : formContentType === ContentType.category ? (
|
||||||
<BookmarkForm
|
<BookmarkForm
|
||||||
modalHandler={toggleModal}
|
modalHandler={toggleModal}
|
||||||
|
|
|
@ -138,7 +138,8 @@ export interface AddAppAction {
|
||||||
payload: App;
|
payload: App;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const addApp = (formData: NewApp | FormData) => async (dispatch: Dispatch) => {
|
export const addApp =
|
||||||
|
(formData: NewApp | FormData) => async (dispatch: Dispatch) => {
|
||||||
try {
|
try {
|
||||||
const res = await axios.post<ApiResponse<App>>("/api/apps", formData);
|
const res = await axios.post<ApiResponse<App>>("/api/apps", formData);
|
||||||
|
|
||||||
|
@ -160,7 +161,7 @@ export const addApp = (formData: NewApp | FormData) => async (dispatch: Dispatch
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PIN CATEGORY
|
* PIN CATEGORY
|
||||||
|
|
|
@ -136,7 +136,8 @@ export const pinBookmark =
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ADD BOOKMARK
|
* ADD BOOKMARK
|
||||||
*/ export interface AddBookmarkAction {
|
*/
|
||||||
|
export interface AddBookmarkAction {
|
||||||
type: ActionTypes.addBookmarkSuccess;
|
type: ActionTypes.addBookmarkSuccess;
|
||||||
payload: Bookmark;
|
payload: Bookmark;
|
||||||
}
|
}
|
||||||
|
@ -442,7 +443,7 @@ export interface ReorderBookmarkCategoriesAction {
|
||||||
payload: Category[];
|
payload: Category[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ReorderReorderCategoriesQueryuery {
|
interface ReorderCategoriesQuery {
|
||||||
categories: {
|
categories: {
|
||||||
id: number;
|
id: number;
|
||||||
orderId: number;
|
orderId: number;
|
||||||
|
@ -452,7 +453,7 @@ interface ReorderReorderCategoriesQueryuery {
|
||||||
export const reorderBookmarkCategories =
|
export const reorderBookmarkCategories =
|
||||||
(categories: Category[]) => async (dispatch: Dispatch) => {
|
(categories: Category[]) => async (dispatch: Dispatch) => {
|
||||||
try {
|
try {
|
||||||
const updateQuery: ReorderReorderCategoriesQueryuery = { categories: [] };
|
const updateQuery: ReorderCategoriesQuery = { categories: [] };
|
||||||
|
|
||||||
categories.forEach((category, index) =>
|
categories.forEach((category, index) =>
|
||||||
updateQuery.categories.push({
|
updateQuery.categories.push({
|
||||||
|
|
|
@ -22,7 +22,7 @@ router
|
||||||
.put(upload, updateBookmark)
|
.put(upload, updateBookmark)
|
||||||
.delete(deleteBookmark);
|
.delete(deleteBookmark);
|
||||||
|
|
||||||
router
|
router
|
||||||
.route('/0/reorder')
|
.route('/0/reorder')
|
||||||
.put(reorderBookmarks);
|
.put(reorderBookmarks);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue