Add customizable mascot by URL.
Add a new setting for customizable mascots, with a new User field MascotURL, and a corresponding cookie setting.
Cette révision appartient à :
Parent
93af9a7df4
révision
e10070b2a9
7 fichiers modifiés avec 56 ajouts et 10 suppressions
|
@ -33,6 +33,7 @@ type User struct {
|
|||
Language string `gorm:"column:language"`
|
||||
Theme string `gorm:"column:theme"`
|
||||
Mascot string `gorm:"column:mascot"`
|
||||
MascotURL string `gorm:"column:mascot_url"`
|
||||
UserSettings string `gorm:"column:settings"`
|
||||
|
||||
// TODO: move this to PublicUser
|
||||
|
|
|
@ -26,6 +26,10 @@ body {
|
|||
pointer-events: auto;
|
||||
}
|
||||
|
||||
#mascot.custom-mascot {
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.header {
|
||||
z-index: 3;
|
||||
position: fixed;
|
||||
|
|
|
@ -3,6 +3,7 @@ package router
|
|||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/NyaaPantsu/nyaa/service/user"
|
||||
"github.com/NyaaPantsu/nyaa/util/publicSettings"
|
||||
|
@ -47,6 +48,7 @@ func ChangePublicSettingsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
theme := r.FormValue("theme")
|
||||
lang := r.FormValue("language")
|
||||
mascot := r.FormValue("mascot")
|
||||
mascotUrl := r.FormValue("mascot_url")
|
||||
|
||||
availableLanguages := publicSettings.GetAvailableLanguages()
|
||||
defer r.Body.Close()
|
||||
|
@ -54,13 +56,26 @@ func ChangePublicSettingsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
http.Error(w, "Language not available", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
// FIXME Are the settings actually sanitized?
|
||||
// Limit the mascot URL, so base64-encoded images aren't valid
|
||||
if len(mascotUrl) > 256 {
|
||||
http.Error(w, "Mascot URL is too long (max is 255 chars)", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// If logged in, update user language.
|
||||
_, err := url.Parse(mascotUrl)
|
||||
if err != nil {
|
||||
http.Error(w, "Error parsing mascot URL: " + err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// If logged in, update user settings.
|
||||
user, _ := userService.CurrentUser(r)
|
||||
if user.ID > 0 {
|
||||
user.Language = lang
|
||||
user.Theme = theme
|
||||
user.Mascot = mascot
|
||||
user.MascotURL = mascotUrl
|
||||
// I don't know if I should use this...
|
||||
userService.UpdateUserCore(&user)
|
||||
}
|
||||
|
@ -68,6 +83,7 @@ func ChangePublicSettingsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
http.SetCookie(w, &http.Cookie{Name: "lang", Value: lang, Expires: timeHelper.FewDaysLater(365)})
|
||||
http.SetCookie(w, &http.Cookie{Name: "theme", Value: theme, Expires: timeHelper.FewDaysLater(365)})
|
||||
http.SetCookie(w, &http.Cookie{Name: "mascot", Value: mascot, Expires: timeHelper.FewDaysLater(365)})
|
||||
http.SetCookie(w, &http.Cookie{Name: "mascot_url", Value: mascotUrl, Expires: timeHelper.FewDaysLater(365)})
|
||||
|
||||
url, _ := Router.Get("home").URL()
|
||||
http.Redirect(w, r, url.String(), http.StatusSeeOther)
|
||||
|
|
|
@ -103,6 +103,7 @@ type commonTemplateVariables struct {
|
|||
T publicSettings.TemplateTfunc
|
||||
Theme string
|
||||
Mascot string
|
||||
MascotURL string
|
||||
User *model.User
|
||||
URL *url.URL // for parsing URL in templates
|
||||
Route *mux.Route // for getting current route in templates
|
||||
|
@ -156,6 +157,7 @@ func newCommonVariables(r *http.Request) commonTemplateVariables {
|
|||
T: publicSettings.GetTfuncFromRequest(r),
|
||||
Theme: publicSettings.GetThemeFromRequest(r),
|
||||
Mascot: publicSettings.GetMascotFromRequest(r),
|
||||
MascotURL: publicSettings.GetMascotUrlFromRequest(r),
|
||||
User: getUser(r),
|
||||
URL: r.URL,
|
||||
Route: mux.CurrentRoute(r),
|
||||
|
|
|
@ -68,16 +68,19 @@
|
|||
<div class="content container center">
|
||||
{{block "content" .}}{{call $.T "nothing_here"}}{{end}}
|
||||
</div>
|
||||
|
||||
{{if ne .Mascot "hide"}}
|
||||
<div id="mascot" class="hide-xs" onclick="playVoice();"></div>
|
||||
{{ if eq .Theme "tomorrow" }}
|
||||
<audio id="explosion" hidden preload="none">
|
||||
<source src="https://megumin.love/sounds/explosion.mp3" type="audio/mpeg">
|
||||
</audio>
|
||||
{{ else }}
|
||||
<audio id="nyanpassu" hidden preload="none">
|
||||
<source src="https://a.doko.moe/sewang.mp3" type="audio/mpeg">
|
||||
</audio>
|
||||
<div id="mascot" class="hide-xs{{if ne .MascotURL ""}} custom-mascot{{end}}" onclick="playVoice();" {{if ne .MascotURL ""}}style="background-image: url('{{.MascotURL}}');"{{end}}></div>
|
||||
{{ if ne .MascotURL "" }}
|
||||
{{ if eq .Theme "tomorrow" }}
|
||||
<audio id="explosion" hidden preload="none">
|
||||
<source src="https://megumin.love/sounds/explosion.mp3" type="audio/mpeg">
|
||||
</audio>
|
||||
{{ else }}
|
||||
<audio id="nyanpassu" hidden preload="none">
|
||||
<source src="https://a.doko.moe/sewang.mp3" type="audio/mpeg">
|
||||
</audio>
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
<div class="pagination">
|
||||
|
|
|
@ -25,6 +25,11 @@
|
|||
<option value="hide" {{ if eq $.Mascot "hide" }} selected{{end}}>{{call $.T "hide"}}</option>
|
||||
</select>
|
||||
</br>
|
||||
|
||||
<h3>{{call $.T "mascot_url"}}</h3>
|
||||
<input type="text" name="mascot_url" class="form-input" value="{{ $.MascotURL }}">
|
||||
</br>
|
||||
|
||||
<p>{{call $.T "cookies"}}</p>
|
||||
<button type="submit" class="form-input btn">{{call $.T "save_changes"}}</button>
|
||||
</div>
|
||||
|
|
|
@ -159,6 +159,21 @@ func GetMascotFromRequest(r *http.Request) string {
|
|||
return "show"
|
||||
}
|
||||
|
||||
// GetMascotUrlFromRequest: Get the user selected mascot url from the request.
|
||||
// Returns an empty string if not set.
|
||||
func GetMascotUrlFromRequest(r *http.Request) string {
|
||||
user, _ := getCurrentUser(r)
|
||||
if user.ID > 0 {
|
||||
return user.MascotURL
|
||||
}
|
||||
|
||||
cookie, err := r.Cookie("mascot_url")
|
||||
if err == nil {
|
||||
return cookie.Value
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func getCurrentUser(r *http.Request) (model.User, error) {
|
||||
if userRetriever == nil {
|
||||
|
|
Référencer dans un nouveau ticket