New settings page

This commit is contained in:
Eduard Urbach 2017-11-05 08:16:20 +01:00
parent b0b819306b
commit 7cf3c2564b
7 changed files with 179 additions and 121 deletions

11
main.go
View File

@ -5,6 +5,7 @@ import (
"github.com/aerogo/session-store-nano" "github.com/aerogo/session-store-nano"
"github.com/animenotifier/arn" "github.com/animenotifier/arn"
"github.com/animenotifier/notify.moe/auth" "github.com/animenotifier/notify.moe/auth"
"github.com/animenotifier/notify.moe/components"
"github.com/animenotifier/notify.moe/components/css" "github.com/animenotifier/notify.moe/components/css"
"github.com/animenotifier/notify.moe/layout" "github.com/animenotifier/notify.moe/layout"
"github.com/animenotifier/notify.moe/middleware" "github.com/animenotifier/notify.moe/middleware"
@ -94,7 +95,6 @@ func configure(app *aero.Application) *aero.Application {
app.Ajax("/post/:id", posts.Get) app.Ajax("/post/:id", posts.Get)
app.Ajax("/character/:id", character.Get) app.Ajax("/character/:id", character.Get)
app.Ajax("/new/thread", newthread.Get) app.Ajax("/new/thread", newthread.Get)
app.Ajax("/settings", settings.Get)
app.Ajax("/artworks", artworks.Get) app.Ajax("/artworks", artworks.Get)
app.Ajax("/amvs", amvs.Get) app.Ajax("/amvs", amvs.Get)
app.Ajax("/users", users.Active) app.Ajax("/users", users.Active)
@ -104,6 +104,15 @@ func configure(app *aero.Application) *aero.Application {
app.Ajax("/statistics/anime", statistics.Anime) app.Ajax("/statistics/anime", statistics.Anime)
app.Ajax("/login", login.Get) app.Ajax("/login", login.Get)
// Settings
app.Ajax("/settings", settings.Get(components.SettingsPersonal))
app.Ajax("/settings/accounts", settings.Get(components.SettingsAccounts))
app.Ajax("/settings/notifications", settings.Get(components.SettingsNotifications))
app.Ajax("/settings/apps", settings.Get(components.SettingsApps))
app.Ajax("/settings/avatar", settings.Get(components.SettingsAvatar))
app.Ajax("/settings/formatting", settings.Get(components.SettingsFormatting))
app.Ajax("/settings/pro", settings.Get(components.SettingsPro))
// Soundtracks // Soundtracks
app.Ajax("/soundtracks", soundtracks.Get) app.Ajax("/soundtracks", soundtracks.Get)
app.Ajax("/soundtracks/from/:index", soundtracks.From) app.Ajax("/soundtracks/from/:index", soundtracks.From)

View File

@ -4,17 +4,19 @@ import (
"net/http" "net/http"
"github.com/aerogo/aero" "github.com/aerogo/aero"
"github.com/animenotifier/notify.moe/components" "github.com/animenotifier/arn"
"github.com/animenotifier/notify.moe/utils" "github.com/animenotifier/notify.moe/utils"
) )
// Get user settings page. // Get settings.
func Get(ctx *aero.Context) string { func Get(component func(*arn.User) string) func(*aero.Context) string {
user := utils.GetUser(ctx) return func(ctx *aero.Context) string {
user := utils.GetUser(ctx)
if user == nil { if user == nil {
return ctx.Error(http.StatusUnauthorized, "Not logged in", nil) return ctx.Error(http.StatusUnauthorized, "Not logged in", nil)
}
return ctx.HTML(component(user))
} }
return utils.AllowEmbed(ctx, ctx.HTML(components.Settings(user)))
} }

View File

@ -1,9 +1,17 @@
component SettingsTabs component SettingsTabs
.tabs .tabs
Tab("Personal", "user", "/settings/personal") Tab("Personal", "user", "/settings")
Tab("Accounts", "cubes", "/settings/accounts")
Tab("Notifications", "bell", "/settings/notifications")
Tab("Apps", "puzzle-piece", "/settings/apps")
Tab("Avatar", "picture-o", "/settings/avatar")
Tab("Formatting", "font", "/settings/formatting")
Tab("PRO", "star", "/settings/pro")
component Settings(user *arn.User) component SettingsPersonal(user *arn.User)
h1.page-title Settings SettingsTabs
h1.page-title Personal settings
.settings .settings
.widget.mountable(data-api="/api/user/" + user.ID) .widget.mountable(data-api="/api/user/" + user.ID)
@ -15,17 +23,12 @@ component Settings(user *arn.User)
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(data-api="/api/user/" + user.ID) component SettingsNotifications(user *arn.User)
h3.widget-title SettingsTabs
Icon("cubes")
span Accounts
InputText("Accounts.AniList.Nick", user.Accounts.AniList.Nick, "AniList", "Your username on anilist.co") h1.page-title Notification settings
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.Osu.Nick", user.Accounts.Osu.Nick, "Osu", "Your username on osu.ppy.sh")
//- InputText("Accounts.AnimePlanet.Nick", user.Accounts.AnimePlanet.Nick, "AnimePlanet", "Your username on anime-planet.com")
.settings
.widget.mountable .widget.mountable
h3.widget-title h3.widget-title
Icon("bell") Icon("bell")
@ -49,6 +52,130 @@ component Settings(user *arn.User)
Icon("paper-plane") Icon("paper-plane")
span Send test notification span Send test notification
component SettingsApps(user *arn.User)
SettingsTabs
h1.page-title App settings
.settings
.widget.mountable
h3.widget-title
Icon("puzzle-piece")
span Apps
.widget-section
label Chrome Extension:
button.action(data-action="installExtension", data-trigger="click")
Icon("chrome")
span Get the Chrome Extension
.widget-section
label Desktop App:
button.action(data-action="installApp", data-trigger="click")
Icon("desktop")
span Get the Desktop App
.widget-section
label Android App:
a.button(href="https://www.youtube.com/watch?v=opyt4cw0ep8", target="_blank", rel="noopener")
Icon("android")
span Get the Android App
component SettingsAvatar(user *arn.User)
SettingsTabs
h1.page-title Avatar settings
.settings
.widget.mountable(data-api="/api/settings/" + user.ID)
h3.widget-title
Icon("picture-o")
span Avatar
.widget-section
label(for="Avatar.Source") Source:
select.widget-ui-element.action(id="Avatar.Source", data-field="Avatar.Source", value=user.Settings().Avatar.Source, data-action="save", data-trigger="change")
option(value="") Automatic
option(value="Gravatar") Gravatar
option(value="URL") Link
//- option(value="FileSystem") Upload
if user.Settings().Avatar.Source == "URL"
InputText("Avatar.SourceURL", user.Settings().Avatar.SourceURL, "Link", "Post the link to the image here")
if user.Settings().Avatar.Source == "Gravatar" || (user.Settings().Avatar.Source == "" && user.Avatar.Source == "Gravatar")
.profile-image-container.avatar-preview
img.profile-image.mountable(src=user.Gravatar(), alt="Gravatar")
if user.Settings().Avatar.Source == "URL" && user.Settings().Avatar.SourceURL != ""
.profile-image-container.avatar-preview
img.profile-image.mountable(src=strings.Replace(user.Settings().Avatar.SourceURL, "http://", "https://", 1), alt="Avatar preview")
component SettingsFormatting(user *arn.User)
SettingsTabs
h1.page-title Formatting settings
.settings
.widget.mountable(data-api="/api/settings/" + user.ID)
h3.widget-title
Icon("font")
span Formatting
.widget-section
label(for="TitleLanguage")= "Title language:"
select.widget-ui-element.action(id="TitleLanguage", data-field="TitleLanguage", value=user.Settings().TitleLanguage, title="Language of anime titles", data-action="save", data-trigger="change")
option(value="canonical") Canonical
option(value="english") English
option(value="romaji") Romaji
option(value="japanese") 日本語
InputNumber("Format.RatingsPrecision", float64(user.Settings().Format.RatingsPrecision), "Ratings precision", "How many decimals after the comma would you like to display in ratings on anime pages?", "0", "2", "1")
component SettingsPro(user *arn.User)
SettingsTabs
h1.page-title PRO settings
.settings
.widget.mountable(data-api="/api/settings/" + user.ID)
h3.widget-title
Icon("star")
span PRO
if user.IsPro()
.widget-section
label
span Your PRO account expires in
span.utc-date(data-date=user.ProExpires)
span .
a.button.ajax(href="/shop")
Icon("star")
span Extend PRO account duration
else
.widget-section
label Would you like to support the site development?
a.button.ajax(href="/shop")
Icon("star")
span Go PRO
component SettingsAccounts(user *arn.User)
SettingsTabs
h1.page-title Accounts settings
.settings
.widget.mountable(data-api="/api/user/" + user.ID)
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.Osu.Nick", user.Accounts.Osu.Nick, "Osu", "Your username on osu.ppy.sh")
//- InputText("Accounts.AnimePlanet.Nick", user.Accounts.AnimePlanet.Nick, "AnimePlanet", "Your username on anime-planet.com")
.widget.mountable .widget.mountable
h3.widget-title h3.widget-title
Icon("user-plus") Icon("user-plus")
@ -76,29 +203,6 @@ component Settings(user *arn.User)
Icon("circle-o") Icon("circle-o")
span Not connected span Not connected
.widget.mountable
h3.widget-title
Icon("puzzle-piece")
span Apps
.widget-section
label Chrome Extension:
button.action(data-action="installExtension", data-trigger="click")
Icon("chrome")
span Get the Chrome Extension
.widget-section
label Desktop App:
button.action(data-action="installApp", data-trigger="click")
Icon("desktop")
span Get the Desktop App
.widget-section
label Android App:
a.button(href="https://www.youtube.com/watch?v=opyt4cw0ep8", target="_blank", rel="noopener")
Icon("android")
span Get the Android App
.widget.mountable .widget.mountable
h3.widget-title h3.widget-title
@ -116,71 +220,4 @@ component Settings(user *arn.User)
label JSON: label JSON:
a.button(href="/api/animelist/" + user.ID) a.button(href="/api/animelist/" + user.ID)
Icon("upload") Icon("upload")
span Export anime list as JSON span Export anime list as JSON
.widget.mountable(data-api="/api/settings/" + user.ID)
h3.widget-title
Icon("picture-o")
span Avatar
.widget-section
label(for="Avatar.Source") Source:
select.widget-ui-element.action(id="Avatar.Source", data-field="Avatar.Source", value=user.Settings().Avatar.Source, data-action="save", data-trigger="change")
option(value="") Automatic
option(value="Gravatar") Gravatar
option(value="URL") Link
//- option(value="FileSystem") Upload
if user.Settings().Avatar.Source == "URL"
InputText("Avatar.SourceURL", user.Settings().Avatar.SourceURL, "Link", "Post the link to the image here")
if user.Settings().Avatar.Source == "Gravatar" || (user.Settings().Avatar.Source == "" && user.Avatar.Source == "Gravatar")
.profile-image-container.avatar-preview
img.profile-image.mountable(src=user.Gravatar(), alt="Gravatar")
if user.Settings().Avatar.Source == "URL" && user.Settings().Avatar.SourceURL != ""
.profile-image-container.avatar-preview
img.profile-image.mountable(src=strings.Replace(user.Settings().Avatar.SourceURL, "http://", "https://", 1), alt="Avatar preview")
.widget.mountable(data-api="/api/settings/" + user.ID)
h3.widget-title
Icon("font")
span Formatting
.widget-section
label(for="TitleLanguage")= "Title language:"
select.widget-ui-element.action(id="TitleLanguage", data-field="TitleLanguage", value=user.Settings().TitleLanguage, title="Language of anime titles", data-action="save", data-trigger="change")
option(value="canonical") Canonical
option(value="english") English
option(value="romaji") Romaji
option(value="japanese") 日本語
InputNumber("Format.RatingsPrecision", float64(user.Settings().Format.RatingsPrecision), "Ratings precision", "How many decimals after the comma would you like to display in ratings on anime pages?", "0", "2", "1")
.widget.mountable(data-api="/api/settings/" + user.ID)
h3.widget-title
Icon("star")
span PRO
if user.IsPro()
.widget-section
label
span Your PRO account expires in
span.utc-date(data-date=user.ProExpires)
span .
a.button.ajax(href="/shop")
Icon("star")
span Extend PRO account duration
else
.widget-section
label Would you like to support the site development?
a.button.ajax(href="/shop")
Icon("star")
span Go PRO
//- .widget.mountable(data-api="/api/settings/" + user.ID)
//- h3.widget-title
//- Icon("cogs")
//- span Settings
//- InputText("TitleLanguage", user.Settings().TitleLanguage, "Title language", "Language of anime titles")

View File

@ -1,8 +1,12 @@
.settings .settings
vertical horizontal-wrap-center
margin 0 auto // vertical
width 100% // margin 0 auto
max-width 400px // width 100%
// max-width 400px
.widget
max-width 400px
.widget-section > button, .widget-section > button,
.widget-section > .button .widget-section > .button

View File

@ -13,7 +13,7 @@ item-color-anime-support-ticket = hsl(217, 64%, 50%)
padding 0.5rem 1rem padding 0.5rem 1rem
.shop-item-name .shop-item-name
font-size 1.7rem font-size 1.6rem
text-align center text-align center
padding 0.75rem 0 padding 0.75rem 0
// border-bottom 1px solid rgba(0, 0, 0, 0.1) // border-bottom 1px solid rgba(0, 0, 0, 0.1)

View File

@ -13,8 +13,8 @@ var items = []*arn.Item{
Includes: Includes:
* Special highlight on the forums
* Chrome extension for quick list access * Chrome extension for quick list access
* Special highlight on the forums
* Access to the VIP channel on Discord * Access to the VIP channel on Discord
* PRO star on your profile * PRO star on your profile
* High priority for your personal suggestions * High priority for your personal suggestions
@ -34,8 +34,8 @@ Includes:
Includes: Includes:
* Special highlight on the forums
* Chrome extension for quick list access * Chrome extension for quick list access
* Special highlight on the forums
* Access to the VIP channel on Discord * Access to the VIP channel on Discord
* PRO star on your profile * PRO star on your profile
* High priority for your personal suggestions * High priority for your personal suggestions
@ -55,8 +55,8 @@ Includes:
Includes: Includes:
* Special highlight on the forums
* Chrome extension for quick list access * Chrome extension for quick list access
* Special highlight on the forums
* Access to the VIP channel on Discord * Access to the VIP channel on Discord
* PRO star on your profile * PRO star on your profile
* High priority for your personal suggestions * High priority for your personal suggestions
@ -76,8 +76,8 @@ Includes:
Includes: Includes:
* Special highlight on the forums
* Chrome extension for quick list access * Chrome extension for quick list access
* Special highlight on the forums
* Access to the VIP channel on Discord * Access to the VIP channel on Discord
* PRO star on your profile * PRO star on your profile
* High priority for your personal suggestions * High priority for your personal suggestions

View File

@ -251,6 +251,12 @@ var routeTests = map[string][]string{
"/dark-flame-master": nil, "/dark-flame-master": nil,
"/user": nil, "/user": nil,
"/settings": nil, "/settings": nil,
"/settings/accounts": nil,
"/settings/notifications": nil,
"/settings/apps": nil,
"/settings/avatar": nil,
"/settings/formatting": nil,
"/settings/pro": nil,
"/shop": nil, "/shop": nil,
"/shop/history": nil, "/shop/history": nil,
"/charge": nil, "/charge": nil,