Improved large anime lists
This commit is contained in:
parent
da57b00ff2
commit
df4b367c61
@ -36,8 +36,8 @@ component AnimeLists(animeLists map[string]*arn.AnimeList, viewUser *arn.User, u
|
|||||||
//- AnimeList(animeList, user)
|
//- AnimeList(animeList, user)
|
||||||
|
|
||||||
component AnimeList(animeList *arn.AnimeList, viewUser *arn.User, user *arn.User)
|
component AnimeList(animeList *arn.AnimeList, viewUser *arn.User, user *arn.User)
|
||||||
table
|
table.anime-list
|
||||||
tbody.anime-list
|
tbody
|
||||||
each item in animeList.Items
|
each item in animeList.Items
|
||||||
tr.anime-list-item(title=item.Notes, data-api="/api/animelist/" + animeList.UserID + "/update/" + item.AnimeID)
|
tr.anime-list-item(title=item.Notes, data-api="/api/animelist/" + animeList.UserID + "/update/" + item.AnimeID)
|
||||||
td.anime-list-item-name
|
td.anime-list-item-name
|
||||||
@ -58,6 +58,8 @@ component AnimeList(animeList *arn.AnimeList, viewUser *arn.User, user *arn.User
|
|||||||
td.anime-list-item-episodes
|
td.anime-list-item-episodes
|
||||||
.anime-list-item-episodes-watched
|
.anime-list-item-episodes-watched
|
||||||
.action(contenteditable=utils.SameUser(user, viewUser), data-field="Episodes", data-type="number", data-trigger="focusout", data-action="save")= item.Episodes
|
.action(contenteditable=utils.SameUser(user, viewUser), data-field="Episodes", data-type="number", data-trigger="focusout", data-action="save")= item.Episodes
|
||||||
|
if item.Status == arn.AnimeListStatusWatching
|
||||||
|
.plus-episode.action(data-action="increaseEpisode", data-trigger="click") +
|
||||||
.anime-list-item-episodes-separator /
|
.anime-list-item-episodes-separator /
|
||||||
.anime-list-item-episodes-max= item.Anime().EpisodeCountString()
|
.anime-list-item-episodes-max= item.Anime().EpisodeCountString()
|
||||||
//- .anime-list-item-episodes-edit
|
//- .anime-list-item-episodes-edit
|
||||||
@ -65,7 +67,7 @@ component AnimeList(animeList *arn.AnimeList, viewUser *arn.User, user *arn.User
|
|||||||
//- RawIcon("pencil")
|
//- RawIcon("pencil")
|
||||||
|
|
||||||
td.anime-list-item-rating(title="Overall rating")
|
td.anime-list-item-rating(title="Overall rating")
|
||||||
.action(contenteditable=utils.SameUser(user, viewUser), data-field="Rating.Overall", data-type="number", data-trigger="focusout", data-action="save")= fmt.Sprintf("%.1f", item.Rating.Overall)
|
.action(contenteditable=utils.SameUser(user, viewUser), data-field="Rating.Overall", data-type="number", data-trigger="focusout", data-action="save")= utils.FormatRating(item.Rating.Overall)
|
||||||
//- td.anime-list-item-rating(title="Story rating")
|
//- td.anime-list-item-rating(title="Story rating")
|
||||||
//- .action(contenteditable=utils.SameUser(user, viewUser), data-field="Rating.Story", data-type="number", data-trigger="focusout", data-action="save")= fmt.Sprintf("%.1f", item.Rating.Story)
|
//- .action(contenteditable=utils.SameUser(user, viewUser), data-field="Rating.Story", data-type="number", data-trigger="focusout", data-action="save")= fmt.Sprintf("%.1f", item.Rating.Story)
|
||||||
//- td.anime-list-item-rating(title="Visuals rating")
|
//- td.anime-list-item-rating(title="Visuals rating")
|
||||||
|
@ -24,8 +24,21 @@
|
|||||||
white-space nowrap
|
white-space nowrap
|
||||||
flex-basis 120px
|
flex-basis 120px
|
||||||
|
|
||||||
|
:hover
|
||||||
|
.plus-episode
|
||||||
|
opacity 1
|
||||||
|
|
||||||
.anime-list-item-episodes-watched
|
.anime-list-item-episodes-watched
|
||||||
flex 0.4
|
flex 0.4
|
||||||
|
horizontal
|
||||||
|
justify-content flex-end
|
||||||
|
|
||||||
|
.plus-episode
|
||||||
|
display inline-block
|
||||||
|
cursor pointer
|
||||||
|
opacity 0
|
||||||
|
margin-left 1px
|
||||||
|
transition opacity transition-speed ease
|
||||||
|
|
||||||
.anime-list-item-episodes-separator
|
.anime-list-item-episodes-separator
|
||||||
flex 0.2
|
flex 0.2
|
||||||
@ -37,6 +50,7 @@
|
|||||||
|
|
||||||
.anime-list-item-rating
|
.anime-list-item-rating
|
||||||
text-align right
|
text-align right
|
||||||
|
flex-basis 70px
|
||||||
|
|
||||||
.anime-list-item-actions
|
.anime-list-item-actions
|
||||||
display none
|
display none
|
||||||
|
@ -25,7 +25,7 @@ component AnimeListItem(viewUser *arn.User, item *arn.AnimeListItem, anime *arn.
|
|||||||
InputTextArea("Notes", item.Notes, "Notes", "Your 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/" + item.Status)
|
||||||
Icon("list")
|
Icon("list")
|
||||||
span View collection
|
span View collection
|
||||||
a.ajax.button(href=anime.Link())
|
a.ajax.button(href=anime.Link())
|
||||||
|
@ -52,7 +52,7 @@ component ProfileNavigation(viewUser *arn.User, uri string)
|
|||||||
Icon("th")
|
Icon("th")
|
||||||
span.tab-text Anime
|
span.tab-text Anime
|
||||||
|
|
||||||
a.button.tab.action(href="/+" + viewUser.Nick + "/animelist", data-action="diff", data-trigger="click")
|
a.button.tab.action(href="/+" + viewUser.Nick + "/animelist/watching", data-action="diff", data-trigger="click")
|
||||||
Icon("list")
|
Icon("list")
|
||||||
span.tab-text Collection
|
span.tab-text Collection
|
||||||
|
|
||||||
@ -68,28 +68,29 @@ component ProfileNavigation(viewUser *arn.User, uri string)
|
|||||||
Icon("music")
|
Icon("music")
|
||||||
span.tab-text Tracks
|
span.tab-text Tracks
|
||||||
|
|
||||||
//- if strings.Contains(uri, "/animelist")
|
if strings.Contains(uri, "/animelist")
|
||||||
//- StatusTabs("/+" + viewUser.Nick + "/animelist")
|
hr
|
||||||
|
StatusTabs("/+" + viewUser.Nick + "/animelist")
|
||||||
|
|
||||||
component StatusTabs(urlPrefix string)
|
component StatusTabs(urlPrefix string)
|
||||||
.buttons.tabs.status-tabs
|
.buttons.tabs.status-tabs
|
||||||
a.button.status-tab.action(href=urlPrefix + "/watching", data-action="diff", data-trigger="click")
|
a.button.tab.status-tab.action(href=urlPrefix + "/watching", data-action="diff", data-trigger="click")
|
||||||
Icon("play")
|
Icon("play")
|
||||||
span.tab-text Watching
|
span.tab-text Watching
|
||||||
|
|
||||||
a.button.status-tab.action(href=urlPrefix + "/completed", data-action="diff", data-trigger="click")
|
a.button.tab.status-tab.action(href=urlPrefix + "/completed", data-action="diff", data-trigger="click")
|
||||||
Icon("check")
|
Icon("check")
|
||||||
span.tab-text Completed
|
span.tab-text Completed
|
||||||
|
|
||||||
a.button.status-tab.action(href=urlPrefix + "/planned", data-action="diff", data-trigger="click")
|
a.button.tab.status-tab.action(href=urlPrefix + "/planned", data-action="diff", data-trigger="click")
|
||||||
Icon("forward")
|
Icon("forward")
|
||||||
span.tab-text Planned
|
span.tab-text Planned
|
||||||
|
|
||||||
a.button.status-tab.action(href=urlPrefix + "/hold", data-action="diff", data-trigger="click")
|
a.button.tab.status-tab.action(href=urlPrefix + "/hold", data-action="diff", data-trigger="click")
|
||||||
Icon("pause")
|
Icon("pause")
|
||||||
span.tab-text On Hold
|
span.tab-text On Hold
|
||||||
|
|
||||||
a.button.status-tab.action(href=urlPrefix + "/dropped", data-action="diff", data-trigger="click")
|
a.button.tab.status-tab.action(href=urlPrefix + "/dropped", data-action="diff", data-trigger="click")
|
||||||
Icon("stop")
|
Icon("stop")
|
||||||
span.tab-text Dropped
|
span.tab-text Dropped
|
||||||
|
|
||||||
@ -101,6 +102,7 @@ component Profile(viewUser *arn.User, user *arn.User, animeList *arn.AnimeList,
|
|||||||
else
|
else
|
||||||
.profile-watching-list.mountable
|
.profile-watching-list.mountable
|
||||||
each item in animeList.Items
|
each item in animeList.Items
|
||||||
|
if item.Status == arn.AnimeListStatusWatching || item.Status == arn.AnimeListStatusCompleted
|
||||||
a.profile-watching-list-item.ajax(href=item.Anime().Link(), title=item.Anime().Title.Canonical + " (" + toString(item.Episodes) + " / " + arn.EpisodesToString(item.Anime().EpisodeCount) + ")")
|
a.profile-watching-list-item.ajax(href=item.Anime().Link(), title=item.Anime().Title.Canonical + " (" + toString(item.Episodes) + " / " + arn.EpisodesToString(item.Anime().EpisodeCount) + ")")
|
||||||
img.profile-watching-list-item-image.lazy(src="", data-src=item.Anime().Image.Tiny, alt=item.Anime().Title.Canonical)
|
img.profile-watching-list-item-image.lazy(src="", data-src=item.Anime().Image.Tiny, alt=item.Anime().Title.Canonical)
|
||||||
|
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
:hover
|
:hover
|
||||||
filter saturate(1.3)
|
filter saturate(1.3)
|
||||||
|
|
||||||
// .status-tabs
|
.status-tabs
|
||||||
|
// margin-top 2px
|
||||||
// position fixed
|
// position fixed
|
||||||
// top 4.6rem
|
// top 4.6rem
|
||||||
// right 1.6rem
|
// right 1.6rem
|
||||||
|
@ -4,14 +4,14 @@ import { Diff } from "./Diff"
|
|||||||
import { findAll } from "./Utils"
|
import { findAll } from "./Utils"
|
||||||
|
|
||||||
// Save new data from an input field
|
// Save new data from an input field
|
||||||
export function save(arn: AnimeNotifier, input: HTMLInputElement | HTMLTextAreaElement) {
|
export function save(arn: AnimeNotifier, input: HTMLElement) {
|
||||||
arn.loading(true)
|
arn.loading(true)
|
||||||
|
|
||||||
let isContentEditable = input.isContentEditable
|
let isContentEditable = input.isContentEditable
|
||||||
let obj = {}
|
let obj = {}
|
||||||
let value = isContentEditable ? input.innerText : input.value
|
let value = isContentEditable ? input.innerText : (input as HTMLInputElement).value
|
||||||
|
|
||||||
if(input.type === "number" || input.dataset.type === "number") {
|
if((input as HTMLInputElement).type === "number" || input.dataset.type === "number") {
|
||||||
if(input.getAttribute("step") === "1" || input.dataset.step === "1") {
|
if(input.getAttribute("step") === "1" || input.dataset.step === "1") {
|
||||||
obj[input.dataset.field] = parseInt(value)
|
obj[input.dataset.field] = parseInt(value)
|
||||||
} else {
|
} else {
|
||||||
@ -24,7 +24,7 @@ export function save(arn: AnimeNotifier, input: HTMLInputElement | HTMLTextAreaE
|
|||||||
if(isContentEditable) {
|
if(isContentEditable) {
|
||||||
input.contentEditable = "false"
|
input.contentEditable = "false"
|
||||||
} else {
|
} else {
|
||||||
input.disabled = true
|
(input as HTMLInputElement).disabled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
let apiEndpoint = arn.findAPIEndpoint(input)
|
let apiEndpoint = arn.findAPIEndpoint(input)
|
||||||
@ -47,7 +47,7 @@ export function save(arn: AnimeNotifier, input: HTMLInputElement | HTMLTextAreaE
|
|||||||
if(isContentEditable) {
|
if(isContentEditable) {
|
||||||
input.contentEditable = "true"
|
input.contentEditable = "true"
|
||||||
} else {
|
} else {
|
||||||
input.disabled = false
|
(input as HTMLInputElement).disabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
return arn.reloadContent()
|
return arn.reloadContent()
|
||||||
@ -59,6 +59,14 @@ export function closeStatusMessage(arn: AnimeNotifier) {
|
|||||||
arn.statusMessage.close()
|
arn.statusMessage.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Increase episode
|
||||||
|
export function increaseEpisode(arn: AnimeNotifier, element: HTMLElement) {
|
||||||
|
let prev = element.previousSibling as HTMLElement
|
||||||
|
let episodes = parseInt(prev.innerText)
|
||||||
|
prev.innerText = String(episodes + 1)
|
||||||
|
save(arn, prev)
|
||||||
|
}
|
||||||
|
|
||||||
// Load
|
// Load
|
||||||
export function load(arn: AnimeNotifier, element: HTMLElement) {
|
export function load(arn: AnimeNotifier, element: HTMLElement) {
|
||||||
let url = element.dataset.url || (element as HTMLAnchorElement).getAttribute("href")
|
let url = element.dataset.url || (element as HTMLAnchorElement).getAttribute("href")
|
||||||
@ -271,7 +279,7 @@ export function removeAnimeFromCollection(arn: AnimeNotifier, button: HTMLElemen
|
|||||||
throw body
|
throw body
|
||||||
}
|
}
|
||||||
|
|
||||||
return arn.app.load("/+" + userNick + "/animelist")
|
return arn.app.load("/+" + userNick + "/animelist/" + (arn.app.find("Status") as HTMLSelectElement).value)
|
||||||
})
|
})
|
||||||
.catch(err => arn.statusMessage.showError(err))
|
.catch(err => arn.statusMessage.showError(err))
|
||||||
.then(() => arn.loading(false))
|
.then(() => arn.loading(false))
|
||||||
|
8
utils/FormatRating.go
Normal file
8
utils/FormatRating.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// FormatRating formats the rating number.
|
||||||
|
func FormatRating(rating float64) string {
|
||||||
|
return fmt.Sprintf("%.1f", rating)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user