diff --git a/main.go b/main.go index 32eb06f3..84301e33 100644 --- a/main.go +++ b/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) diff --git a/pages/settings/settings.go b/pages/settings/settings.go index a7a03e0a..87c47159 100644 --- a/pages/settings/settings.go +++ b/pages/settings/settings.go @@ -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))) } diff --git a/pages/settings/settings.pixy b/pages/settings/settings.pixy index 2a8dfa0a..a42106e2 100644 --- a/pages/settings/settings.pixy +++ b/pages/settings/settings.pixy @@ -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") \ No newline at end of file + span Export anime list as JSON \ No newline at end of file diff --git a/pages/settings/settings.scarlet b/pages/settings/settings.scarlet index 1bd383ff..23a00d75 100644 --- a/pages/settings/settings.scarlet +++ b/pages/settings/settings.scarlet @@ -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 diff --git a/pages/shop/shop.scarlet b/pages/shop/shop.scarlet index 1a70c6df..8c4c25be 100644 --- a/pages/shop/shop.scarlet +++ b/pages/shop/shop.scarlet @@ -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) diff --git a/patches/add-shop-items/add-shop-items.go b/patches/add-shop-items/add-shop-items.go index 4d79929b..89dd101e 100644 --- a/patches/add-shop-items/add-shop-items.go +++ b/patches/add-shop-items/add-shop-items.go @@ -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 diff --git a/tests.go b/tests.go index 00c691be..ff45fb35 100644 --- a/tests.go +++ b/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,