Make back and forward button works

This commit is contained in:
Radhi Fadlillah 2019-05-28 09:13:44 +07:00
parent 923a2c4f22
commit d35a396ad2
4 changed files with 110 additions and 39 deletions

View file

@ -24,7 +24,7 @@
<body>
<div class="home" id="app">
<div class="home-sidebar">
<a v-for="item in sidebarItems" :title="item.title" :class="{active: activePage === item.page}" @click="activePage = item.page">
<a v-for="item in sidebarItems" :title="item.title" :class="{active: activePage === item.page}" @click="switchPage(item.page)">
<i class="fas fa-fw" :class="item.icon"></i>
</a>
<div class="spacer"></div>
@ -60,9 +60,17 @@
title: "Setting",
icon: "fa-cog",
page: "page-setting",
}]
}],
historyState: {},
},
methods: {
switchPage(page) {
var pageName = page.replace("page-", ""),
state = {activePage: page};
this.activePage = page;
history.pushState(state, page, `#${pageName}`);
},
logout() {
this.showDialog({
title: "Log Out",
@ -89,6 +97,21 @@
}
});
}
},
mounted() {
// Prepare history state watcher
var stateWatcher = (e) => {
var state = e.state || {};
this.activePage = state.activePage || "page-home";
}
window.addEventListener('popstate', stateWatcher);
this.$once('hook:beforeDestroy', function () {
window.removeEventListener('popstate', stateWatcher);
})
// Set initial URL
history.replaceState(null, "page-home", "#home");
}
})
</script>

View file

@ -1,7 +1,7 @@
var template = `
<div id="page-home">
<div class="page-header">
<input type="text" placeholder="Search url, keyword or tags" v-model.trim="search" @focus="$event.target.select()" @keyup.enter="loadBookmarks()"/>
<input type="text" placeholder="Search url, keyword or tags" v-model.trim="search" @focus="$event.target.select()" @keyup.enter="searchBookmarks"/>
<a title="Refresh storage" @click="reloadData">
<i class="fas fa-fw fa-sync-alt" :class="loading && 'fa-spin'"></i>
</a>
@ -87,9 +87,12 @@ export default {
this.search = "";
this.loadBookmarks();
},
loadBookmarks() {
loadBookmarks(saveState) {
if (this.loading) return;
// By default, we eill save the state
saveState = (typeof saveState === "boolean") ? saveState : true;
// Parse search query
var rxTagA = /['"]#([^'"]+)['"]/g, // "#tag with space"
rxTagB = /(^|\s+)#(\S+)/g, // #tag-without-space
@ -130,10 +133,31 @@ export default {
return response.json();
})
.then(json => {
// Set data
this.page = json.page;
this.maxPage = json.maxPage;
this.bookmarks = json.bookmarks;
this.loading = false;
// Save state and change URL if needed
if (saveState) {
var history = {
activePage: "page-home",
search: this.search,
page: this.page
};
var urlQueries = [];
if (this.page > 1) urlQueries.push(`page=${this.page}`);
if (this.search !== "") urlQueries.push(`search=${this.search}`);
var url = "#home"
if (urlQueries.length > 0) {
url += `?${urlQueries.join("&")}`;
}
window.history.pushState(history, "page-home", url);
}
})
.catch(err => {
this.loading = false;
@ -142,9 +166,11 @@ export default {
})
});
},
searchBookmarks() {
this.page = 1;
this.loadBookmarks();
},
changePage(page) {
if (this.loading) return;
page = parseInt(page, 10) || 0;
if (page >= this.maxPage) this.page = this.maxPage;
else if (page <= 1) this.page = 1;
@ -164,6 +190,24 @@ export default {
}
},
mounted() {
this.loadBookmarks();
var stateWatcher = (e) => {
var state = e.state || {},
activePage = state.activePage || "page-home",
search = state.search || "",
page = state.page || 1;
if (activePage !== "page-home") return;
this.page = page;
this.search = search;
this.loadBookmarks(false);
}
window.addEventListener('popstate', stateWatcher);
this.$once('hook:beforeDestroy', function() {
window.removeEventListener('popstate', stateWatcher);
})
this.loadBookmarks(false);
}
}

View file

@ -93,6 +93,10 @@
})
});
}
},
mounted() {
// Set initial URL
history.replaceState(null, "login", "login");
}
})
</script>

File diff suppressed because one or more lines are too long