Skip to content

Commit

Permalink
[IMP] Import/Export Bookmarks
Browse files Browse the repository at this point in the history
This commit adds functionality of importing/exporting your personal bookmarks.
It can help to share your bookmarks with your friends or get their bookmarks too.
  • Loading branch information
user-64bit committed May 25, 2024
1 parent 16e55a9 commit d10217a
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useRef, useState } from 'react'
import { BiBookmarkMinus } from 'react-icons/bi'
import toast from 'react-simple-toasts'
import { CardLink } from 'src/components/Elements'
Expand Down Expand Up @@ -60,17 +61,79 @@ const BookmarkItem = ({ item, appendRef = false }: BookmarkItemProps) => {
}

export const BookmarkSettings = () => {
const { userBookmarks } = useBookmarks()
const inputFile = useRef<HTMLInputElement | null>(null)
const {initState, userBookmarks } = useBookmarks()

const importBookmarks = () => {
inputFile.current?.click()
}

const exportBookmarks = () => {
const blob = new Blob([JSON.stringify(userBookmarks, null, 2)], {
type: 'application/json',
})
const downloadURL = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = downloadURL;
link.download = "hackertabBookmarks";
link.click();
toast('Your bookmarks have been successfully exported', { theme: 'defaultToast' })
}
const handleFileChange = (event: any) => {
const file = event.target.files?.[0];
if (file && file.type === 'application/json') {
const reader = new FileReader()
reader.onload = () => {
const importData: BookmarkedPost[] = JSON.parse(reader.result as string);
const validatedData = importData.filter(
(data: BookmarkedPost) =>
data.title &&
data.url &&
!userBookmarks.some((bm) => bm.title === data.title && bm.url === data.url))
.map((data) => ({
title: data.title,
url: data.url,
source: data.source || '',
sourceType: data.sourceType || '',
}));
initState({
userBookmarks: [...userBookmarks, ...validatedData],
});
toast('Your bookmarks have been successfully imported', { theme: 'defaultToast' })
}
reader.readAsText(file)
}
}


return (
<SettingsContentLayout
title="Bookmarks"
description="Find all your bookmarks here. You can remove a bookmark by clicking on the remove icon.">
<div className="bookmarks">
{userBookmarks.map((bm) => (
<BookmarkItem item={bm} key={bm.url} />
))}
<>
<div className="btn-group">
<div>
<input
type="file"
id="file"
ref={inputFile}
style={{ display: 'none' }}
onChange={handleFileChange}
/>
<button className="notbtn btn" onClick={() => importBookmarks()}>
Import
</button>
</div>
<button className="notbtn btn" onClick={() => exportBookmarks()}>
Export
</button>
</div>
</SettingsContentLayout>
<SettingsContentLayout
title="Bookmarks"
description="Find all your bookmarks here. You can remove a bookmark by clicking on the remove icon.">
<div className="bookmarks">
{userBookmarks.map((bm) => (
<BookmarkItem item={bm} key={bm.url} />
))}
</div>
</SettingsContentLayout>
</>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,31 @@
align-items: center;
justify-content: center;
}

/* Export/Import Bookmark Buttons */

/* removing that ugly default button design */
.notbtn {
background: none;
color: inherit;
border: none;
padding: 0;
font: inherit;
cursor: pointer;
outline: inherit;
}

.btn-group {
padding: 10px;
display: flex;
}

.btn {
border-radius: 12px;
padding: 6px 12px;
margin-right: 5px;
background-color: var(--chip-background);
}
.btn:hover {
filter: brightness(85%);
}

0 comments on commit d10217a

Please sign in to comment.