From 1f4dc0a05ded595eb798a5df4b163613b68add04 Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Sat, 8 Jul 2017 23:27:24 +0200 Subject: [PATCH] Implemented forum likes --- mixins/Postable.pixy | 15 +++++++-------- scripts/Actions.ts | 18 ++++++++++++++++++ scripts/AnimeNotifier.ts | 27 ++++++++++++++++++++------- scripts/Diff.ts | 4 ++-- tests.go | 4 ++++ 5 files changed, 51 insertions(+), 17 deletions(-) diff --git a/mixins/Postable.pixy b/mixins/Postable.pixy index 77fdf3b4..6df39fff 100644 --- a/mixins/Postable.pixy +++ b/mixins/Postable.pixy @@ -30,14 +30,13 @@ component Postable(post arn.Postable, user *arn.User, highlightAuthorID string) .post-likes(id="likes-" + post.ID(), title="Likes")= len(post.Likes()) if user != nil - //- if user.ID !== post.authorId - //- - var liked = post.likes && post.likes.indexOf(user.ID) !== -1 - - //- a.post-tool.post-like(id="like-" + post.ID, onclick=`$.like("${type.toLowerCase()}", "${post.ID}")`, title="Like", class=liked ? "hidden" : ") - //- i.fa.fa-thumbs-up.fa-fw - - //- a.post-tool.post-unlike(id="unlike-" + post.ID, onclick=`$.unlike("${type.toLowerCase()}", "${post.ID}")`, title="Unlike", class=!liked ? "hidden" : ") - //- i.fa.fa-thumbs-down.fa-fw + if user.ID != post.Author().ID + if post.LikedBy(user.ID) + a.post-tool.post-unlike.action(id="unlike-" + post.ID(), title="Unlike", data-action="unlike", data-trigger="click") + RawIcon("thumbs-down") + else + a.post-tool.post-like.action(id="like-" + post.ID(), title="Like", data-action="like", data-trigger="click") + RawIcon("thumbs-up") if user.ID == post.Author().ID a.post-tool.post-edit.action(data-action="editPost", data-trigger="click", data-id=post.ID(), title="Edit") diff --git a/scripts/Actions.ts b/scripts/Actions.ts index 6e437977..917ebde7 100644 --- a/scripts/Actions.ts +++ b/scripts/Actions.ts @@ -115,6 +115,24 @@ export function savePost(arn: AnimeNotifier, element: HTMLElement) { .catch(console.error) } +// like +export function like(arn: AnimeNotifier, element: HTMLElement) { + let apiEndpoint = arn.findAPIEndpoint(element) + + arn.post(apiEndpoint + "/like", null) + .then(() => arn.reloadContent()) + .catch(console.error) +} + +// unlike +export function unlike(arn: AnimeNotifier, element: HTMLElement) { + let apiEndpoint = arn.findAPIEndpoint(element) + + arn.post(apiEndpoint + "/unlike", null) + .then(() => arn.reloadContent()) + .catch(console.error) +} + // Forum reply export function forumReply(arn: AnimeNotifier) { let textarea = arn.app.find("new-reply") as HTMLTextAreaElement diff --git a/scripts/AnimeNotifier.ts b/scripts/AnimeNotifier.ts index c8e32f73..3e3cc16a 100644 --- a/scripts/AnimeNotifier.ts +++ b/scripts/AnimeNotifier.ts @@ -182,23 +182,36 @@ export class AnimeNotifier { assignActions() { for(let element of findAll("action")) { - if(element["action assigned"]) { - continue - } - + let actionTrigger = element.dataset.trigger let actionName = element.dataset.action - element.addEventListener(element.dataset.trigger, e => { + let oldAction = element["action assigned"] + + if(oldAction) { + if(oldAction.trigger === actionTrigger && oldAction.action === actionName) { + continue + } + + element.removeEventListener(oldAction.trigger, oldAction.handler) + } + + let actionHandler = e => { actions[actionName](this, element, e) e.stopPropagation() e.preventDefault() - }) + } + + element.addEventListener(actionTrigger, actionHandler) // Use "action assigned" flag instead of removing the class. // This will make sure that DOM diffs which restore the class name // will not assign the action multiple times to the same element. - element["action assigned"] = true + element["action assigned"] = { + trigger: actionTrigger, + action: actionName, + handler: actionHandler + } } } diff --git a/scripts/Diff.ts b/scripts/Diff.ts index 2326bf50..c2b7793d 100644 --- a/scripts/Diff.ts +++ b/scripts/Diff.ts @@ -47,8 +47,8 @@ export class Diff { let elemA = a as HTMLElement let elemB = b as HTMLElement - // Skip iframes - if(elemA.tagName === "IFRAME") { + // Skip iframes and lazy loaded images + if(elemA.tagName === "IFRAME" || elemA.classList.contains("lazy")) { continue } diff --git a/tests.go b/tests.go index ae7db0ed..8b872208 100644 --- a/tests.go +++ b/tests.go @@ -186,6 +186,7 @@ var routeTests = map[string][]string{ "/anime/:id/edit": nil, "/new/thread": nil, "/new/soundtrack": nil, + "/editor": nil, "/user": nil, "/settings": nil, "/extension/embed": nil, @@ -194,6 +195,7 @@ var routeTests = map[string][]string{ // API interfaces var creatable = reflect.TypeOf((*api.Creatable)(nil)).Elem() var updatable = reflect.TypeOf((*api.Updatable)(nil)).Elem() +var actionable = reflect.TypeOf((*api.Actionable)(nil)).Elem() var collection = reflect.TypeOf((*api.Collection)(nil)).Elem() // Required interface implementations @@ -204,10 +206,12 @@ var interfaceImplementations = map[string][]reflect.Type{ "Thread": []reflect.Type{ creatable, updatable, + actionable, }, "Post": []reflect.Type{ creatable, updatable, + actionable, }, "SoundTrack": []reflect.Type{ creatable,