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) component InputText(id string, value string, label string, placeholder string)
.widget-input .widget-input
label(for=id)= label + ":" 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) component InputTextArea(id string, value string, label string, placeholder string)
.widget-input .widget-input
label(for=id)= label + ":" 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 .widget-input
label(for=id)= label + ":" 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 th.anime-list-item-rating Rating
tbody tbody
each item in animeList.Items each item in animeList.Items
tr.anime-list-item.mountable tr.anime-list-item.mountable(title=item.Notes)
td.anime-list-item-name td.anime-list-item-name
a.ajax(href=item.Anime().Link())= item.Anime().Title.Canonical a.ajax(href=item.Anime().Link())= item.Anime().Title.Canonical
td.anime-list-item-episodes= toString(item.Episodes) + " / " + item.Anime().EpisodeCountString() 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) component AnimeListItem(viewUser *arn.User, item *arn.AnimeListItem, anime *arn.Anime)
.widgets.mountable .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 h2= anime.Title.Canonical
if anime.EpisodeCount == 0 InputNumber("Episodes", item.Episodes, "Episodes", "Number of episodes you watched", "0", arn.EpisodeCountMax(anime.EpisodeCount))
InputNumber("episodes", item.Episodes, "Episodes", "Number of episodes you watched", 0, 10000) InputNumber("RewatchCount", item.RewatchCount, "Rewatched", "How often you rewatched this anime", "0", "100")
else
InputNumber("episodes", item.Episodes, "Episodes", "Number of episodes you watched", 0, anime.EpisodeCount)
InputTextArea("notes", item.Notes, "Notes", "Notes") InputTextArea("Notes", item.Notes, "Notes", "Your notes")
.buttons.mountable .buttons.mountable
a.ajax.button(href="/+" + viewUser.Nick + "/animelist") a.ajax.button(href="/+" + viewUser.Nick + "/animelist")

View File

@ -1,20 +1,20 @@
component Settings(user *arn.User) component Settings(user *arn.User)
h2.page-title Settings h2.page-title Settings
.widgets .widgets(data-api="/api/user/" + user.ID)
.widget.mountable .widget.mountable
h3.widget-title h3.widget-title
Icon("user") Icon("user")
span Personal span Personal
InputText("nick", user.Nick, "Username", "Your username on notify.moe") InputText("Nick", user.Nick, "Username", "Your username on notify.moe")
InputText("tagline", user.Tagline, "Tagline", "Text that appears below your username") InputText("Tagline", user.Tagline, "Tagline", "Text that appears below your username")
InputText("website", user.Website, "Website", "Your homepage") InputText("Website", user.Website, "Website", "Your homepage")
.widget.mountable .widget.mountable
h3.widget-title h3.widget-title
Icon("cubes") Icon("cubes")
span Accounts span Accounts
InputText("accounts.anilist.nick", user.Accounts.AniList.Nick, "AniList", "Your username on anilist.co") 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.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.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) this.app.loading.classList.add(this.app.fadeOutClass)
} }
} }
onContentLoaded() { updateActions() {
this.updateMountables()
this.updateAvatars()
for(let element of findAll(".action")) { for(let element of findAll(".action")) {
let actionName = element.dataset.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() { updateAvatars() {
for(let element of findAll(".user-image")) { for(let element of findAll(".user-image")) {
let img = element as HTMLImageElement 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) { // onResize(e: UIEvent) {
// let hasScrollbar = this.app.content.clientHeight === this.app.content.scrollHeight // 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 { AnimeNotifier } from "./AnimeNotifier"
import { Diff } from "./Diff" 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 // Search
export function search(arn: AnimeNotifier, search: HTMLInputElement, e: KeyboardEvent) { export function search(arn: AnimeNotifier, search: HTMLInputElement, e: KeyboardEvent) {
if(e.ctrlKey || e.altKey) { if(e.ctrlKey || e.altKey) {

View File

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