[refactor] improve link binding, search matching and feedback when no bookmarks

This commit is contained in:
Kombie 2019-01-13 22:54:48 +00:00 committed by GitHub
parent 20d6691220
commit dce3f48a99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 267 additions and 132 deletions

View File

@ -40,7 +40,7 @@ input[type="reset"]:focus,
input[type="submit"]:hover, input[type="submit"]:hover,
input[type="submit"]:focus { input[type="submit"]:focus {
background-color: var(--gray-03); background-color: var(--gray-03);
border-bottom-color: rgb(var(--accent)); border-bottom-color: var(--gray-08);
color: var(--white); color: var(--white);
outline: 0; outline: 0;
} }
@ -51,6 +51,7 @@ input[type="button"]:active,
input[type="reset"]:active, input[type="reset"]:active,
input[type="submit"]:active { input[type="submit"]:active {
background-color: var(--gray-04); background-color: var(--gray-04);
border-bottom-color: rgb(var(--accent));
color: var(--white); color: var(--white);
transition: none; transition: none;
} }

View File

@ -72,7 +72,7 @@ input[type="search"]:hover,
input[type="tel"]:hover, input[type="tel"]:hover,
input[type="text"]:hover { input[type="text"]:hover {
background-color: var(--gray-16); background-color: var(--gray-16);
border-color: rgb(var(--accent)); border-color: var(--gray-10);
color: var(--black); color: var(--black);
outline: 0; outline: 0;
} }
@ -300,17 +300,32 @@ input[type="checkbox"]:focus+.input-label-button,
input[type="radio"]:hover+.input-label-button, input[type="radio"]:hover+.input-label-button,
input[type="radio"]:focus+.input-label-button { input[type="radio"]:focus+.input-label-button {
background-color: var(--gray-03); background-color: var(--gray-03);
border-bottom-color: rgb(var(--accent)); border-bottom-color: var(--gray-10);
color: var(--white); color: var(--white);
outline: 0; outline: 0;
} }
input[type="color"]:active+.input-label-button,
input[type="checkbox"]:active+.input-label-button,
input[type="radio"]:active+.input-label-button {
border-bottom-color: rgb(var(--accent));
}
input[type="color"]:checked+.input-label-button, input[type="color"]:checked+.input-label-button,
input[type="checkbox"]:checked+.input-label-button, input[type="checkbox"]:checked+.input-label-button,
input[type="radio"]:checked+.input-label-button { input[type="radio"]:checked+.input-label-button {
border-bottom-color: rgb(var(--accent)); border-bottom-color: rgb(var(--accent));
} }
input[type="color"][disabled]+.input-label-button,
input[type="checkbox"][disabled]+.input-label-button,
input[type="radio"][disabled]+.input-label-button {
background-color: var(--gray-02);
border-color: transparent;
color: var(--gray-04);
cursor: default;
}
input[type="checkbox"][disabled]+label, input[type="checkbox"][disabled]+label,
input[type="radio"][disabled]+label { input[type="radio"][disabled]+label {
color: var(--gray-04); color: var(--gray-04);

View File

@ -19,9 +19,6 @@
} }
.header-item { .header-item {
margin-left: var(--gutter);
margin-right: var(--gutter);
margin-bottom: 1em;
margin: var(--gutter); margin: var(--gutter);
display: flex; display: flex;
flex-wrap: nowrap; flex-wrap: nowrap;

View File

@ -230,6 +230,16 @@
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.link-empty {
grid-column-start: 1;
grid-column-end: -1;
text-align: center;
}
.link-empty-heading {
color: var(--gray-04);
}
.is-link-block .link-name { .is-link-block .link-name {
text-align: center; text-align: center;
} }

View File

@ -70,7 +70,7 @@
</label> </label>
</div> </div>
</div> </div>
<div class="header-item"> <div class="header-item header-menu">
<button class="button mb-0 control-menu" tabindex="1"> <button class="button mb-0 control-menu" tabindex="1">
<span class="button-text"><span class="icon-settings"></span></span> <span class="button-text"><span class="icon-settings"></span></span>
</button> </button>
@ -252,13 +252,6 @@
<label for="control-link-sort-letter"><span class="label-icon"></span>Letter</label> <label for="control-link-sort-letter"><span class="label-icon"></span>Letter</label>
</div> </div>
</div> </div>
<div class="menu-item">
<h1 class="menu-header">Theme</h1>
<div class="checkbox-wrap">
<input id="control-layout-theme-random" class="control-layout-theme-random" type="checkbox" tabindex="1">
<label for="control-layout-theme-random"><span class="label-icon"></span>Random Accent colour on load/refresh</label>
</div>
</div>
</div> </div>
<div class="menu-content-area menu-content-area-layout is-hidden"> <div class="menu-content-area menu-content-area-layout is-hidden">
<div class="menu-item"> <div class="menu-item">
@ -283,6 +276,13 @@
<label for="control-layout-scroll-past-end"><span class="label-icon"></span>Scroll past end</label> <label for="control-layout-scroll-past-end"><span class="label-icon"></span>Scroll past end</label>
</div> </div>
</div> </div>
<div class="menu-item">
<h1 class="menu-header">Theme</h1>
<div class="checkbox-wrap">
<input id="control-layout-theme-random" class="control-layout-theme-random" type="checkbox" tabindex="1">
<label for="control-layout-theme-random"><span class="label-icon"></span>Random Accent colour on load/refresh</label>
</div>
</div>
</div> </div>
</div> </div>

View File

@ -134,14 +134,16 @@ var bookmarks = (function() {
var get = function(timeStamp) { var get = function(timeStamp) {
var _singleBookmark = function() { var _singleBookmark = function() {
var found = false;
for (var i = 0; i < all.length; i++) { for (var i = 0; i < all.length; i++) {
if (all[i].timeStamp === timeStamp) { if (all[i].timeStamp === timeStamp) {
return all[i]; found = all[i];
}; };
}; };
return found;
}; };
var _allBookmarks = function() { var _allBookmarks = function() {
var by = { var action = {
none: function(array) { none: function(array) {
return helper.sortObject(array, "timeStamp"); return helper.sortObject(array, "timeStamp");
}, },
@ -152,9 +154,9 @@ var bookmarks = (function() {
return helper.sortObject(array, "letter"); return helper.sortObject(array, "letter");
} }
}; };
return by[state.get().link.sort](all); return action[state.get().link.sort](all);
}; };
if (timeStamp) { if (timeStamp && typeof timeStamp == "number") {
return _singleBookmark(timeStamp); return _singleBookmark(timeStamp);
} else { } else {
return _allBookmarks(); return _allBookmarks();

View File

@ -108,7 +108,19 @@ var control = (function() {
_layout(); _layout();
}; };
var _dependents = function() { var dependents = function() {
var _edit = function() {
if (bookmarks.get().length > 0) {
helper.e(".control-edit").disabled = false;
} else {
helper.e(".control-edit").disabled = true;
helper.e(".control-edit").checked = false;
state.change({
path: "edit.active",
value: false
});
};
};
var _date = function() { var _date = function() {
var activeCount = 0; var activeCount = 0;
var toCheck = [state.get().header.date.show.date, state.get().header.date.show.day, state.get().header.date.show.month, state.get().header.date.show.year]; var toCheck = [state.get().header.date.show.date, state.get().header.date.show.day, state.get().header.date.show.month, state.get().header.date.show.year];
@ -180,6 +192,7 @@ var control = (function() {
helper.e(".control-header-search-engine-custom-url").disabled = true; helper.e(".control-header-search-engine-custom-url").disabled = true;
}; };
}; };
_edit();
_date(); _date();
_clock(); _clock();
_search(); _search();
@ -198,6 +211,7 @@ var control = (function() {
value: this.checked value: this.checked
}); });
render(); render();
dependents();
data.save(); data.save();
}, false); }, false);
helper.e(".control-layout-theme").addEventListener("change", function() { helper.e(".control-layout-theme").addEventListener("change", function() {
@ -252,7 +266,7 @@ var control = (function() {
value: this.checked value: this.checked
}); });
render(); render();
_dependents(); dependents();
header.render(); header.render();
data.save(); data.save();
}, false); }, false);
@ -262,7 +276,7 @@ var control = (function() {
value: this.checked value: this.checked
}); });
render(); render();
_dependents(); dependents();
header.render(); header.render();
data.save(); data.save();
}, false); }, false);
@ -273,7 +287,7 @@ var control = (function() {
value: this.value value: this.value
}); });
render(); render();
_dependents(); dependents();
search.update(); search.update();
data.save(); data.save();
}, false); }, false);
@ -292,7 +306,7 @@ var control = (function() {
value: this.checked value: this.checked
}); });
render(); render();
_dependents(); dependents();
date.clear(); date.clear();
date.render(); date.render();
header.render(); header.render();
@ -304,7 +318,7 @@ var control = (function() {
value: this.checked value: this.checked
}); });
render(); render();
_dependents(); dependents();
date.clear(); date.clear();
date.render(); date.render();
header.render(); header.render();
@ -316,7 +330,7 @@ var control = (function() {
value: this.checked value: this.checked
}); });
render(); render();
_dependents(); dependents();
date.clear(); date.clear();
date.render(); date.render();
header.render(); header.render();
@ -328,7 +342,7 @@ var control = (function() {
value: this.checked value: this.checked
}); });
render(); render();
_dependents(); dependents();
date.clear(); date.clear();
date.render(); date.render();
header.render(); header.render();
@ -340,7 +354,7 @@ var control = (function() {
value: this.checked value: this.checked
}); });
render(); render();
_dependents(); dependents();
date.clear(); date.clear();
date.render(); date.render();
header.render(); header.render();
@ -365,7 +379,7 @@ var control = (function() {
value: this.checked value: this.checked
}); });
render(); render();
_dependents(); dependents();
clock.clear(); clock.clear();
clock.render(); clock.render();
header.render(); header.render();
@ -377,7 +391,7 @@ var control = (function() {
value: this.checked value: this.checked
}); });
render(); render();
_dependents(); dependents();
clock.clear(); clock.clear();
clock.render(); clock.render();
header.render(); header.render();
@ -389,7 +403,7 @@ var control = (function() {
value: this.checked value: this.checked
}); });
render(); render();
_dependents(); dependents();
clock.clear(); clock.clear();
clock.render(); clock.render();
header.render(); header.render();
@ -410,7 +424,7 @@ var control = (function() {
path: "header.clock.hour24", path: "header.clock.hour24",
value: this.checked value: this.checked
}); });
_dependents(); dependents();
clock.clear(); clock.clear();
clock.render(); clock.render();
header.render(); header.render();
@ -508,15 +522,16 @@ var control = (function() {
var init = function() { var init = function() {
_bind(); _bind();
update(); update();
_dependents(); dependents();
render(); render();
}; };
// exposed methods // exposed methods
return { return {
init: init, init: init,
update: update, render: render,
render: render dependents: dependents,
update: update
}; };
})(); })();

