diff --git a/auth/auth.go b/auth/auth.go index 02fb1413..3cd67a9b 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -3,7 +3,7 @@ package auth import "github.com/aerogo/aero" import "github.com/animenotifier/notify.moe/utils" -const newUserStartRoute = "/settings" +const newUserStartRoute = "/welcome" // Install installs the authentication routes in the application. func Install(app *aero.Application) { diff --git a/pages/embed/embed.go b/pages/embed/embed.go index 68117f69..a175975f 100644 --- a/pages/embed/embed.go +++ b/pages/embed/embed.go @@ -16,6 +16,10 @@ func Get(ctx *aero.Context) string { return utils.AllowEmbed(ctx, ctx.HTML(components.Login("_blank"))) } + if !user.HasBasicInfo() { + return utils.AllowEmbed(ctx, ctx.HTML(components.ExtensionEnterBasicInfo())) + } + // Extension is enabled as long as the site isn't finished yet. // --- // if !user.IsPro() && user.TimeSinceRegistered() > 14*24*time.Hour { diff --git a/pages/embed/embed.pixy b/pages/embed/embed.pixy index 45f0dead..bf6e9c99 100644 --- a/pages/embed/embed.pixy +++ b/pages/embed/embed.pixy @@ -10,4 +10,13 @@ component ExtensionNavigation(user *arn.User) .spacer a.button(href="/support", target="_blank") - RawIcon("heart") \ No newline at end of file + RawIcon("heart") + +component ExtensionEnterBasicInfo + h1.mountable Welcome! + p.welcome-text.mountable Please complete some basic information about your profile. + + .buttons.mountable + a.button(href="/welcome", target="_blank") + Icon("pencil") + span Complete profile \ No newline at end of file diff --git a/pages/home/home.go b/pages/home/home.go index 7a6d82eb..7cad055d 100644 --- a/pages/home/home.go +++ b/pages/home/home.go @@ -14,5 +14,9 @@ func Get(ctx *aero.Context) string { return frontpage.Get(ctx) } + if !user.HasBasicInfo() { + return utils.SmartRedirect(ctx, "/welcome") + } + return utils.SmartRedirect(ctx, "/+"+user.Nick+"/animelist/watching") } diff --git a/pages/index/coreroutes/coreroutes.go b/pages/index/coreroutes/coreroutes.go index 7669e9ab..0ee589f3 100644 --- a/pages/index/coreroutes/coreroutes.go +++ b/pages/index/coreroutes/coreroutes.go @@ -9,6 +9,7 @@ import ( "github.com/animenotifier/notify.moe/pages/login" "github.com/animenotifier/notify.moe/pages/statistics" "github.com/animenotifier/notify.moe/pages/terms" + "github.com/animenotifier/notify.moe/pages/welcome" ) // Register registers the page routes. @@ -19,6 +20,9 @@ func Register(l *layout.Layout) { // Login l.Page("/login", login.Get) + // Welcome + l.Page("/welcome", welcome.Get) + // Activity l.Page("/activity", activity.Global) l.Page("/activity/from/:index", activity.Global) diff --git a/pages/listimport/listimport.pixy b/pages/listimport/listimport.pixy index 642c743d..e8ad67d6 100644 --- a/pages/listimport/listimport.pixy +++ b/pages/listimport/listimport.pixy @@ -22,4 +22,16 @@ component ImportLists(user *arn.User) .widget-section a.button(href="/import/myanimelist/animelist") Icon("download") - span Import MyAnimeList \ No newline at end of file + span Import MyAnimeList + +component ImportFinished(user *arn.User) + h1.mountable Import finished + + .buttons + a.button.mountable(href=user.Link()) + Icon("user") + span Profile + + a.button.mountable(href=user.Link() + "/animelist/watching") + Icon("list") + span Anime list \ No newline at end of file diff --git a/pages/listimport/listimportanilist/anilist.go b/pages/listimport/listimportanilist/anilist.go index a2695bf3..5f359349 100644 --- a/pages/listimport/listimportanilist/anilist.go +++ b/pages/listimport/listimportanilist/anilist.go @@ -67,8 +67,7 @@ func Finish(ctx *aero.Context) string { } animeList.Save() - - return utils.SmartRedirect(ctx, "/+"+user.Nick+"/animelist/watching") + return ctx.HTML(components.ImportFinished(user)) } // getMatches finds and returns all matches for the logged in user. diff --git a/pages/listimport/listimportkitsu/kitsu.go b/pages/listimport/listimportkitsu/kitsu.go index b1fd726d..58503b00 100644 --- a/pages/listimport/listimportkitsu/kitsu.go +++ b/pages/listimport/listimportkitsu/kitsu.go @@ -78,8 +78,7 @@ func Finish(ctx *aero.Context) string { } animeList.Save() - - return utils.SmartRedirect(ctx, "/+"+user.Nick+"/animelist/watching") + return ctx.HTML(components.ImportFinished(user)) } // getMatches finds and returns all matches for the logged in user. diff --git a/pages/listimport/listimportmyanimelist/myanimelist.go b/pages/listimport/listimportmyanimelist/myanimelist.go index b18c10ec..071f9761 100644 --- a/pages/listimport/listimportmyanimelist/myanimelist.go +++ b/pages/listimport/listimportmyanimelist/myanimelist.go @@ -72,8 +72,7 @@ func Finish(ctx *aero.Context) string { } animeList.Save() - - return utils.SmartRedirect(ctx, "/+"+user.Nick+"/animelist/watching") + return ctx.HTML(components.ImportFinished(user)) } // getMatches finds and returns all matches for the logged in user. diff --git a/pages/settings/personal.pixy b/pages/settings/personal.pixy index d5b455d9..648baf49 100644 --- a/pages/settings/personal.pixy +++ b/pages/settings/personal.pixy @@ -42,16 +42,7 @@ component SettingsPersonal(user *arn.User) //- //- File upload //- if user.Settings().Avatar.Source == "FileSystem" - InputFileUpload("avatar-input", "File", "image", "/api/upload/avatar") - - .profile-image-container.avatar-preview - if user.HasAvatar() - img.avatar-input-preview.profile-image.lazy(data-src=user.AvatarLink("large"), data-webp="true", alt="Profile image", title="Recommended: 560 x 560 | PNG or JPG") - else - img.avatar-input-preview.profile-image.hidden(src=user.AvatarLink("large"), alt="Profile image", title="Recommended: 560 x 560 | PNG or JPG") - - #avatar-input-preview-svg - SVGProfileImage(user) + AvatarInput(user) .widget.mountable(data-api="/api/settings/" + user.ID) h3.widget-title @@ -66,3 +57,15 @@ component SettingsPersonal(user *arn.User) if !user.IsPro() .footer p PRO account required. + +component AvatarInput(user *arn.User) + InputFileUpload("avatar-input", "File", "image", "/api/upload/avatar") + + .profile-image-container.avatar-preview + if user.HasAvatar() + img.avatar-input-preview.profile-image.lazy(data-src=user.AvatarLink("large"), data-webp="true", alt="Profile image", title="Recommended: 560 x 560 | PNG or JPG") + else + img.avatar-input-preview.profile-image.hidden(src=user.AvatarLink("large"), alt="Profile image", title="Recommended: 560 x 560 | PNG or JPG") + + #avatar-input-preview-svg + SVGProfileImage(user) \ No newline at end of file diff --git a/pages/welcome/welcome.go b/pages/welcome/welcome.go new file mode 100644 index 00000000..6a1529c7 --- /dev/null +++ b/pages/welcome/welcome.go @@ -0,0 +1,20 @@ +package welcome + +import ( + "net/http" + + "github.com/aerogo/aero" + "github.com/animenotifier/notify.moe/components" + "github.com/animenotifier/notify.moe/utils" +) + +// Get returns the welcome page. +func Get(ctx *aero.Context) string { + user := utils.GetUser(ctx) + + if user == nil { + return ctx.Error(http.StatusUnauthorized, "Not logged in") + } + + return ctx.HTML(components.Welcome(user)) +} diff --git a/pages/welcome/welcome.pixy b/pages/welcome/welcome.pixy new file mode 100644 index 00000000..737d6530 --- /dev/null +++ b/pages/welcome/welcome.pixy @@ -0,0 +1,44 @@ +component Welcome(user *arn.User) + .welcome + if user.HasBasicInfo() + h1.mountable Thanks! + else + h1.mountable Welcome! + + if !user.HasNick() + p.welcome-text.mountable To start using notify.moe, please enter a username. + + .mountable(data-api="/api/user/" + user.ID) + //- [^\\W\\s\\d]{1,24}[A-Za-z]{1} + InputText("Nick", user.CleanNick(), "Nick", "Your username on notify.moe") + + .footer.mountable + p Only letters and underscore. + else if !user.HasAvatar() + p.welcome-text.mountable Add an avatar so people can recognize you. + + .mountable(data-api="/api/user/" + user.ID) + AvatarInput(user) + + .footer.mountable + p Recommended size: 560x560 (minimum: 280x280) + else if user.Introduction == "" + p.welcome-text.mountable Write a little introduction so people know who you are! + + .mountable(data-api="/api/user/" + user.ID) + InputTextArea("Introduction", user.Introduction, "Introduction", "Tell us about yourself") + + .footer.mountable + p Markdown allowed. + else + p.welcome-text.mountable You're ready to start using Anime Notifier! + + .buttons.mountable + if len(user.AnimeList().Items) == 0 + a.button(href="/settings/accounts") + Icon("download") + span Import anime list + else + a.button(href=user.Link()) + Icon("user") + span= user.Nick \ No newline at end of file diff --git a/pages/welcome/welcome.scarlet b/pages/welcome/welcome.scarlet new file mode 100644 index 00000000..f4f60f64 --- /dev/null +++ b/pages/welcome/welcome.scarlet @@ -0,0 +1,10 @@ +.welcome + max-width 600px + margin 0 auto + + label + display none + +.welcome-text + text-align center + margin-bottom 1rem \ No newline at end of file diff --git a/scripts/Actions/Theme.ts b/scripts/Actions/Theme.ts index ef2a997e..0b0468b1 100644 --- a/scripts/Actions/Theme.ts +++ b/scripts/Actions/Theme.ts @@ -41,9 +41,9 @@ const themes = { "tip-bg-color": "hsl(0, 0%, 10%)", // "tip-bg-color": "hsl(var(--bg-color-h), var(--bg-color-s), 10%)", - "post-like-color": "var(--link-color)", - "post-unlike-color": "var(--link-color)", - "post-permalink-color": "var(--link-color)", + "like-color": "var(--link-color)", + "unlike-color": "var(--link-color)", + "permalink-color": "var(--link-color)", "quote-color": "var(--text-color)", diff --git a/scripts/AnimeNotifier.ts b/scripts/AnimeNotifier.ts index 63d4521a..903bdd11 100644 --- a/scripts/AnimeNotifier.ts +++ b/scripts/AnimeNotifier.ts @@ -171,6 +171,12 @@ export default class AnimeNotifier { // Apply page title this.applyPageTitle() + + // Auto-focus first input element on welcome page. + if(location.pathname === "/welcome") { + let firstInput = this.app.content.getElementsByTagName("input")[0] as HTMLInputElement + firstInput.focus() + } } applyPageTitle() { @@ -1118,6 +1124,7 @@ export default class AnimeNotifier { } if(!apiObject) { + this.statusMessage.showError("API object not found") throw "API object not found" } diff --git a/styles/forum.scarlet b/styles/forum.scarlet index 41240a3b..ce227e61 100644 --- a/styles/forum.scarlet +++ b/styles/forum.scarlet @@ -107,16 +107,16 @@ post-content-padding-y = 0.75rem margin-right 0.4em .post-permalink - color post-permalink-color + color permalink-color .post-like - color post-like-color + color like-color .post-unlike - color post-unlike-color + color unlike-color .post-delete - color post-delete-color + color delete-color .post-save // diff --git a/styles/include/config.scarlet b/styles/include/config.scarlet index a5323c58..22de7f9b 100644 --- a/styles/include/config.scarlet +++ b/styles/include/config.scarlet @@ -80,10 +80,10 @@ quote-color = hsl(0, 0%, 45%) quote-side-border-color = quote-color // Forum -post-like-color = green !important -post-unlike-color = rgb(255, 32, 12) !important -post-delete-color = post-unlike-color !important -post-permalink-color = blue !important +like-color = green +unlike-color = rgb(255, 32, 12) +delete-color = unlike-color +permalink-color = blue table-row-hover-background = hsla(0, 0%, 0%, 0.01) anime-list-item-name-color = link-color diff --git a/styles/input.scarlet b/styles/input.scarlet index cd8863db..b43ff3a1 100644 --- a/styles/input.scarlet +++ b/styles/input.scarlet @@ -34,6 +34,14 @@ input, select input height input-height + [pattern] + :focus + :invalid + border-color red !important + + :valid + border-color green !important + :active transform translateY(3px) diff --git a/utils/routetests/All.go b/utils/routetests/All.go index ceb74462..f4a83bc9 100644 --- a/utils/routetests/All.go +++ b/utils/routetests/All.go @@ -483,6 +483,7 @@ var routeTests = map[string][]string{ "/log/from/:index": nil, "/inventory": nil, "/extension/embed": nil, + "/welcome": nil, } // All returns which specific routes to test for a given generic route.