New settings page
This commit is contained in:
parent
b0b819306b
commit
7cf3c2564b
11
main.go
11
main.go
@ -5,6 +5,7 @@ import (
|
||||
"github.com/aerogo/session-store-nano"
|
||||
"github.com/animenotifier/arn"
|
||||
"github.com/animenotifier/notify.moe/auth"
|
||||
"github.com/animenotifier/notify.moe/components"
|
||||
"github.com/animenotifier/notify.moe/components/css"
|
||||
"github.com/animenotifier/notify.moe/layout"
|
||||
"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("/character/:id", character.Get)
|
||||
app.Ajax("/new/thread", newthread.Get)
|
||||
app.Ajax("/settings", settings.Get)
|
||||
app.Ajax("/artworks", artworks.Get)
|
||||
app.Ajax("/amvs", amvs.Get)
|
||||
app.Ajax("/users", users.Active)
|
||||
@ -104,6 +104,15 @@ func configure(app *aero.Application) *aero.Application {
|
||||
app.Ajax("/statistics/anime", statistics.Anime)
|
||||
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
|
||||
app.Ajax("/soundtracks", soundtracks.Get)
|
||||
app.Ajax("/soundtracks/from/:index", soundtracks.From)
|
||||
|
@ -4,17 +4,19 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/aerogo/aero"
|
||||
"github.com/animenotifier/notify.moe/components"
|
||||
"github.com/animenotifier/arn"
|
||||
"github.com/animenotifier/notify.moe/utils"
|
||||
)
|
||||
|
||||
// Get user settings page.
|
||||
func Get(ctx *aero.Context) string {
|
||||
user := utils.GetUser(ctx)
|
||||
// Get settings.
|
||||
func Get(component func(*arn.User) string) func(*aero.Context) string {
|
||||
return func(ctx *aero.Context) string {
|
||||
user := utils.GetUser(ctx)
|
||||
|
||||
if user == nil {
|
||||
return ctx.Error(http.StatusUnauthorized, "Not logged in", nil)
|
||||
if user == nil {
|
||||
return ctx.Error(http.StatusUnauthorized, "Not logged in", nil)
|
||||
}
|
||||
|
||||
return ctx.HTML(component(user))
|
||||
}
|
||||
|
||||
return utils.AllowEmbed(ctx, ctx.HTML(components.Settings(user)))
|
||||
}
|
||||
|
@ -1,9 +1,17 @@
|
||||
component SettingsTabs
|
||||
.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)
|
||||
h1.page-title Settings
|
||||
component SettingsPersonal(user *arn.User)
|
||||
SettingsTabs
|
||||
|
||||
h1.page-title Personal settings
|
||||
|
||||
.settings
|
||||
.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("Website", user.Website, "Website", "Your homepage")
|
||||
|
||||
.widget.mountable(data-api="/api/user/" + user.ID)
|
||||
h3.widget-title
|
||||
Icon("cubes")
|
||||
span Accounts
|
||||
component SettingsNotifications(user *arn.User)
|
||||
SettingsTabs
|
||||
|
||||
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")
|
||||
h1.page-title Notification settings
|
||||
|
||||
.settings
|
||||
.widget.mountable
|
||||
h3.widget-title
|
||||
Icon("bell")
|
||||
@ -49,6 +52,130 @@ component Settings(user *arn.User)
|
||||
Icon("paper-plane")
|
||||
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
|
||||
h3.widget-title
|
||||
Icon("user-plus")
|
||||
@ -76,29 +203,6 @@ component Settings(user *arn.User)
|
||||
|
||||
Icon("circle-o")
|
||||
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
|
||||
h3.widget-title
|
||||
@ -116,71 +220,4 @@ component Settings(user *arn.User)
|
||||
label JSON:
|
||||
a.button(href="/api/animelist/" + user.ID)
|
||||
Icon("upload")
|
||||
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")
|
||||
span Export anime list as JSON
|
@ -1,8 +1,12 @@
|
||||
.settings
|
||||
vertical
|
||||
margin 0 auto
|
||||
width 100%
|
||||
max-width 400px
|
||||
horizontal-wrap-center
|
||||
// vertical
|
||||
// margin 0 auto
|
||||
// width 100%
|
||||
// max-width 400px
|
||||
|
||||
.widget
|
||||
max-width 400px
|
||||
|
||||
.widget-section > button,
|
||||
.widget-section > .button
|
||||
|
@ -13,7 +13,7 @@ item-color-anime-support-ticket = hsl(217, 64%, 50%)
|
||||
padding 0.5rem 1rem
|
||||
|
||||
.shop-item-name
|
||||
font-size 1.7rem
|
||||
font-size 1.6rem
|
||||
text-align center
|
||||
padding 0.75rem 0
|
||||
// border-bottom 1px solid rgba(0, 0, 0, 0.1)
|
||||
|
@ -13,8 +13,8 @@ var items = []*arn.Item{
|
||||
|
||||
Includes:
|
||||
|
||||
* Special highlight on the forums
|
||||
* Chrome extension for quick list access
|
||||
* Special highlight on the forums
|
||||
* Access to the VIP channel on Discord
|
||||
* PRO star on your profile
|
||||
* High priority for your personal suggestions
|
||||
@ -34,8 +34,8 @@ Includes:
|
||||
|
||||
Includes:
|
||||
|
||||
* Special highlight on the forums
|
||||
* Chrome extension for quick list access
|
||||
* Special highlight on the forums
|
||||
* Access to the VIP channel on Discord
|
||||
* PRO star on your profile
|
||||
* High priority for your personal suggestions
|
||||
@ -55,8 +55,8 @@ Includes:
|
||||
|
||||
Includes:
|
||||
|
||||
* Special highlight on the forums
|
||||
* Chrome extension for quick list access
|
||||
* Special highlight on the forums
|
||||
* Access to the VIP channel on Discord
|
||||
* PRO star on your profile
|
||||
* High priority for your personal suggestions
|
||||
@ -76,8 +76,8 @@ Includes:
|
||||
|
||||
Includes:
|
||||
|
||||
* Special highlight on the forums
|
||||
* Chrome extension for quick list access
|
||||
* Special highlight on the forums
|
||||
* Access to the VIP channel on Discord
|
||||
* PRO star on your profile
|
||||
* High priority for your personal suggestions
|
||||
|
6
tests.go
6
tests.go
@ -251,6 +251,12 @@ var routeTests = map[string][]string{
|
||||
"/dark-flame-master": nil,
|
||||
"/user": nil,
|
||||
"/settings": nil,
|
||||
"/settings/accounts": nil,
|
||||
"/settings/notifications": nil,
|
||||
"/settings/apps": nil,
|
||||
"/settings/avatar": nil,
|
||||
"/settings/formatting": nil,
|
||||
"/settings/pro": nil,
|
||||
"/shop": nil,
|
||||
"/shop/history": nil,
|
||||
"/charge": nil,
|
||||
|
Loading…
Reference in New Issue
Block a user