From 6302c3b2194e43add648724044bb293ea15c5116 Mon Sep 17 00:00:00 2001 From: Frédéric Guillot Date: Thu, 18 Jan 2018 20:23:26 -0800 Subject: Add mark as read/unread link on list items --- locale/translations.go | 17 +++- locale/translations/de_DE.json | 2 +- locale/translations/fr_FR.json | 9 +- template/common.go | 53 ++++++++++- template/html/category_entries.html | 33 +------ template/html/common/item_meta.html | 43 +++++++++ template/html/common/layout.html | 2 +- template/html/feed_entries.html | 33 +------ template/html/history.html | 33 +------ template/html/starred.html | 33 +------ template/html/unread.html | 33 +------ template/views.go | 177 +++--------------------------------- ui/static/js.go | 15 +-- ui/static/js/app.js | 42 +++++++-- 14 files changed, 174 insertions(+), 351 deletions(-) create mode 100644 template/html/common/item_meta.html diff --git a/locale/translations.go b/locale/translations.go index d6cec68..104ad0c 100644 --- a/locale/translations.go +++ b/locale/translations.go @@ -1,5 +1,5 @@ // Code generated by go generate; DO NOT EDIT. -// 2018-01-18 00:53:55.957312 +0100 CET m=+0.014632776 +// 2018-01-18 20:15:20.477741406 -0800 PST m=+0.057220191 package locale @@ -208,7 +208,7 @@ var translations = map[string]string{ "Flush history": "Verlauf leeren", "Site URL": "Webseite-URL", "Feed URL": "Feed-URL", - "Logged as": "Angemeldet als", + "Logged as %s": "Angemeldet als %s", "Unread Items": "Ungelesen" } `, @@ -421,13 +421,20 @@ var translations = map[string]string{ "There is already someone associated with this provider!": "Il y a déjà quelqu'un d'associé avec ce provider !", "There is already someone else with the same Fever username!": "Il y a déjà quelqu'un d'autre avec le même nom d'utilisateur Fever !", "Mark all as read": "Tout marquer comme lu", - "This feed is empty": "Cet abonnement est vide" + "This feed is empty": "Cet abonnement est vide", + "Flush history": "Supprimer l'historique", + "Site URL": "URL du site web", + "Feed URL": "URL du flux", + "Logged as %s": "Connecté en tant que %s", + "Unread Items": "Éléments non lus", + "Change entry status": "Changer le statut de l'élément", + "Read": "Lu" } `, } var translationsChecksums = map[string]string{ - "de_DE": "a6f658b6e10f0a4b581d35050b01f03aa81d3a1d69d458c57f958b8f2bcb4af8", + "de_DE": "4489570ade4480a3b0ca8f0e3b48b72271593d16a2aee5260f4d33b006a2385c", "en_US": "6fe95384260941e8a5a3c695a655a932e0a8a6a572c1e45cb2b1ae8baa01b897", - "fr_FR": "888baaeba8cee020f0cf77db7bad9960e9b640277d042029cafb41e72e13566e", + "fr_FR": "776658a9a09c49d25f1f259fea794b48c4fa39b92024318d0f223bafb9164aad", } diff --git a/locale/translations/de_DE.json b/locale/translations/de_DE.json index 269df6c..eaa6881 100644 --- a/locale/translations/de_DE.json +++ b/locale/translations/de_DE.json @@ -202,6 +202,6 @@ "Flush history": "Verlauf leeren", "Site URL": "Webseite-URL", "Feed URL": "Feed-URL", - "Logged as": "Angemeldet als", + "Logged as %s": "Angemeldet als %s", "Unread Items": "Ungelesen" } diff --git a/locale/translations/fr_FR.json b/locale/translations/fr_FR.json index 1cfde0a..fecc78b 100644 --- a/locale/translations/fr_FR.json +++ b/locale/translations/fr_FR.json @@ -197,5 +197,12 @@ "There is already someone associated with this provider!": "Il y a déjà quelqu'un d'associé avec ce provider !", "There is already someone else with the same Fever username!": "Il y a déjà quelqu'un d'autre avec le même nom d'utilisateur Fever !", "Mark all as read": "Tout marquer comme lu", - "This feed is empty": "Cet abonnement est vide" + "This feed is empty": "Cet abonnement est vide", + "Flush history": "Supprimer l'historique", + "Site URL": "URL du site web", + "Feed URL": "URL du flux", + "Logged as %s": "Connecté en tant que %s", + "Unread Items": "Éléments non lus", + "Change entry status": "Changer le statut de l'élément", + "Read": "Lu" } diff --git a/template/common.go b/template/common.go index 7ec578f..798f8ff 100644 --- a/template/common.go +++ b/template/common.go @@ -1,5 +1,5 @@ // Code generated by go generate; DO NOT EDIT. -// 2018-01-02 21:59:10.101985953 -0800 PST m=+0.029361282 +// 2018-01-18 20:15:20.47432327 -0800 PST m=+0.053802055 package template @@ -22,6 +22,49 @@ var templateCommonMap = map[string]string{ {{ end }} +{{ end }}`, + "item_meta": `{{ define "item_meta" }} +
+ +
{{ end }}`, "layout": `{{ define "base" }} @@ -86,7 +129,7 @@ var templateCommonMap = map[string]string{ {{ t "Settings" }}
  • - {{ t "Logout" }} + {{ t "Logout" }}
  • @@ -146,7 +189,8 @@ var templateCommonMap = map[string]string{ -{{ end }}`, +{{ end }} +`, "pagination": `{{ define "pagination" }} diff --git a/template/html/common/item_meta.html b/template/html/common/item_meta.html new file mode 100644 index 0000000..668a5d2 --- /dev/null +++ b/template/html/common/item_meta.html @@ -0,0 +1,43 @@ +{{ define "item_meta" }} +
    + +
    +{{ end }} \ No newline at end of file diff --git a/template/html/common/layout.html b/template/html/common/layout.html index fd32499..ca19313 100644 --- a/template/html/common/layout.html +++ b/template/html/common/layout.html @@ -61,7 +61,7 @@ {{ t "Settings" }}
  • - {{ t "Logout" }} + {{ t "Logout" }}
  • diff --git a/template/html/feed_entries.html b/template/html/feed_entries.html index 1568f40..ebd8ea7 100644 --- a/template/html/feed_entries.html +++ b/template/html/feed_entries.html @@ -38,38 +38,7 @@ {{ .Feed.Category.Title }} -
    - -
    + {{ template "item_meta" . }} {{ end }} diff --git a/template/html/history.html b/template/html/history.html index 5baa0df..892f183 100644 --- a/template/html/history.html +++ b/template/html/history.html @@ -27,38 +27,7 @@ {{ .Feed.Category.Title }} -
    - -
    + {{ template "item_meta" . }} {{ end }} diff --git a/template/html/starred.html b/template/html/starred.html index 1ed1b13..b16b9e7 100644 --- a/template/html/starred.html +++ b/template/html/starred.html @@ -20,38 +20,7 @@ {{ .Feed.Category.Title }} -
    - -
    + {{ template "item_meta" . }} {{ end }} diff --git a/template/html/unread.html b/template/html/unread.html index 7f285d0..e88c847 100644 --- a/template/html/unread.html +++ b/template/html/unread.html @@ -30,38 +30,7 @@ {{ .Feed.Category.Title }} -
    - -
    + {{ template "item_meta" . }} {{ end }} diff --git a/template/views.go b/template/views.go index 14c6230..76d05a4 100644 --- a/template/views.go +++ b/template/views.go @@ -1,5 +1,5 @@ // Code generated by go generate; DO NOT EDIT. -// 2018-01-05 18:05:45.591353454 -0800 PST m=+0.022613760 +// 2018-01-18 20:15:20.459420484 -0800 PST m=+0.038899269 package template @@ -179,38 +179,7 @@ var templateViewsMap = map[string]string{ {{ .Feed.Category.Title }} -
    - -
    + {{ template "item_meta" . }} {{ end }} @@ -638,38 +607,7 @@ var templateViewsMap = map[string]string{ {{ .Feed.Category.Title }} -
    - -
    + {{ template "item_meta" . }} {{ end }} @@ -785,38 +723,7 @@ var templateViewsMap = map[string]string{ {{ .Feed.Category.Title }} -
    - -
    + {{ template "item_meta" . }} {{ end }} @@ -1161,38 +1068,7 @@ var templateViewsMap = map[string]string{ {{ .Feed.Category.Title }} -
    - -
    + {{ template "item_meta" . }} {{ end }} @@ -1233,38 +1109,7 @@ var templateViewsMap = map[string]string{ {{ .Feed.Category.Title }} -
    - -
    + {{ template "item_meta" . }} {{ end }} @@ -1339,7 +1184,7 @@ var templateViewsMapChecksums = map[string]string{ "about": "ad2fb778fc73c39b733b3f81b13e5c7d689b041fadd24ee2d4577f545aa788ad", "add_subscription": "053c920b0d7e109ea19dce6a448e304ce720db8633588ea04db16677f7209a7b", "categories": "ca1280cd157bb527d4fc907da67b05a8347378f6dce965b9389d4bcdf3600a11", - "category_entries": "ce59529666520b8363c9588ce2c437de5a3f6d91941e5c46be25ca08f6900364", + "category_entries": "a92bd528d1162e7af4972f7ad25feddf7ceb17164db593805caf3d363ff32aac", "choose_subscription": "a325f9c976ca2b2dc148e25c8fef0cf6ccab0e04e86e604e7812bb18dc4cdde1", "create_category": "2b82af5d2dcd67898dc5daa57a6461e6ff8121a6089b2a2a1be909f35e4a2275", "create_user": "45e226df757126d5fe7c464e295e9a34f07952cfdb71e31e49839850d35af139", @@ -1347,15 +1192,15 @@ var templateViewsMapChecksums = map[string]string{ "edit_feed": "30ff6ee5526b8beb9b457526b77ede55938f53eb279b1acc719ce896359e2ed8", "edit_user": "82d9749d76ddbd2352816d813c4b1f6d92f2222de678b4afe5821090246735c7", "entry": "6b4405e0c8e4a7d31874659f8835f4e43e01dc3c20686091517ac750196dd70f", - "feed_entries": "6b4a7d52b2590a7c54b58ed3180bd3bb5d869ceaecc80e3575339a9c351309c6", + "feed_entries": "3a7b4d942d9ac9da7df5c09950fbadaa0ff564696953c4f1c302d955696cc2ee", "feeds": "65b0a47c4438810b9d51c60f3f3b2519690e56ff74029e6296c68626b83a470b", - "history": "abc7ea29f7d54f28f73fe14979bbd03dbc41fa6a7c86f95f56d6e94f7b09b9ba", + "history": "d2476fd727e4f53428b5ed1f3f9423063583337ec8cfe1dd9c931fcb03852a20", "import": "73b5112e20bfd232bf73334544186ea419505936bc237d481517a8622901878f", "integrations": "3c14d7de904911aad7f3ebec6d1a20b50843287f58125c526e167f429f3d455d", "login": "7d83c3067c02f1f6aafdd8816c7f97a4eb5a5a4bdaaaa4cc1e2fbb9c17ea65e8", "sessions": "9a3609c52b071a280b85fd886f15d4b91c76bb0ab93a99ad132c695a216ac5cf", "settings": "ea2505b9d0a6d6bb594dba87a92079de19baa6d494f0651693a7685489fb7de9", - "starred": "33dd40d1a24739e9d05f9cc4b66497cfdb8c86a7abb209a66ca65c2fbafc7d87", - "unread": "690bac794c4d21086f1a03588753088d7c26385de9a0c2723add6c7905b63f5e", + "starred": "121b761ce218de472ebf70879c1aa2fe3b9ae8981c11f1ed53a355e34049b269", + "unread": "17335b21dc5fb79207da317a8e8a6685a122bc94c323662cbda7cfdbf73dd2f9", "users": "44677e28bb5347799ed0020c90ec785aadec4b1454446d92411cfdaf6e32110b", } diff --git a/ui/static/js.go b/ui/static/js.go index 04fc945..7665a2f 100644 --- a/ui/static/js.go +++ b/ui/static/js.go @@ -1,5 +1,5 @@ // Code generated by go generate; DO NOT EDIT. -// 2018-01-02 21:59:10.089270078 -0800 PST m=+0.016645407 +// 2018-01-20 13:23:40.729553481 -0800 PST m=+0.015026127 package static @@ -8,14 +8,15 @@ var Javascript = map[string]string{ static openNewTab(url){let win=window.open(url,"_blank");win.focus();} static scrollPageTo(element){let windowScrollPosition=window.pageYOffset;let windowHeight=document.documentElement.clientHeight;let viewportPosition=windowScrollPosition+windowHeight;let itemBottomPosition=element.offsetTop+element.offsetHeight;if(viewportPosition-itemBottomPosition<0||viewportPosition-element.offsetTop>windowHeight){window.scrollTo(0,element.offsetTop-10);}} static getVisibleElements(selector){let elements=document.querySelectorAll(selector);let result=[];for(let i=0;i=-1&&this.touch.move.x>=-1){let horizontalDistance=Math.abs(this.touch.move.x-this.touch.start.x);let verticalDistance=Math.abs(this.touch.move.y-this.touch.start.y);if(horizontalDistance>30&&verticalDistance<70){return this.touch.move.x-this.touch.start.x;}} return 0;} findElement(element){if(element.classList.contains("touch-item")){return element;} -for(;element&&element!==document;element=element.parentNode){if(element.classList.contains("touch-item")){return element;}} -return null;} +return DomHelper.findParent(element,"touch-item");} onTouchStart(event){if(event.touches===undefined||event.touches.length!==1){return;} this.reset();this.touch.start.x=event.touches[0].clientX;this.touch.start.y=event.touches[0].clientY;this.touch.element=this.findElement(event.touches[0].target);} onTouchMove(event){if(event.touches===undefined||event.touches.length!==1||this.element===null){return;} @@ -46,7 +47,9 @@ static increment(n){this.updateValue((current)=>{return current+n;});} static updateValue(callback){let counterElements=document.querySelectorAll("span.unread-counter");counterElements.forEach((element)=>{let oldValue=parseInt(element.textContent,10);element.innerHTML=callback(oldValue);});}} 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);if(newStatus==="read"){UnreadCounterHandler.decrement(1);}else{UnreadCounterHandler.increment(1);} +let link=element.querySelector("a[data-toggle-status]");if(link){this.toggleLinkStatus(link);} break;}}} +static toggleLinkStatus(link){if(link.dataset.value==="read"){link.innerHTML=link.dataset.labelRead;link.dataset.value="unread";}else{link.innerHTML=link.dataset.labelUnread;link.dataset.value="read";}} static toggleBookmark(element){element.innerHTML=element.dataset.labelLoading;let request=new RequestBuilder(element.dataset.bookmarkUrl);request.withCallback(()=>{if(element.dataset.value==="star"){element.innerHTML=element.dataset.labelStar;element.dataset.value="unstar";}else{element.innerHTML=element.dataset.labelUnstar;element.dataset.value="star";}});request.execute();} 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;} @@ -84,9 +87,9 @@ if(currentItem===null){items[0].classList.add("current-item");return;} for(let i=0;inavHandler.goToPage("unread"));keyboardHandler.on("g b",()=>navHandler.goToPage("starred"));keyboardHandler.on("g h",()=>navHandler.goToPage("history"));keyboardHandler.on("g f",()=>navHandler.goToPage("feeds"));keyboardHandler.on("g c",()=>navHandler.goToPage("categories"));keyboardHandler.on("g s",()=>navHandler.goToPage("settings"));keyboardHandler.on("ArrowLeft",()=>navHandler.goToPrevious());keyboardHandler.on("ArrowRight",()=>navHandler.goToNext());keyboardHandler.on("j",()=>navHandler.goToPrevious());keyboardHandler.on("p",()=>navHandler.goToPrevious());keyboardHandler.on("k",()=>navHandler.goToNext());keyboardHandler.on("n",()=>navHandler.goToNext());keyboardHandler.on("h",()=>navHandler.goToPage("previous"));keyboardHandler.on("l",()=>navHandler.goToPage("next"));keyboardHandler.on("o",()=>navHandler.openSelectedItem());keyboardHandler.on("v",()=>navHandler.openOriginalLink());keyboardHandler.on("m",()=>navHandler.toggleEntryStatus());keyboardHandler.on("A",()=>navHandler.markPageAsRead());keyboardHandler.on("s",()=>navHandler.saveEntry());keyboardHandler.on("d",()=>navHandler.fetchOriginalContent());keyboardHandler.on("f",()=>navHandler.toggleBookmark());keyboardHandler.on("?",()=>navHandler.showKeyboardShortcuts());keyboardHandler.on("Escape",()=>ModalHandler.close());keyboardHandler.listen();let mouseHandler=new MouseHandler();mouseHandler.onClick("a[data-save-entry]",(event)=>{event.preventDefault();EntryHandler.saveEntry(event.target);});mouseHandler.onClick("a[data-toggle-bookmark]",(event)=>{event.preventDefault();EntryHandler.toggleBookmark(event.target);});mouseHandler.onClick("a[data-fetch-content-entry]",(event)=>{event.preventDefault();EntryHandler.fetchOriginalContent(event.target);});mouseHandler.onClick("a[data-on-click=markPageAsRead]",()=>navHandler.markPageAsRead());mouseHandler.onClick("a[data-confirm]",(event)=>{(new ConfirmHandler()).handle(event);});if(document.documentElement.clientWidth<600){let menuHandler=new MenuHandler();mouseHandler.onClick(".logo",()=>menuHandler.toggleMainMenu());mouseHandler.onClick(".header nav li",(event)=>menuHandler.clickMenuListItem(event));}});})();`, +document.addEventListener("DOMContentLoaded",function(){FormHandler.handleSubmitButtons();let touchHandler=new TouchHandler();touchHandler.listen();let navHandler=new NavHandler();let keyboardHandler=new KeyboardHandler();keyboardHandler.on("g u",()=>navHandler.goToPage("unread"));keyboardHandler.on("g b",()=>navHandler.goToPage("starred"));keyboardHandler.on("g h",()=>navHandler.goToPage("history"));keyboardHandler.on("g f",()=>navHandler.goToPage("feeds"));keyboardHandler.on("g c",()=>navHandler.goToPage("categories"));keyboardHandler.on("g s",()=>navHandler.goToPage("settings"));keyboardHandler.on("ArrowLeft",()=>navHandler.goToPrevious());keyboardHandler.on("ArrowRight",()=>navHandler.goToNext());keyboardHandler.on("j",()=>navHandler.goToPrevious());keyboardHandler.on("p",()=>navHandler.goToPrevious());keyboardHandler.on("k",()=>navHandler.goToNext());keyboardHandler.on("n",()=>navHandler.goToNext());keyboardHandler.on("h",()=>navHandler.goToPage("previous"));keyboardHandler.on("l",()=>navHandler.goToPage("next"));keyboardHandler.on("o",()=>navHandler.openSelectedItem());keyboardHandler.on("v",()=>navHandler.openOriginalLink());keyboardHandler.on("m",()=>navHandler.toggleEntryStatus());keyboardHandler.on("A",()=>navHandler.markPageAsRead());keyboardHandler.on("s",()=>navHandler.saveEntry());keyboardHandler.on("d",()=>navHandler.fetchOriginalContent());keyboardHandler.on("f",()=>navHandler.toggleBookmark());keyboardHandler.on("?",()=>navHandler.showKeyboardShortcuts());keyboardHandler.on("Escape",()=>ModalHandler.close());keyboardHandler.listen();let mouseHandler=new MouseHandler();mouseHandler.onClick("a[data-save-entry]",(event)=>{event.preventDefault();EntryHandler.saveEntry(event.target);});mouseHandler.onClick("a[data-toggle-bookmark]",(event)=>{event.preventDefault();EntryHandler.toggleBookmark(event.target);});mouseHandler.onClick("a[data-toggle-status]",(event)=>{event.preventDefault();let currentItem=DomHelper.findParent(event.target,"item");if(currentItem){EntryHandler.toggleEntryStatus(currentItem);}});mouseHandler.onClick("a[data-fetch-content-entry]",(event)=>{event.preventDefault();EntryHandler.fetchOriginalContent(event.target);});mouseHandler.onClick("a[data-on-click=markPageAsRead]",()=>navHandler.markPageAsRead());mouseHandler.onClick("a[data-confirm]",(event)=>{(new ConfirmHandler()).handle(event);});if(document.documentElement.clientWidth<600){let menuHandler=new MenuHandler();mouseHandler.onClick(".logo",()=>menuHandler.toggleMainMenu());mouseHandler.onClick(".header nav li",(event)=>menuHandler.clickMenuListItem(event));}});})();`, } var JavascriptChecksums = map[string]string{ - "app": "36dfcfb33ddc3f75f701fc4353873e2ce6da813dbfdd3b37100a4475a32b0545", + "app": "aa432d89d424abf0d19278f72e75ffd98cba203cf3cccb40b80e6d91e7609a17", } diff --git a/ui/static/js/app.js b/ui/static/js/app.js index 4ec82e4..c5aff81 100644 --- a/ui/static/js/app.js +++ b/ui/static/js/app.js @@ -35,6 +35,16 @@ class DomHelper { return result; } + + static findParent(element, selector) { + for (; element && element !== document; element = element.parentNode) { + if (element.classList.contains(selector)) { + return element; + } + } + + return null; + } } class TouchHandler { @@ -68,13 +78,7 @@ class TouchHandler { return element; } - for (; element && element !== document; element = element.parentNode) { - if (element.classList.contains("touch-item")) { - return element; - } - } - - return null; + return DomHelper.findParent(element, "touch-item"); } onTouchStart(event) { @@ -324,11 +328,26 @@ class EntryHandler { UnreadCounterHandler.increment(1); } + let link = element.querySelector("a[data-toggle-status]"); + if (link) { + this.toggleLinkStatus(link); + } + break; } } } + static toggleLinkStatus(link) { + if (link.dataset.value === "read") { + link.innerHTML = link.dataset.labelRead; + link.dataset.value = "unread"; + } else { + link.innerHTML = link.dataset.labelUnread; + link.dataset.value = "read"; + } + } + static toggleBookmark(element) { element.innerHTML = element.dataset.labelLoading; @@ -728,6 +747,15 @@ document.addEventListener("DOMContentLoaded", function() { EntryHandler.toggleBookmark(event.target); }); + mouseHandler.onClick("a[data-toggle-status]", (event) => { + event.preventDefault(); + + let currentItem = DomHelper.findParent(event.target, "item"); + if (currentItem) { + EntryHandler.toggleEntryStatus(currentItem); + } + }); + mouseHandler.onClick("a[data-fetch-content-entry]", (event) => { event.preventDefault(); EntryHandler.fetchOriginalContent(event.target); -- cgit v1.2.3