Added user follows

This commit is contained in:
Eduard Urbach 2017-07-21 10:10:48 +02:00
parent 8a72b76d27
commit 524ab3fff9
10 changed files with 126 additions and 18 deletions

View File

@ -39,8 +39,8 @@ component LoggedInMenu(user *arn.User)
.extra-navigation .extra-navigation
NavigationButton("Forum", "/forum", "comment") NavigationButton("Forum", "/forum", "comment")
.extra-navigation //- .extra-navigation
NavigationButton("Soundtracks", "/soundtracks", "headphones") //- NavigationButton("Soundtracks", "/soundtracks", "headphones")
FuzzySearch FuzzySearch
@ -56,8 +56,8 @@ component LoggedInMenu(user *arn.User)
.hide-landscape .hide-landscape
NavigationButton("Settings", "/settings", "cog") NavigationButton("Settings", "/settings", "cog")
.extra-navigation.hide-landscape //- .extra-navigation.hide-landscape
NavigationButtonNoAJAX("Logout", "/logout", "sign-out") //- NavigationButtonNoAJAX("Logout", "/logout", "sign-out")
component FuzzySearch component FuzzySearch
input#search.action(data-action="search", data-trigger="input", type="text", placeholder="Search...", title="Shortcut: F") input#search.action(data-action="search", data-trigger="input", type="text", placeholder="Search...", title="Shortcut: F")

View File

@ -65,8 +65,7 @@
width 65px width 65px
.anime-list-item-actions .anime-list-item-actions
display none display none !important
width 30px
// // Beautify icon alignment // // Beautify icon alignment
// .raw-icon // .raw-icon
@ -74,7 +73,11 @@
> 740px > 740px
.anime-list-item-actions .anime-list-item-actions
display block display flex !important
width 30px
:empty
display none !important
.anime-list-item-airing-date .anime-list-item-airing-date
display none !important display none !important

View File

@ -44,10 +44,22 @@ component ProfileHeader(viewUser *arn.User, user *arn.User, uri string)
Icon("rocket") Icon("rocket")
span= arn.Capitalize(viewUser.Role) span= arn.Capitalize(viewUser.Role)
//- .profile-actions if user != nil
//- button.action(data-action="followUser", data-trigger="click") .profile-actions
//- Icon("user-plus") if user.ID != viewUser.ID
//- span Follow 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)
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)
Icon("user-times")
span Unfollow
if user.Role == "admin" || user.Role == "editor"
a.button.profile-action(href="/api/user/" + viewUser.ID)
Icon("search-plus")
span API
ProfileNavigation(viewUser, uri) ProfileNavigation(viewUser, uri)

View File

@ -31,7 +31,15 @@ profile-boot-duration = 2s
margin-top calc(content-padding * 1.5) margin-top calc(content-padding * 1.5)
.profile-actions .profile-actions
horizontal vertical
margin-top content-padding
:empty
display none
.profile-action
margin-bottom 0.5rem
text-shadow none !important
> 740px > 740px
.profile .profile
@ -50,11 +58,11 @@ profile-boot-duration = 2s
max-width 900px max-width 900px
.profile-actions .profile-actions
vertical
position absolute position absolute
top 0 top 0
right 0 right 0
padding content-padding padding content-padding
margin-top 0
// animation appear // animation appear
// 0% // 0%

View File

@ -0,0 +1,42 @@
package main
import (
"fmt"
"github.com/animenotifier/arn"
"github.com/fatih/color"
)
func main() {
color.Yellow("Adding user follows to users who don't have one")
// Get a stream of all users
allUsers, err := arn.StreamUsers()
if err != nil {
panic(err)
}
// Iterate over the stream
for user := range allUsers {
// exists, err := arn.DB.Exists("UserFollows", user.ID)
// if err != nil || exists {
// continue
// }
fmt.Println(user.Nick)
follows := &arn.UserFollows{}
follows.UserID = user.ID
follows.Items = user.Following
err = arn.DB.Set("UserFollows", follows.UserID, follows)
if err != nil {
color.Red(err.Error())
}
}
color.Green("Finished.")
}

View File

@ -3,6 +3,22 @@ import { AnimeNotifier } from "./AnimeNotifier"
import { Diff } from "./Diff" import { Diff } from "./Diff"
import { findAll } from "./Utils" import { findAll } from "./Utils"
// Follow user
export function followUser(arn: AnimeNotifier, elem: HTMLElement) {
return arn.post(elem.dataset.api, elem.dataset.viewUserId)
.then(() => arn.reloadContent())
.then(() => arn.statusMessage.showInfo("You are now following " + arn.app.find("nick").innerText + "."))
.catch(err => arn.statusMessage.showError(err))
}
// Unfollow user
export function unfollowUser(arn: AnimeNotifier, elem: HTMLElement) {
return arn.post(elem.dataset.api, elem.dataset.viewUserId)
.then(() => arn.reloadContent())
.then(() => arn.statusMessage.showInfo("You stopped following " + arn.app.find("nick").innerText + "."))
.catch(err => arn.statusMessage.showError(err))
}
// Toggle sidebar // Toggle sidebar
export function toggleSidebar(arn: AnimeNotifier) { export function toggleSidebar(arn: AnimeNotifier) {
arn.app.find("sidebar").classList.toggle("sidebar-visible") arn.app.find("sidebar").classList.toggle("sidebar-visible")

View File

@ -580,18 +580,30 @@ export class AnimeNotifier {
}) })
} }
post(url, obj) { post(url, body) {
if(typeof body !== "string") {
body = JSON.stringify(body)
}
this.loading(true)
return fetch(url, { return fetch(url, {
method: "POST", method: "POST",
body: JSON.stringify(obj), body,
credentials: "same-origin" credentials: "same-origin"
}) })
.then(response => response.text()) .then(response => response.text())
.then(body => { .then(body => {
this.loading(false)
if(body !== "ok") { if(body !== "ok") {
throw body throw body
} }
}) })
.catch(err => {
this.loading(false)
throw err
})
} }
scrollTo(target: HTMLElement) { scrollTo(target: HTMLElement) {

View File

@ -9,7 +9,7 @@ export class StatusMessage {
this.text = text this.text = text
} }
show(message: string, duration?: number) { show(message: string, duration: number) {
let messageId = String(Date.now()) let messageId = String(Date.now())
this.text.innerText = message this.text.innerText = message
@ -27,10 +27,15 @@ export class StatusMessage {
} }
showError(message: string, duration?: number) { showError(message: string, duration?: number) {
this.show(message, duration) this.show(message, duration || 4000)
this.container.classList.add("error-message") this.container.classList.add("error-message")
} }
showInfo(message: string, duration?: number) {
this.show(message, duration || 2000)
this.container.classList.add("info-message")
}
close() { close() {
this.container.classList.add("fade-out") this.container.classList.add("fade-out")
} }

View File

@ -17,4 +17,8 @@
.error-message .error-message
color white color white
background-color hsl(0, 75%, 50%) background-color hsl(0, 75%, 50%)
.info-message
color white
background-color forum-tag-hover-color

View File

@ -228,6 +228,12 @@ var interfaceImplementations = map[string][]reflect.Type{
"AnimeList": []reflect.Type{ "AnimeList": []reflect.Type{
collection, collection,
}, },
"PushSubscriptions": []reflect.Type{
collection,
},
"UserFollows": []reflect.Type{
collection,
},
} }
func init() { func init() {