mirror of
https://github.com/miniflux/v2.git
synced 2025-08-06 17:41:00 +00:00
Improve naviguation
This commit is contained in:
parent
5546dd99a5
commit
0e6fc2db1e
3 changed files with 53 additions and 28 deletions
|
@ -1,5 +1,5 @@
|
||||||
// Code generated by go generate; DO NOT EDIT.
|
// Code generated by go generate; DO NOT EDIT.
|
||||||
// 2017-12-03 17:25:29.409871548 -0800 PST m=+0.022898473
|
// 2017-12-04 20:40:04.511740583 -0800 PST m=+0.012182340
|
||||||
|
|
||||||
package static
|
package static
|
||||||
|
|
||||||
|
@ -41,30 +41,30 @@ withCallback(callback){this.callback=callback;return this;}
|
||||||
getCsrfToken(){let element=document.querySelector("meta[name=X-CSRF-Token]");if(element!==null){return element.getAttribute("value");}
|
getCsrfToken(){let element=document.querySelector("meta[name=X-CSRF-Token]");if(element!==null){return element.getAttribute("value");}
|
||||||
return "";}
|
return "";}
|
||||||
execute(){fetch(new Request(this.url,this.options)).then((response)=>{if(this.callback){this.callback(response);}});}}
|
execute(){fetch(new Request(this.url,this.options)).then((response)=>{if(this.callback){this.callback(response);}});}}
|
||||||
class EntryHandler{static updateEntriesStatus(entryIDs,status){let url=document.body.dataset.entriesStatusUrl;let request=new RequestBuilder(url);request.withBody({entry_ids:entryIDs,status:status});request.execute();}
|
class EntryHandler{static updateEntriesStatus(entryIDs,status,callback){let url=document.body.dataset.entriesStatusUrl;let request=new RequestBuilder(url);request.withBody({entry_ids:entryIDs,status:status});request.withCallback(callback);request.execute();}
|
||||||
static toggleEntryStatus(element){let entryID=parseInt(element.dataset.id,10);let statuses={read:"unread",unread:"read"};for(let currentStatus in statuses){let newStatus=statuses[currentStatus];if(element.classList.contains("item-status-"+currentStatus)){element.classList.remove("item-status-"+currentStatus);element.classList.add("item-status-"+newStatus);this.updateEntriesStatus([entryID],newStatus);break;}}}
|
static toggleEntryStatus(element){let entryID=parseInt(element.dataset.id,10);let statuses={read:"unread",unread:"read"};for(let currentStatus in statuses){let newStatus=statuses[currentStatus];if(element.classList.contains("item-status-"+currentStatus)){element.classList.remove("item-status-"+currentStatus);element.classList.add("item-status-"+newStatus);this.updateEntriesStatus([entryID],newStatus);break;}}}
|
||||||
|
static markEntryAsRead(element){if(element.classList.contains("item-status-unread")){element.classList.remove("item-status-unread");element.classList.add("item-status-read");let entryID=parseInt(element.dataset.id,10);this.updateEntriesStatus([entryID],"read");}}
|
||||||
static saveEntry(element){if(element.dataset.completed){return;}
|
static saveEntry(element){if(element.dataset.completed){return;}
|
||||||
element.innerHTML=element.dataset.labelLoading;let request=new RequestBuilder(element.dataset.saveUrl);request.withCallback(()=>{element.innerHTML=element.dataset.labelDone;element.dataset.completed=true;});request.execute();}}
|
element.innerHTML=element.dataset.labelLoading;let request=new RequestBuilder(element.dataset.saveUrl);request.withCallback(()=>{element.innerHTML=element.dataset.labelDone;element.dataset.completed=true;});request.execute();}}
|
||||||
class ConfirmHandler{remove(url){let request=new RequestBuilder(url);request.withCallback(()=>window.location.reload());request.execute();}
|
class ConfirmHandler{remove(url){let request=new RequestBuilder(url);request.withCallback(()=>window.location.reload());request.execute();}
|
||||||
handle(event){let questionElement=document.createElement("span");let linkElement=event.target;let containerElement=linkElement.parentNode;linkElement.style.display="none";let yesElement=document.createElement("a");yesElement.href="#";yesElement.appendChild(document.createTextNode(linkElement.dataset.labelYes));yesElement.onclick=(event)=>{event.preventDefault();let loadingElement=document.createElement("span");loadingElement.className="loading";loadingElement.appendChild(document.createTextNode(linkElement.dataset.labelLoading));questionElement.remove();containerElement.appendChild(loadingElement);this.remove(linkElement.dataset.url);};let noElement=document.createElement("a");noElement.href="#";noElement.appendChild(document.createTextNode(linkElement.dataset.labelNo));noElement.onclick=(event)=>{event.preventDefault();linkElement.style.display="inline";questionElement.remove();};questionElement.className="confirm";questionElement.appendChild(document.createTextNode(linkElement.dataset.labelQuestion+" "));questionElement.appendChild(yesElement);questionElement.appendChild(document.createTextNode(", "));questionElement.appendChild(noElement);containerElement.appendChild(questionElement);}}
|
handle(event){let questionElement=document.createElement("span");let linkElement=event.target;let containerElement=linkElement.parentNode;linkElement.style.display="none";let yesElement=document.createElement("a");yesElement.href="#";yesElement.appendChild(document.createTextNode(linkElement.dataset.labelYes));yesElement.onclick=(event)=>{event.preventDefault();let loadingElement=document.createElement("span");loadingElement.className="loading";loadingElement.appendChild(document.createTextNode(linkElement.dataset.labelLoading));questionElement.remove();containerElement.appendChild(loadingElement);this.remove(linkElement.dataset.url);};let noElement=document.createElement("a");noElement.href="#";noElement.appendChild(document.createTextNode(linkElement.dataset.labelNo));noElement.onclick=(event)=>{event.preventDefault();linkElement.style.display="inline";questionElement.remove();};questionElement.className="confirm";questionElement.appendChild(document.createTextNode(linkElement.dataset.labelQuestion+" "));questionElement.appendChild(yesElement);questionElement.appendChild(document.createTextNode(", "));questionElement.appendChild(noElement);containerElement.appendChild(questionElement);}}
|
||||||
class MenuHandler{clickMenuListItem(event){let element=event.target;if(element.tagName==="A"){window.location.href=element.getAttribute("href");}else{window.location.href=element.querySelector("a").getAttribute("href");}}
|
class MenuHandler{clickMenuListItem(event){let element=event.target;if(element.tagName==="A"){window.location.href=element.getAttribute("href");}else{window.location.href=element.querySelector("a").getAttribute("href");}}
|
||||||
toggleMainMenu(){let menu=document.querySelector(".header nav ul");if(DomHelper.isVisible(menu)){menu.style.display="none";}else{menu.style.display="block";}}}
|
toggleMainMenu(){let menu=document.querySelector(".header nav ul");if(DomHelper.isVisible(menu)){menu.style.display="none";}else{menu.style.display="block";}}}
|
||||||
class NavHandler{markPageAsRead(){let items=DomHelper.getVisibleElements(".items .item");let entryIDs=[];items.forEach((element)=>{element.classList.add("item-status-read");entryIDs.push(parseInt(element.dataset.id,10));});if(entryIDs.length>0){EntryHandler.updateEntriesStatus(entryIDs,"read");}
|
class NavHandler{markPageAsRead(){let items=DomHelper.getVisibleElements(".items .item");let entryIDs=[];items.forEach((element)=>{element.classList.add("item-status-read");entryIDs.push(parseInt(element.dataset.id,10));});if(entryIDs.length>0){EntryHandler.updateEntriesStatus(entryIDs,"read",()=>{this.goToPage("next",true);});}}
|
||||||
this.goToPage("next");}
|
|
||||||
saveEntry(){if(this.isListView()){let currentItem=document.querySelector(".current-item");if(currentItem!==null){let saveLink=currentItem.querySelector("a[data-save-entry]");if(saveLink){EntryHandler.saveEntry(saveLink);}}}else{let saveLink=document.querySelector("a[data-save-entry]");if(saveLink){EntryHandler.saveEntry(saveLink);}}}
|
saveEntry(){if(this.isListView()){let currentItem=document.querySelector(".current-item");if(currentItem!==null){let saveLink=currentItem.querySelector("a[data-save-entry]");if(saveLink){EntryHandler.saveEntry(saveLink);}}}else{let saveLink=document.querySelector("a[data-save-entry]");if(saveLink){EntryHandler.saveEntry(saveLink);}}}
|
||||||
toggleEntryStatus(){let currentItem=document.querySelector(".current-item");if(currentItem!==null){EntryHandler.toggleEntryStatus(currentItem);this.goToNextListItem();}}
|
toggleEntryStatus(){let currentItem=document.querySelector(".current-item");if(currentItem!==null){this.goToNextListItem();EntryHandler.toggleEntryStatus(currentItem);}}
|
||||||
openOriginalLink(){let entryLink=document.querySelector(".entry h1 a");if(entryLink!==null){DomHelper.openNewTab(entryLink.getAttribute("href"));return;}
|
openOriginalLink(){let entryLink=document.querySelector(".entry h1 a");if(entryLink!==null){DomHelper.openNewTab(entryLink.getAttribute("href"));return;}
|
||||||
let currentItemOriginalLink=document.querySelector(".current-item a[data-original-link]");if(currentItemOriginalLink!==null){DomHelper.openNewTab(currentItemOriginalLink.getAttribute("href"));}}
|
let currentItemOriginalLink=document.querySelector(".current-item a[data-original-link]");if(currentItemOriginalLink!==null){DomHelper.openNewTab(currentItemOriginalLink.getAttribute("href"));let currentItem=document.querySelector(".current-item");this.goToNextListItem();EntryHandler.markEntryAsRead(currentItem);}}
|
||||||
openSelectedItem(){let currentItemLink=document.querySelector(".current-item .item-title a");if(currentItemLink!==null){window.location.href=currentItemLink.getAttribute("href");}}
|
openSelectedItem(){let currentItemLink=document.querySelector(".current-item .item-title a");if(currentItemLink!==null){window.location.href=currentItemLink.getAttribute("href");}}
|
||||||
goToPage(page){let element=document.querySelector("a[data-page="+page+"]");if(element){document.location.href=element.href;}}
|
goToPage(page,fallbackSelf){let element=document.querySelector("a[data-page="+page+"]");if(element){document.location.href=element.href;}else if(fallbackSelf){window.location.reload();}}
|
||||||
goToPrevious(){if(this.isListView()){this.goToPreviousListItem();}else{this.goToPage("previous");}}
|
goToPrevious(){if(this.isListView()){this.goToPreviousListItem();}else{this.goToPage("previous");}}
|
||||||
goToNext(){if(this.isListView()){this.goToNextListItem();}else{this.goToPage("next");}}
|
goToNext(){if(this.isListView()){this.goToNextListItem();}else{this.goToPage("next");}}
|
||||||
goToPreviousListItem(){let items=DomHelper.getVisibleElements(".items .item");if(items.length===0){return;}
|
goToPreviousListItem(){let items=DomHelper.getVisibleElements(".items .item");if(items.length===0){return;}
|
||||||
if(document.querySelector(".current-item")===null){items[0].classList.add("current-item");return;}
|
if(document.querySelector(".current-item")===null){items[0].classList.add("current-item");return;}
|
||||||
for(let i=0;i<items.length;i++){if(items[i].classList.contains("current-item")){items[i].classList.remove("current-item");if(i-1>=0){items[i-1].classList.add("current-item");DomHelper.scrollPageTo(items[i-1]);}
|
for(let i=0;i<items.length;i++){if(items[i].classList.contains("current-item")){items[i].classList.remove("current-item");if(i-1>=0){items[i-1].classList.add("current-item");DomHelper.scrollPageTo(items[i-1]);}
|
||||||
break;}}}
|
break;}}}
|
||||||
goToNextListItem(){let items=DomHelper.getVisibleElements(".items .item");if(items.length===0){return;}
|
goToNextListItem(){let currentItem=document.querySelector(".current-item");let items=DomHelper.getVisibleElements(".items .item");if(items.length===0){return;}
|
||||||
if(document.querySelector(".current-item")===null){items[0].classList.add("current-item");return;}
|
if(currentItem===null){items[0].classList.add("current-item");return;}
|
||||||
for(let i=0;i<items.length;i++){if(items[i].classList.contains("current-item")){items[i].classList.remove("current-item");if(i+1<items.length){items[i+1].classList.add("current-item");DomHelper.scrollPageTo(items[i+1]);}
|
for(let i=0;i<items.length;i++){if(items[i].classList.contains("current-item")){items[i].classList.remove("current-item");if(i+1<items.length){items[i+1].classList.add("current-item");DomHelper.scrollPageTo(items[i+1]);}
|
||||||
break;}}}
|
break;}}}
|
||||||
isListView(){return document.querySelector(".items")!==null;}}
|
isListView(){return document.querySelector(".items")!==null;}}
|
||||||
|
@ -72,5 +72,5 @@ document.addEventListener("DOMContentLoaded",function(){FormHandler.handleSubmit
|
||||||
}
|
}
|
||||||
|
|
||||||
var JavascriptChecksums = map[string]string{
|
var JavascriptChecksums = map[string]string{
|
||||||
"app": "ce9791d6752f8b09f6163907e5ba01092f76595d6f99d611858216d6533f4655",
|
"app": "7d14f00cb219662aaf59f20080265097eb236999dcc712b83775882970d05803",
|
||||||
}
|
}
|
||||||
|
|
|
@ -275,10 +275,11 @@ class RequestBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
class EntryHandler {
|
class EntryHandler {
|
||||||
static updateEntriesStatus(entryIDs, status) {
|
static updateEntriesStatus(entryIDs, status, callback) {
|
||||||
let url = document.body.dataset.entriesStatusUrl;
|
let url = document.body.dataset.entriesStatusUrl;
|
||||||
let request = new RequestBuilder(url);
|
let request = new RequestBuilder(url);
|
||||||
request.withBody({entry_ids: entryIDs, status: status});
|
request.withBody({entry_ids: entryIDs, status: status});
|
||||||
|
request.withCallback(callback);
|
||||||
request.execute();
|
request.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,6 +300,16 @@ class EntryHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static markEntryAsRead(element) {
|
||||||
|
if (element.classList.contains("item-status-unread")) {
|
||||||
|
element.classList.remove("item-status-unread");
|
||||||
|
element.classList.add("item-status-read");
|
||||||
|
|
||||||
|
let entryID = parseInt(element.dataset.id, 10);
|
||||||
|
this.updateEntriesStatus([entryID], "read");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static saveEntry(element) {
|
static saveEntry(element) {
|
||||||
if (element.dataset.completed) {
|
if (element.dataset.completed) {
|
||||||
return;
|
return;
|
||||||
|
@ -395,10 +406,11 @@ class NavHandler {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (entryIDs.length > 0) {
|
if (entryIDs.length > 0) {
|
||||||
EntryHandler.updateEntriesStatus(entryIDs, "read");
|
EntryHandler.updateEntriesStatus(entryIDs, "read", () => {
|
||||||
|
// This callback make sure the Ajax request reach the server before we reload the page.
|
||||||
|
this.goToPage("next", true);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.goToPage("next");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
saveEntry() {
|
saveEntry() {
|
||||||
|
@ -421,8 +433,10 @@ class NavHandler {
|
||||||
toggleEntryStatus() {
|
toggleEntryStatus() {
|
||||||
let currentItem = document.querySelector(".current-item");
|
let currentItem = document.querySelector(".current-item");
|
||||||
if (currentItem !== null) {
|
if (currentItem !== null) {
|
||||||
EntryHandler.toggleEntryStatus(currentItem);
|
// The order is important here,
|
||||||
|
// On the unread page, the read item will be hidden.
|
||||||
this.goToNextListItem();
|
this.goToNextListItem();
|
||||||
|
EntryHandler.toggleEntryStatus(currentItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,6 +450,11 @@ class NavHandler {
|
||||||
let currentItemOriginalLink = document.querySelector(".current-item a[data-original-link]");
|
let currentItemOriginalLink = document.querySelector(".current-item a[data-original-link]");
|
||||||
if (currentItemOriginalLink !== null) {
|
if (currentItemOriginalLink !== null) {
|
||||||
DomHelper.openNewTab(currentItemOriginalLink.getAttribute("href"));
|
DomHelper.openNewTab(currentItemOriginalLink.getAttribute("href"));
|
||||||
|
|
||||||
|
// Move to the next item and if we are on the unread page mark this item as read.
|
||||||
|
let currentItem = document.querySelector(".current-item");
|
||||||
|
this.goToNextListItem();
|
||||||
|
EntryHandler.markEntryAsRead(currentItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,11 +465,17 @@ class NavHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
goToPage(page) {
|
/**
|
||||||
|
* @param {string} page Page to redirect to.
|
||||||
|
* @param {boolean} fallbackSelf Refresh actual page if the page is not found.
|
||||||
|
*/
|
||||||
|
goToPage(page, fallbackSelf) {
|
||||||
let element = document.querySelector("a[data-page=" + page + "]");
|
let element = document.querySelector("a[data-page=" + page + "]");
|
||||||
|
|
||||||
if (element) {
|
if (element) {
|
||||||
document.location.href = element.href;
|
document.location.href = element.href;
|
||||||
|
} else if (fallbackSelf) {
|
||||||
|
window.location.reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,7 +497,6 @@ class NavHandler {
|
||||||
|
|
||||||
goToPreviousListItem() {
|
goToPreviousListItem() {
|
||||||
let items = DomHelper.getVisibleElements(".items .item");
|
let items = DomHelper.getVisibleElements(".items .item");
|
||||||
|
|
||||||
if (items.length === 0) {
|
if (items.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -497,13 +521,13 @@ class NavHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
goToNextListItem() {
|
goToNextListItem() {
|
||||||
|
let currentItem = document.querySelector(".current-item");
|
||||||
let items = DomHelper.getVisibleElements(".items .item");
|
let items = DomHelper.getVisibleElements(".items .item");
|
||||||
|
|
||||||
if (items.length === 0) {
|
if (items.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.querySelector(".current-item") === null) {
|
if (currentItem === null) {
|
||||||
items[0].classList.add("current-item");
|
items[0].classList.add("current-item");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,15 +191,6 @@ func (c *Controller) ShowUnreadEntry(ctx *core.Context, request *core.Request, r
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if entry.Status == model.EntryStatusUnread {
|
|
||||||
err = c.store.SetEntriesStatus(user.ID, []int64{entry.ID}, model.EntryStatusRead)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
response.HTML().ServerError(nil)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
args, err := c.getCommonTemplateArgs(ctx)
|
args, err := c.getCommonTemplateArgs(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
response.HTML().ServerError(err)
|
response.HTML().ServerError(err)
|
||||||
|
@ -225,6 +216,16 @@ func (c *Controller) ShowUnreadEntry(ctx *core.Context, request *core.Request, r
|
||||||
prevEntryRoute = ctx.Route("unreadEntry", "entryID", prevEntry.ID)
|
prevEntryRoute = ctx.Route("unreadEntry", "entryID", prevEntry.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We change the status here, otherwise we cannot get the pagination for unread items.
|
||||||
|
if entry.Status == model.EntryStatusUnread {
|
||||||
|
err = c.store.SetEntriesStatus(user.ID, []int64{entry.ID}, model.EntryStatusRead)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
response.HTML().ServerError(nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
response.HTML().Render("entry", args.Merge(tplParams{
|
response.HTML().Render("entry", args.Merge(tplParams{
|
||||||
"entry": entry,
|
"entry": entry,
|
||||||
"prevEntry": prevEntry,
|
"prevEntry": prevEntry,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue