Can edit anime list items now

This commit is contained in:
Eduard Urbach 2017-06-21 14:00:52 +02:00
parent 5c900c9738
commit cc09017b36
8 changed files with 131 additions and 48 deletions

View File

@ -1,14 +1,14 @@
component InputText(id string, value string, label string, placeholder string)
.widget-input
label(for=id)= label + ":"
input.widget-element(id=id, type="text", value=value, placeholder=placeholder)
input.widget-element.action(id=id, type="text", value=value, placeholder=placeholder, data-action="save", data-trigger="change")
component InputTextArea(id string, value string, label string, placeholder string)
.widget-input
label(for=id)= label + ":"
textarea.widget-element(id=id, value=value, placeholder=placeholder)
textarea.widget-element.action(id=id, placeholder=placeholder, data-action="save", data-trigger="change")= value
component InputNumber(id string, value int, label string, placeholder string, min int, max int)
component InputNumber(id string, value int, label string, placeholder string, min string, max string)
.widget-input
label(for=id)= label + ":"
input.widget-element(id=id, type="number", value=value, min=min, max=max, placeholder=placeholder)
input.widget-element.action(id=id, type="number", value=value, min=min, max=max, placeholder=placeholder, data-action="save", data-trigger="change")

View File

@ -7,7 +7,7 @@ component AnimeList(animeList *arn.AnimeList)
th.anime-list-item-rating Rating
tbody
each item in animeList.Items
tr.anime-list-item.mountable
tr.anime-list-item.mountable(title=item.Notes)
td.anime-list-item-name
a.ajax(href=item.Anime().Link())= item.Anime().Title.Canonical
td.anime-list-item-episodes= toString(item.Episodes) + " / " + item.Anime().EpisodeCountString()

View File

@ -1,14 +1,12 @@
component AnimeListItem(viewUser *arn.User, item *arn.AnimeListItem, anime *arn.Anime)
.widgets.mountable
.widget.anime-list-item-view
.widget.anime-list-item-view(data-api="/api/animelist/" + viewUser.ID + "/update/" + anime.ID)
h2= anime.Title.Canonical
if anime.EpisodeCount == 0
InputNumber("episodes", item.Episodes, "Episodes", "Number of episodes you watched", 0, 10000)
else
InputNumber("episodes", item.Episodes, "Episodes", "Number of episodes you watched", 0, anime.EpisodeCount)
InputNumber("Episodes", item.Episodes, "Episodes", "Number of episodes you watched", "0", arn.EpisodeCountMax(anime.EpisodeCount))
InputNumber("RewatchCount", item.RewatchCount, "Rewatched", "How often you rewatched this anime", "0", "100")
InputTextArea("notes", item.Notes, "Notes", "Notes")
InputTextArea("Notes", item.Notes, "Notes", "Your notes")
.buttons.mountable
a.ajax.button(href="/+" + viewUser.Nick + "/animelist")

View File

@ -1,20 +1,20 @@
component Settings(user *arn.User)
h2.page-title Settings
.widgets
.widgets(data-api="/api/user/" + user.ID)
.widget.mountable
h3.widget-title
Icon("user")
span Personal
InputText("nick", user.Nick, "Username", "Your username on notify.moe")
InputText("tagline", user.Tagline, "Tagline", "Text that appears below your username")
InputText("website", user.Website, "Website", "Your homepage")
InputText("Nick", user.Nick, "Username", "Your username on notify.moe")
InputText("Tagline", user.Tagline, "Tagline", "Text that appears below your username")
InputText("Website", user.Website, "Website", "Your homepage")
.widget.mountable
h3.widget-title
Icon("cubes")
span Accounts
InputText("accounts.anilist.nick", user.Accounts.AniList.Nick, "AniList", "Your username on anilist.co")
InputText("accounts.myanimelist.nick", user.Accounts.MyAnimeList.Nick, "MyAnimeList", "Your username on myanimelist.net")
InputText("accounts.kitsu.nick", user.Accounts.Kitsu.Nick, "Kitsu", "Your username on kitsu.io")
InputText("Accounts.AniList.Nick", user.Accounts.AniList.Nick, "AniList", "Your username on anilist.co")
InputText("Accounts.MyAnimeList.Nick", user.Accounts.MyAnimeList.Nick, "MyAnimeList", "Your username on myanimelist.net")
InputText("Accounts.Kitsu.Nick", user.Accounts.Kitsu.Nick, "Kitsu", "Your username on kitsu.io")

