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

Feature/1267 refactor bookmarks plugin #1270

Merged
merged 19 commits into from
Feb 3, 2023
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
2 changes: 1 addition & 1 deletion new-client/public/simpleMapConfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@
"index": 15
},
{
"type": "bookmark",
"type": "bookmarks",
"options": {
"target": "toolbar",
"instruction": "",
Expand Down
90 changes: 43 additions & 47 deletions new-client/src/plugins/Bookmarks/Bookmarks.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,64 +5,60 @@ import BookmarksModel from "./BookmarksModel";
import BookmarksView from "./BookmarksView";
import BookmarksIcon from "@mui/icons-material/Bookmarks";

// Constants
import { STORAGE_KEY } from "./constants";

/**
* @summary Main class for the Bookmarks plugin.
* @description The Bookmarks plugin allows the user to store bookmarks
* in localStorage. A bookmark contains the map, x,y, zoom level, visible layers etc.
*
* @class Bookmarks
* @extends {React.PureComponent}
* @extends {React.Component}
*/
class Bookmarks extends React.PureComponent {
state = {
title: "Bokmärken",
color: null,
};

static propTypes = {
app: PropTypes.object.isRequired,
map: PropTypes.object.isRequired,
options: PropTypes.object.isRequired,
};
const Bookmarks = (props) => {
const [bookmarksModel] = React.useState(
() =>
new BookmarksModel({
app: props.app,
map: props.map,
storageKey: STORAGE_KEY,
})
);
const [bookmarks, setBookmarks] = React.useState(bookmarksModel.bookmarks);

static defaultProps = {
options: {},
};
// Read bookmarks from local storage on component mount
React.useEffect(() => {
bookmarksModel.readFromStorage();
setBookmarks(bookmarksModel.bookmarks);
}, [bookmarksModel]);

constructor(props) {
super(props);
this.bookmarksModel = new BookmarksModel({
app: props.app,
map: props.map,
});
}
return (
<BaseWindowPlugin
{...props}
type="Bookmarks"
custom={{
icon: <BookmarksIcon />,
title: "Bokmärken",
description: "Användarens bokmärken",
height: 450,
width: 400,
}}
>
<BookmarksView model={bookmarksModel} bookmarks={bookmarks} />
</BaseWindowPlugin>
);
};

updateCustomProp = (prop, value) => {
this.setState({ [prop]: value });
};
Bookmarks.propTypes = {
app: PropTypes.object.isRequired,
map: PropTypes.object.isRequired,
options: PropTypes.object,
};

render() {
return (
<BaseWindowPlugin
{...this.props}
type="Bookmarks"
custom={{
icon: <BookmarksIcon />,
title: this.state.title,
color: this.state.color,
description: "Användarens bokmärken",
height: 450,
width: 400,
}}
>
<BookmarksView
model={this.bookmarksModel}
app={this.props.app}
updateCustomProp={this.updateCustomProp}
/>
</BaseWindowPlugin>
);
}
}
Bookmarks.defaultProps = {
options: {},
};

export default Bookmarks;
110 changes: 61 additions & 49 deletions new-client/src/plugins/Bookmarks/BookmarksModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,16 @@
*/

import { isValidLayerId } from "../../utils/Validator";

const bookmarksVersion = "1.0";
const storageKey = `bookmarks_v${bookmarksVersion}`;
import LocalStorageHelper from "../../utils/LocalStorageHelper";

class BookmarksModel {
#storageKey;

constructor(settings) {
this.map = settings.map;
this.app = settings.app;
this.bookmarks = [];

this.readFromStorage();
this.bookmarks = this.readFromStorage() || {};
this.#storageKey = settings.storageKey || "bookmarks";
}

getVisibleLayers() {
Expand Down Expand Up @@ -69,40 +68,65 @@ class BookmarksModel {
};
}

setMapStateFromBookmarkIndex(index) {
let bookmark = this.bookmarks[index];
if (bookmark) {
this.setMapState(bookmark);
}
}

setMapState(bookmark) {
if (!bookmark) {
return;
}

let bm = this.getDecodedBookmark(bookmark);
this.setVisibleLayers(bm.settings.l);
bookmark = this.getDecodedBookmark(bookmark);
this.setVisibleLayers(bookmark.settings.l);
let view = this.map.getView();
view.setCenter([bm.settings.x, bm.settings.y]);
view.setZoom(bm.settings.z);
bm = null;
view.setCenter([bookmark.settings.x, bookmark.settings.y]);
view.setZoom(bookmark.settings.z);
bookmark = null;
}

readFromStorage() {
let storedBookmarks = localStorage.getItem(storageKey);
if (!storedBookmarks) {
let emptyJSONArr = "[]";
// Check if we have legacy bookmarks in localStorage.
if (localStorage.getItem("bookmarks_v1.0")) {
// TODO: Describe in https://github.com/hajkmap/Hajk/wiki/Cookies-in-Hajk and add the functionalOk() hook
localStorage.setItem(storageKey, emptyJSONArr);
storedBookmarks = emptyJSONArr;
const legacyBookmarks = JSON.parse(
localStorage.getItem("bookmarks_v1.0")
);
const newBookmarks = {};
legacyBookmarks.forEach((bookmark) => {
const decodedBookmark = this.getDecodedBookmark(bookmark);
if (!decodedBookmark) return;
const keyName = decodedBookmark.settings.m || this.app.config.activeMap;
try {
LocalStorageHelper.setKeyName(keyName);
} catch (error) {
console.log(
`An error occurred while trying to set the bookmarks in localStorage: ${error}`
);
}

const inStorage = LocalStorageHelper.get(
this.#storageKey || "bookmarks"
);
newBookmarks[keyName] = inStorage || {};
newBookmarks[keyName][decodedBookmark.name] = {
settings: bookmark.settings,
};

LocalStorageHelper.set(
this.#storageKey || "bookmarks",
newBookmarks[keyName]
);
});

localStorage.removeItem("bookmarks_v1.0");

// Change back to current map.
LocalStorageHelper.setKeyName(this.app.config.activeMap);
}
this.bookmarks = JSON.parse(storedBookmarks);

const inStorage = LocalStorageHelper.get(this.#storageKey);
this.bookmarks = inStorage || {};
}

writeToStorage() {
// TODO: Describe in https://github.com/hajkmap/Hajk/wiki/Cookies-in-Hajk and add the functionalOk() hook
localStorage.setItem(storageKey, JSON.stringify(this.bookmarks));
LocalStorageHelper.set(this.#storageKey, this.bookmarks);
}

getDecodedBookmark(bookmark) {
Expand All @@ -115,7 +139,7 @@ class BookmarksModel {
}

bookmarkWithNameExists(name) {
return this.bookmarks.find((bookmark) => bookmark.name === name);
return Object.keys(this.bookmarks).includes(name);
}

replaceBookmark(bookmark) {
Expand All @@ -126,33 +150,21 @@ class BookmarksModel {
}

addBookmark(name, allowReplace = false) {
let bookmark = this.bookmarkWithNameExists(name);

if (bookmark) {
if (allowReplace === true) {
this.replaceBookmark(bookmark);
}
return false;
// Check if bookmark exist and if we should replace it.
if (this.bookmarkWithNameExists(name) && allowReplace) {
this.replaceBookmark(this.bookmarks[name]);
return;
}

let settings = this.getMapState();
this.bookmarks.push({
name: name,
settings: btoa(JSON.stringify(settings)),
sortOrder: 0,
favorite: false,
});
this.bookmarks[name] = {
settings: btoa(JSON.stringify(this.getMapState())),
};
this.writeToStorage();

return true;
}

removeBookmark(bookmark) {
let index = this.bookmarks.indexOf(bookmark);
if (index > -1) {
this.bookmarks.splice(index, 1);
this.writeToStorage();
}
deleteBookmark(name) {
delete this.bookmarks[name];
this.writeToStorage();
}
}

Expand Down
Loading