View File

@ -10,7 +10,7 @@ var data = (function() {
return localStorage.getItem(key); return localStorage.getItem(key);
}; };
var clear = function(key) { var remove = function(key) {
localStorage.removeItem(key); localStorage.removeItem(key);
}; };
@ -24,6 +24,10 @@ var data = (function() {
console.log("data saved"); console.log("data saved");
}; };
var wipe = function() {
remove(saveName);
};
var load = function() { var load = function() {
var data = JSON.parse(get(saveName)); var data = JSON.parse(get(saveName));
return data; return data;
@ -48,14 +52,10 @@ var data = (function() {
_checkForSavedData(load()); _checkForSavedData(load());
}; };
var wipe = function() {
clear(saveName);
};
return { return {
init: init, init: init,
save: save, save: save,
clear: clear, remove: remove,
set: set, set: set,
get: get, get: get,
load: load, load: load,

View File

@ -113,10 +113,7 @@ var helper = (function() {
var makeNode = function(override) { var makeNode = function(override) {
var options = { var options = {
tag: null, tag: null,
classes: null,
text: null, text: null,
url: null,
index: null,
attr: null attr: null
}; };
if (override) { if (override) {

View File

@ -3,7 +3,8 @@ var link = (function() {
var _bind = function(override) { var _bind = function(override) {
var options = { var options = {
element: null, element: null,
action: null action: null,
bookmarkData: null
}; };
if (override) { if (override) {
options = helper.applyOptions(options, override); options = helper.applyOptions(options, override);
@ -11,88 +12,98 @@ var link = (function() {
var action = { var action = {
edit: function() { edit: function() {
options.element.addEventListener("click", function() { options.element.addEventListener("click", function() {
edit(this); edit(options.bookmarkData);
}, false); }, false);
}, },
delete: function() { remove: function() {
options.element.addEventListener("click", function() { options.element.addEventListener("click", function() {
remove(this); remove(options.bookmarkData);
control.dependents();
control.render();
}, false); }, false);
} }
}; };
if (options.element != null) { if (options.element != null) {
action[options.action](); action[options.action]();
} };
}; };
var add = function() { var edit = function(bookmarkData) {
state.get().link.action = "add"; var currentBookmark = bookmarks.get(bookmarkData.timeStamp);
var form = _makeLinkForm();
modal.render({
heading: "Add a new bookmark",
action: save,
actionText: "Add",
size: "small",
content: form
});
};
var edit = function(button) {
state.get().link.action = "edit";
state.get().link.editObject = bookmarks.get(parseInt(button.closest(".link-item").dataset.timeStamp, 10));
var currentBookmark = bookmarks.get(state.get().link.editObject.timeStamp);
var form = _makeLinkForm(); var form = _makeLinkForm();
form.querySelector(".link-form-input-letter").value = currentBookmark.letter; form.querySelector(".link-form-input-letter").value = currentBookmark.letter;
form.querySelector(".link-form-input-name").value = currentBookmark.name; form.querySelector(".link-form-input-name").value = currentBookmark.name;
form.querySelector(".link-form-input-url").value = currentBookmark.url; form.querySelector(".link-form-input-url").value = currentBookmark.url;
modal.render({ modal.render({
heading: "Edit " + currentBookmark.name, heading: "Edit " + currentBookmark.name,
action: save, action: function() {
save({
action: "edit",
form: form,
bookmarkData: bookmarkData
});
},
actionText: "Save", actionText: "Save",
size: "small", size: "small",
content: form content: form
}); });
}; };
var save = function(button) { var add = function() {
var action = { var form = _makeLinkForm();
add: function(newLinkData) { modal.render({
newLinkData.timeStamp = new Date().getTime(); heading: "Add a new bookmark",
bookmarks.add(newLinkData); action: function() {
save({
action: "add",
form: form
});
control.dependents();
control.render();
}, },
edit: function(newLinkData) { actionText: "Add",
newLinkData.timeStamp = state.get().link.editObject.timeStamp; size: "small",
bookmarks.edit(newLinkData, state.get().link.editObject.timeStamp); content: form
} });
};
var form = helper.e(".link-form");
var newLinkData = {
letter: form.querySelector(".link-form-input-letter").value,
name: form.querySelector(".link-form-input-name").value,
url: form.querySelector(".link-form-input-url").value
};
action[state.get().link.action](newLinkData);
state.get().link.editObject = null;
state.get().link.action = null;
clear();
if (state.get().header.search.searching) {
search.render();
} else {
render();
};
data.save();
}; };
var remove = function(button) { var save = function(override) {
var timeStamp = parseInt(button.closest(".link-item").dataset.timeStamp, 10); var options = {
bookmarks.remove(timeStamp); action: null,
clear(); form: null,
if (state.get().header.search.searching) { bookmarkData: null
search.render();
} else {
render();
}; };
if (override) {
options = helper.applyOptions(options, override);
};
var action = {
add: function() {
var newBookmarkData = {
letter: options.form.querySelector(".link-form-input-letter").value,
name: options.form.querySelector(".link-form-input-name").value,
url: options.form.querySelector(".link-form-input-url").value,
timeStamp: new Date().getTime()
};
bookmarks.add(newBookmarkData);
},
edit: function() {
options.bookmarkData.letter = options.form.querySelector(".link-form-input-letter").value;
options.bookmarkData.name = options.form.querySelector(".link-form-input-name").value;
options.bookmarkData.url = options.form.querySelector(".link-form-input-url").value;
bookmarks.edit(options.bookmarkData, options.bookmarkData.timeStamp);
}
};
action[options.action]();
data.save(); data.save();
clear();
render();
};
var remove = function(bookmarkData) {
bookmarks.remove(bookmarkData.timeStamp);
data.save();
clear();
render();
}; };
var _makeLinkForm = function() { var _makeLinkForm = function() {
@ -212,9 +223,6 @@ var link = (function() {
attr: [{ attr: [{
key: "class", key: "class",
value: "link-item" value: "link-item"
}, {
key: "data-time-stamp",
value: data.timeStamp
}] }]
}); });
var linkOptions = { var linkOptions = {
@ -286,7 +294,7 @@ var link = (function() {
tag: "button", tag: "button",
attr: [{ attr: [{
key: "class", key: "class",
value: "button button-small link-control-item link-edit" value: "button button-small link-control-item"
}, { }, {
key: "tabindex", key: "tabindex",
value: -1 value: -1
@ -299,17 +307,17 @@ var link = (function() {
value: "button-icon icon-edit" value: "button-icon icon-edit"
}] }]
}); });
var linkDelete = helper.makeNode({ var linkRemove = helper.makeNode({
tag: "button", tag: "button",
attr: [{ attr: [{
key: "class", key: "class",
value: "button button-small link-control-item link-delete" value: "button button-small link-control-item"
}, { }, {
key: "tabindex", key: "tabindex",
value: -1 value: -1
}] }]
}); });
var linkDeleteIcon = helper.makeNode({ var linkRemoveIcon = helper.makeNode({
tag: "span", tag: "span",
attr: [{ attr: [{
key: "class", key: "class",
@ -319,9 +327,9 @@ var link = (function() {
linkPanelFront.appendChild(linkLetter); linkPanelFront.appendChild(linkLetter);
linkPanelFront.appendChild(linkName); linkPanelFront.appendChild(linkName);
linkEdit.appendChild(linkEditIcon); linkEdit.appendChild(linkEditIcon);
linkDelete.appendChild(linkDeleteIcon); linkRemove.appendChild(linkRemoveIcon);
linkControl.appendChild(linkEdit); linkControl.appendChild(linkEdit);
linkControl.appendChild(linkDelete); linkControl.appendChild(linkRemove);
linkUrl.appendChild(linkUrlText); linkUrl.appendChild(linkUrlText);
linkPanelBack.appendChild(linkUrl); linkPanelBack.appendChild(linkUrl);
linkPanelBack.appendChild(linkControl); linkPanelBack.appendChild(linkControl);
@ -329,21 +337,105 @@ var link = (function() {
linkItem.appendChild(linkPanelBack); linkItem.appendChild(linkPanelBack);
_bind({ _bind({
element: linkEdit, element: linkEdit,
action: "edit" action: "edit",
bookmarkData: data
}); });
_bind({ _bind({
element: linkDelete, element: linkRemove,
action: "delete" action: "remove",
bookmarkData: data
}); });
return linkItem; return linkItem;
}; };
var render = function(array) { var _makeEmptySearch = function() {
var linkArea = helper.e(".link-area"); var searchInput = helper.e(".search-input");
var bookmarksToRender = array || bookmarks.get(); var div = helper.makeNode({
bookmarksToRender.forEach(function(arrayItem) { tag: "div",
linkArea.appendChild(_makeLink(arrayItem)); attr: [{
key: "class",
value: "link-empty"
}]
}); });
var h1 = helper.makeNode({
tag: "h1",
attr: [{
key: "class",
value: "link-empty-heading"
}],
text: "No matching bookmarks found"
});
div.appendChild(h1);
return div;
};
var _makeEmptyBookmarks = function() {
var searchInput = helper.e(".search-input");
var div = helper.makeNode({
tag: "div",
attr: [{
key: "class",
value: "link-empty"
}]
});
var h1 = helper.makeNode({
tag: "h1",
attr: [{
key: "class",
value: "link-empty-heading"
}],
text: "No bookmarks added"
});
div.appendChild(h1);
return div;
};
var render = function() {
var linkArea = helper.e(".link-area");
var bookmarksToRender = false;
if (state.get().header.search.searching) {
bookmarksToRender = search.get();
} else {
bookmarksToRender = bookmarks.get();
};
var action = {
render: {
bookmarks: function(array) {
array.forEach(function(arrayItem, index) {
linkArea.appendChild(_makeLink(arrayItem));
});
},
empty: {
search: function() {
linkArea.appendChild(_makeEmptySearch());
},
bookmarks: function() {
linkArea.appendChild(_makeEmptyBookmarks());
}
}
}
};
// if searching
if (state.get().header.search.searching) {
// if bookmarks exist to be searched
if (bookmarksToRender.total > 0) {
// if matching bookmarks found
if (bookmarksToRender.matching.length > 0) {
action.render.bookmarks(bookmarksToRender.matching);
} else {
action.render.empty.search();
};
} else {
action.render.empty.bookmarks();
};
} else {
// if bookmarks exist
if (bookmarksToRender.length > 0) {
action.render.bookmarks(bookmarksToRender);
} else {
action.render.empty.bookmarks();
};
};
}; };
var tabIndex = function() { var tabIndex = function() {

View File

@ -6,7 +6,8 @@ var search = (function() {
searchInput.addEventListener("input", function() { searchInput.addEventListener("input", function() {
_toggle(this); _toggle(this);
_searchClear(); _searchClear();
render(); link.clear();
link.render();
}, false); }, false);
searchClear.addEventListener("click", function() { searchClear.addEventListener("click", function() {
_toggle(this); _toggle(this);
@ -17,9 +18,15 @@ var search = (function() {
var _toggle = function(input) { var _toggle = function(input) {
if (input.value != "") { if (input.value != "") {
state.get().header.search.searching = true; state.change({
path: "header.search.searching",
value: true
})
} else { } else {
state.get().header.search.searching = false; state.change({
path: "header.search.searching",
value: false
})
}; };
}; };
@ -33,22 +40,21 @@ var search = (function() {
}; };
}; };
var render = function() { var get = function() {
var searchInput = helper.e(".search-input"); var searchInput = helper.e(".search-input");
if (state.get().header.search.searching) { if (state.get().header.search.searching) {
var searchedBookmarks = []; var searchedBookmarks = {
total: 0,
matching: []
};
searchedBookmarks.total = bookmarks.get().length;
bookmarks.get().forEach(function(arrayItem, index) { bookmarks.get().forEach(function(arrayItem, index) {
if (arrayItem.url.replace(/^https?\:\/\//i, "").replace(/\/$/, "").toLowerCase().includes(searchInput.value.toLowerCase()) || arrayItem.name.toLowerCase().includes(searchInput.value.toLowerCase())) { if (arrayItem.url.replace(/^https?\:\/\//i, "").replace(/\/$/, "").toLowerCase().includes(searchInput.value.toLowerCase().replace(/\s/g, "")) || arrayItem.name.toLowerCase().includes(searchInput.value.toLowerCase().replace(/\s/g, ""))) {
var copy = JSON.parse(JSON.stringify(arrayItem)); var bookmarkDataCopy = JSON.parse(JSON.stringify(arrayItem));
copy.index = index; searchedBookmarks.matching.push(bookmarkDataCopy);
searchedBookmarks.push(copy);
}; };
}); });
link.clear(); return searchedBookmarks;
link.render(searchedBookmarks);
} else {
link.clear();
link.render();
}; };
}; };
@ -73,7 +79,7 @@ var search = (function() {
// exposed methods // exposed methods
return { return {
init: init, init: init,
render: render, get: get,
update: update, update: update,
clear: clear clear: clear
}; };

View File

@ -54,7 +54,6 @@ var state = (function() {
}, },
link: { link: {
editObject: null, editObject: null,
action: null,
newTab: false, newTab: false,
style: "block", style: "block",
sort: "none" sort: "none"

View File

@ -1,5 +1,6 @@
var version = (function() { var version = (function() {
// version is normally bumped when the state needs changing or any new functionality is added
var current = "2.1.0"; var current = "2.1.0";
var get = function() { var get = function() {