31
scripts/APIObject.ts Normal file
View File

@ -0,0 +1,31 @@
// Save new data from an input field
// export function save(arn: AnimeNotifier, input: HTMLInputElement | HTMLTextAreaElement) {
// let apiObject: HTMLElement
// let parent = input as HTMLElement
// while(parent = parent.parentElement) {
// if(parent.classList.contains("api-object")) {
// apiObject = parent
// break
// }
// }
// if(!apiObject) {
// throw "API object not found"
// }
// let request = apiObject["api-fetch"]
// request.then(obj => {
// obj[input.id] = input.value
// console.log(obj)
// })
// }
// updateAPIObjects() {
// for(let element of findAll(".api-object")) {
// let apiObject = element
// apiObject["api-fetch"] = fetch(element.dataset.api).then(response => response.json())
// }
// }

View File

@ -30,11 +30,8 @@ export class AnimeNotifier {
this.app.loading.classList.add(this.app.fadeOutClass)
}
}
onContentLoaded() {
this.updateMountables()
this.updateAvatars()
updateActions() {
for(let element of findAll(".action")) {
let actionName = element.dataset.action
@ -46,31 +43,6 @@ export class AnimeNotifier {
}
}
onPopState(e: PopStateEvent) {
if(e.state) {
this.app.load(e.state, {
addToHistory: false
})
} else if(this.app.currentPath !== this.app.originalPath) {
this.app.load(this.app.originalPath, {
addToHistory: false
})
}
}
onKeyDown(e: KeyboardEvent) {
// Ctrl + Q = Search
if(e.ctrlKey && e.keyCode == 81) {
let search = this.app.find("search") as HTMLInputElement
search.focus()
search.select()
e.preventDefault()
e.stopPropagation()
}
}
updateAvatars() {
for(let element of findAll(".user-image")) {
let img = element as HTMLImageElement
@ -108,6 +80,38 @@ export class AnimeNotifier {
}
}
onContentLoaded() {
// Update each of these asynchronously
Promise.resolve().then(() => this.updateMountables())
Promise.resolve().then(() => this.updateAvatars())
Promise.resolve().then(() => this.updateActions())
}
onPopState(e: PopStateEvent) {
if(e.state) {
this.app.load(e.state, {
addToHistory: false
})
} else if(this.app.currentPath !== this.app.originalPath) {
this.app.load(this.app.originalPath, {
addToHistory: false
})
}
}
onKeyDown(e: KeyboardEvent) {
// Ctrl + Q = Search
if(e.ctrlKey && e.keyCode == 81) {
let search = this.app.find("search") as HTMLInputElement
search.focus()
search.select()
e.preventDefault()
e.stopPropagation()
}
}
// onResize(e: UIEvent) {
// let hasScrollbar = this.app.content.clientHeight === this.app.content.scrollHeight

View File

@ -2,6 +2,55 @@ import { Application } from "./Application"
import { AnimeNotifier } from "./AnimeNotifier"
import { Diff } from "./Diff"
// Save new data from an input field
export function save(arn: AnimeNotifier, input: HTMLInputElement | HTMLTextAreaElement) {
arn.loading(true)
let obj = {}
let value = input.value
if(input.type === "number") {
obj[input.id] = parseInt(value)
} else {
obj[input.id] = value
}
// console.log(input.type, input.dataset.api, obj, JSON.stringify(obj))
let apiObject: HTMLElement
let parent = input as HTMLElement
while(parent = parent.parentElement) {
if(parent.dataset.api !== undefined) {
apiObject = parent
break
}
}
if(!apiObject) {
throw "API object not found"
}
input.disabled = true
fetch(apiObject.dataset.api, {
method: "POST",
body: JSON.stringify(obj),
credentials: "same-origin"
})
.then(response => response.text())
.then(body => {
if(body !== "ok") {
throw body
}
})
.catch(console.error)
.then(() => {
arn.loading(false)
input.disabled = false
})
}
// Search
export function search(arn: AnimeNotifier, search: HTMLInputElement, e: KeyboardEvent) {
if(e.ctrlKey || e.altKey) {

View File

@ -109,4 +109,5 @@ func init() {
app.Test("/auth/google", nil)
app.Test("/auth/google/callback", nil)
app.Test("/user", nil)
app.Test("/settings", nil)
}