diff --git a/main_test.go b/main_test.go index a20c3ca3..f5b0c65b 100644 --- a/main_test.go +++ b/main_test.go @@ -1,15 +1,11 @@ package main import ( - "errors" "net/http" "net/http/httptest" - "reflect" "testing" "github.com/aerogo/aero" - "github.com/aerogo/api" - "github.com/animenotifier/arn" "github.com/fatih/color" ) @@ -33,52 +29,3 @@ func TestRoutes(t *testing.T) { } } } - -func TestInterfaceImplementations(t *testing.T) { - // API interfaces - var creatable = reflect.TypeOf((*api.Creatable)(nil)).Elem() - var editable = reflect.TypeOf((*api.Editable)(nil)).Elem() - var actionable = reflect.TypeOf((*api.Actionable)(nil)).Elem() - var collection = reflect.TypeOf((*api.Collection)(nil)).Elem() - - // Required interface implementations - var interfaceImplementations = map[string][]reflect.Type{ - "User": []reflect.Type{ - editable, - }, - "Thread": []reflect.Type{ - creatable, - editable, - actionable, - }, - "Post": []reflect.Type{ - creatable, - editable, - actionable, - }, - "SoundTrack": []reflect.Type{ - creatable, - editable, - }, - "Analytics": []reflect.Type{ - creatable, - }, - "AnimeList": []reflect.Type{ - collection, - }, - "PushSubscriptions": []reflect.Type{ - collection, - }, - "UserFollows": []reflect.Type{ - collection, - }, - } - - for typeName, interfaces := range interfaceImplementations { - for _, requiredInterface := range interfaces { - if !reflect.PtrTo(arn.DB.Type(typeName)).Implements(requiredInterface) { - panic(errors.New(typeName + " does not implement interface " + requiredInterface.Name())) - } - } - } -} diff --git a/pages/anime/anime.go b/pages/anime/anime.go index ea537484..1339dfef 100644 --- a/pages/anime/anime.go +++ b/pages/anime/anime.go @@ -51,13 +51,13 @@ func Get(ctx *aero.Context) string { for i := range friends { j := i - deleted friendAnimeList := friends[j].AnimeList() - obj, err := friendAnimeList.Get(anime.ID) + friendAnimeListItem := friendAnimeList.Find(anime.ID) - if err != nil { + if friendAnimeListItem == nil { friends = friends[:j+copy(friends[j:], friends[j+1:])] deleted++ } else { - friendsAnimeListItems[friends[j]] = obj.(*arn.AnimeListItem) + friendsAnimeListItems[friends[j]] = friendAnimeListItem } } diff --git a/pages/anime/anime.pixy b/pages/anime/anime.pixy index 4b06618d..3efbc5e1 100644 --- a/pages/anime/anime.pixy +++ b/pages/anime/anime.pixy @@ -31,7 +31,7 @@ component Anime(anime *arn.Anime, friends []*arn.User, listItems map[*arn.User]* Icon("pencil") span Edit in collection else - button.action(data-action="addAnimeToCollection", data-trigger="click", data-anime-id=anime.ID, data-user-id=user.ID, data-user-nick=user.Nick) + button.action(data-api="/api/animelist/" + user.ID, data-action="arrayAppend", data-trigger="click", data-field="Items", data-object="{\"AnimeID\": \"" + anime.ID + "\"}") Icon("plus") span Add to collection diff --git a/pages/animelistitem/animelistitem.pixy b/pages/animelistitem/animelistitem.pixy index 078b5bd6..97659fe7 100644 --- a/pages/animelistitem/animelistitem.pixy +++ b/pages/animelistitem/animelistitem.pixy @@ -27,12 +27,12 @@ component AnimeListItem(viewUser *arn.User, item *arn.AnimeListItem, anime *arn. InputTextArea("Notes", item.Notes, "Notes", "Your notes") .buttons.mountable - a.ajax.button(href="/+" + viewUser.Nick + "/animelist/" + item.Status) + a.ajax.button(href="/animelist/" + item.Status) Icon("list") span View collection a.ajax.button(href=anime.Link()) Icon("search-plus") span View anime - button.action(data-action="removeAnimeFromCollection", data-trigger="click", data-anime-id=anime.ID, data-user-id=viewUser.ID, data-user-nick=viewUser.Nick) + button.action(data-action="removeAnimeFromCollection", data-trigger="click", data-api="/api/animelist/" + viewUser.ID, data-field="Items", data-index="AnimeID=\"" + anime.ID + "\"", data-nick=viewUser.Nick) Icon("trash") span Remove from collection \ No newline at end of file diff --git a/pages/profile/profile.pixy b/pages/profile/profile.pixy index 135ce40e..9d9eeb61 100644 --- a/pages/profile/profile.pixy +++ b/pages/profile/profile.pixy @@ -54,11 +54,11 @@ component ProfileHeader(viewUser *arn.User, user *arn.User, uri string) .profile-actions if user.ID != viewUser.ID if !user.Follows().Contains(viewUser.ID) - button.profile-action.action(data-action="followUser", data-trigger="click", data-api="/api/userfollows/" + user.ID + "/add", data-view-user-id=viewUser.ID) + button.profile-action.action(data-action="followUser", data-trigger="click", data-api="/api/userfollows/" + user.ID + "/add/" + viewUser.ID) Icon("user-plus") span Follow else - button.profile-action.action(data-action="unfollowUser", data-trigger="click", data-api="/api/userfollows/" + user.ID + "/remove", data-view-user-id=viewUser.ID) + button.profile-action.action(data-action="unfollowUser", data-trigger="click", data-api="/api/userfollows/" + user.ID + "/remove/" + viewUser.ID) Icon("user-times") span Unfollow diff --git a/scripts/Actions.ts b/scripts/Actions.ts index 8ee8c49b..3367a659 100644 --- a/scripts/Actions.ts +++ b/scripts/Actions.ts @@ -5,7 +5,7 @@ import { findAll } from "./Utils" // Follow user export function followUser(arn: AnimeNotifier, elem: HTMLElement) { - return arn.post(elem.dataset.api, elem.dataset.viewUserId) + return arn.post(elem.dataset.api, "") .then(() => arn.reloadContent()) .then(() => arn.statusMessage.showInfo("You are now following " + arn.app.find("nick").innerText + ".")) .catch(err => arn.statusMessage.showError(err)) @@ -13,7 +13,7 @@ export function followUser(arn: AnimeNotifier, elem: HTMLElement) { // Unfollow user export function unfollowUser(arn: AnimeNotifier, elem: HTMLElement) { - return arn.post(elem.dataset.api, elem.dataset.viewUserId) + return arn.post(elem.dataset.api, "") .then(() => arn.reloadContent()) .then(() => arn.statusMessage.showInfo("You stopped following " + arn.app.find("nick").innerText + ".")) .catch(err => arn.statusMessage.showError(err)) @@ -254,52 +254,14 @@ export function testNotification(arn: AnimeNotifier) { }) } -// Add anime to collection -export function addAnimeToCollection(arn: AnimeNotifier, button: HTMLElement) { - button.innerText = "Adding..." - arn.loading(true) - - let {animeId, userId, userNick} = button.dataset - - fetch("/api/animelist/" + userId + "/add", { - method: "POST", - body: animeId, - credentials: "same-origin" - }) - .then(response => response.text()) - .then(body => { - if(body !== "ok") { - throw body - } - - return arn.reloadContent() - }) - .catch(err => arn.statusMessage.showError(err)) - .then(() => arn.loading(false)) -} - // Remove anime from collection -export function removeAnimeFromCollection(arn: AnimeNotifier, button: HTMLElement) { - button.innerText = "Removing..." - arn.loading(true) +export function removeAnimeFromCollection(arn: AnimeNotifier, element: HTMLElement) { + let {field, index, nick} = element.dataset + let apiEndpoint = arn.findAPIEndpoint(element) - let {animeId, userId, userNick} = button.dataset - - fetch("/api/animelist/" + userId + "/remove", { - method: "POST", - body: animeId, - credentials: "same-origin" - }) - .then(response => response.text()) - .then(body => { - if(body !== "ok") { - throw body - } - - return arn.app.load("/+" + userNick + "/animelist/" + (arn.app.find("Status") as HTMLSelectElement).value) - }) + arn.post(apiEndpoint + "/field/" + field + "/remove/" + index, "") + .then(() => arn.app.load("/+" + nick + "/animelist/" + (arn.app.find("Status") as HTMLSelectElement).value)) .catch(err => arn.statusMessage.showError(err)) - .then(() => arn.loading(false)) } // Charge up @@ -368,7 +330,7 @@ export function buyItem(arn: AnimeNotifier, button: HTMLElement) { // Append new element to array export function arrayAppend(arn: AnimeNotifier, element: HTMLElement) { let field = element.dataset.field - let object = element.dataset.object ? JSON.parse(element.dataset.object) : {} + let object = element.dataset.object || "" let apiEndpoint = arn.findAPIEndpoint(element) arn.post(apiEndpoint + "/field/" + field + "/append", object) diff --git a/scripts/AnimeNotifier.ts b/scripts/AnimeNotifier.ts index d65d6db4..71ee9dcc 100644 --- a/scripts/AnimeNotifier.ts +++ b/scripts/AnimeNotifier.ts @@ -665,7 +665,7 @@ export class AnimeNotifier { .catch(console.error) } - post(url, body) { + post(url: string, body: any) { if(typeof body !== "string") { body = JSON.stringify(body) }