Albirew/nyaa-pantsu
Albirew
/
nyaa-pantsu
Archivé
1
0
Bifurcation 0

Account theme switcher (Pls merge) (#750)

* added pagination

* cleanup

* indentation fix

* fix

* Loads theme from context

* Basic theme switching working

* working properly

* Fuck golint tbqh

* united language and theme into one settings page

* made the settings page a little nicer

* fixed it so it works properly now

* removed parts of inline js and fixed bug

* removed remains of other theme switching method

* fixed very minor bug

* fix
Cette révision appartient à :
Steindór 2017-05-27 17:08:47 +00:00 révisé par alucard0134
Parent d485ae65fc
révision 25562e0d54
17 fichiers modifiés avec 136 ajouts et 82 suppressions

Voir le fichier

@ -16,7 +16,7 @@ import (
"github.com/NyaaPantsu/nyaa/service/scraper"
"github.com/NyaaPantsu/nyaa/service/torrent/metainfoFetcher"
"github.com/NyaaPantsu/nyaa/service/user"
"github.com/NyaaPantsu/nyaa/util/languages"
"github.com/NyaaPantsu/nyaa/util/publicSettings"
"github.com/NyaaPantsu/nyaa/util/log"
"github.com/NyaaPantsu/nyaa/util/search"
"github.com/NyaaPantsu/nyaa/util/signals"
@ -129,7 +129,7 @@ func main() {
if err != nil {
log.Fatal(err.Error())
}
err = languages.InitI18n(conf.I18n, userService.NewCurrentUserRetriever())
err = publicSettings.InitI18n(conf.I18n, userService.NewCurrentUserRetriever())
if err != nil {
log.Fatal(err.Error())
}

Voir le fichier

@ -31,6 +31,7 @@ type User struct {
APIToken string `gorm:"column:api_token"`
APITokenExpiry time.Time `gorm:"column:api_token_expiry"`
Language string `gorm:"column:language"`
Theme string `gorm:"column:theme"`
UserSettings string `gorm:"column:settings"`
// TODO: move this to PublicUser
@ -62,7 +63,7 @@ func (u User) Size() (s int) {
4*3 + //time.Time
3*2 + // arrays
// string arrays
len(u.Username) + len(u.Password) + len(u.Email) + len(u.APIToken) + len(u.MD5) + len(u.Language)
len(u.Username) + len(u.Password) + len(u.Email) + len(u.APIToken) + len(u.MD5) + len(u.Language) + len(u.Theme)
s *= 8
// Ignoring foreign key users. Fuck them.

Voir le fichier

@ -11,6 +11,47 @@ function toggleNightMode() {
localStorage.setItem("night", (night == "true") ? "false" : "true");
}
// Switches between themes when a new one is selected
function switchThemes(){
themeName = document.getElementById("theme-selector").value
var head = document.getElementsByTagName("head")[0];
// Remove the theme in place, it fails if one isn't set
try{
head.removeChild(document.getElementById("theme"));
} catch(err){}
// Don't add a node if we don't want extra styling
if(themeName === ""){
return;
}
// Create the new one and put it back
var newTheme = document.createElement("link");
newTheme.setAttribute("rel", "stylesheet");
newTheme.setAttribute("href", "/css/"+ themeName + ".css");
newTheme.setAttribute("id", "theme");
head.appendChild(newTheme);
}
function changeTheme(opt) {
theme = opt.value;
localStorage.setItem("theme", theme);
document.getElementById("theme").href = "/css/" + theme;
console.log(theme);
}
function toggleMascot(btn) {
var state= btn.value;
if (state == "hide") {
btn.innerHTML = "Mascot";
document.getElementById("mascot").className = "hide";
btn.value = "show";
} else {
btn.innerHTML = "Mascot";
document.getElementById("mascot").className = "";
btn.value = "hide";
}
}
// Used by spoiler tags
function toggleLayer(elem) {
if (elem.classList.contains("hide"))

Voir le fichier

@ -5,7 +5,7 @@ import (
"net/http"
"github.com/NyaaPantsu/nyaa/service/user"
"github.com/NyaaPantsu/nyaa/util/languages"
"github.com/NyaaPantsu/nyaa/util/publicSettings"
"github.com/NyaaPantsu/nyaa/util/timeHelper"
)
@ -15,11 +15,10 @@ type LanguagesJSONResponse struct {
Languages map[string]string `json:"languages"`
}
// SeeLanguagesHandler : Controller to view the languages
func SeeLanguagesHandler(w http.ResponseWriter, r *http.Request) {
_, Tlang := languages.GetTfuncAndLanguageFromRequest(r)
availableLanguages := languages.GetAvailableLanguages()
// SeePublicSettingsHandler : Controller to view the languages and themes
func SeePublicSettingsHandler(w http.ResponseWriter, r *http.Request) {
_, Tlang := publicSettings.GetTfuncAndLanguageFromRequest(r)
availableLanguages := publicSettings.GetAvailableLanguages()
defer r.Body.Close()
contentType := r.Header.Get("Content-Type")
if contentType == "application/json" {
@ -35,7 +34,7 @@ func SeeLanguagesHandler(w http.ResponseWriter, r *http.Request) {
Language: Tlang.Tag,
Languages: availableLanguages,
}
err := changeLanguageTemplate.ExecuteTemplate(w, "index.html", clv)
err := changePublicSettingsTemplate.ExecuteTemplate(w, "index.html", clv)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@ -43,25 +42,29 @@ func SeeLanguagesHandler(w http.ResponseWriter, r *http.Request) {
}
}
// ChangeLanguageHandler : Controller for changing the current language
func ChangeLanguageHandler(w http.ResponseWriter, r *http.Request) {
// ChangePublicSettingsHandler : Controller for changing the current language and theme
func ChangePublicSettingsHandler(w http.ResponseWriter, r *http.Request) {
theme := r.FormValue("theme")
lang := r.FormValue("language")
availableLanguages := publicSettings.GetAvailableLanguages()
defer r.Body.Close()
availableLanguages := languages.GetAvailableLanguages()
if _, exists := availableLanguages[lang]; !exists {
http.Error(w, "Language not available", http.StatusInternalServerError)
return
}
// If logged in, update user language; if not, set cookie.
// If logged in, update user language.
user, _ := userService.CurrentUser(r)
if user.ID > 0 {
user.Language = lang
user.Theme = theme
// I don't know if I should use this...
userService.UpdateUserCore(&user)
}
// Set cookie
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)})
url, _ := Router.Get("home").URL()
http.Redirect(w, r, url.String(), http.StatusSeeOther)

Voir le fichier

@ -114,8 +114,8 @@ func init() {
Router.Handle("/dumps", gzipDatabaseDumpHandler).Name("dump").Methods("GET")
Router.HandleFunc("/language", SeeLanguagesHandler).Methods("GET").Name("see_languages")
Router.HandleFunc("/language", ChangeLanguageHandler).Methods("POST").Name("change_language")
Router.HandleFunc("/settings", SeePublicSettingsHandler).Methods("GET").Name("see_languages")
Router.HandleFunc("/settings", ChangePublicSettingsHandler).Methods("POST").Name("see_languages")
Router.NotFoundHandler = http.HandlerFunc(NotFoundHandler)
}

Voir le fichier

@ -26,7 +26,7 @@ var homeTemplate,
viewUserDeleteTemplate,
userTorrentEd,
notFoundTemplate,
changeLanguageTemplate,
changePublicSettingsTemplate,
databaseDumpTemplate *template.Template
var panelIndex,
@ -128,10 +128,11 @@ func ReloadTemplates() {
file: "404.html",
},
{
templ: &changeLanguageTemplate,
name: "change_language",
file: "change_language.html",
templ: &changePublicSettingsTemplate,
name: "change_settings",
file: "public_settings.html",
},
}
for idx := range pubTempls {
pubTempls[idx].indexFile = filepath.Join(TemplateDir, "index.html")

Voir le fichier

@ -12,12 +12,12 @@ import (
"github.com/NyaaPantsu/nyaa/util"
"github.com/NyaaPantsu/nyaa/util/categories"
"github.com/NyaaPantsu/nyaa/util/filelist"
"github.com/NyaaPantsu/nyaa/util/languages"
"github.com/NyaaPantsu/nyaa/util/publicSettings"
)
type captchaData struct {
CaptchaID string
T languages.TemplateTfunc
T publicSettings.TemplateTfunc
}
// FuncMap : Functions accessible in templates by {{ $.Function }}
@ -146,7 +146,7 @@ var FuncMap = template.FuncMap{
return template.HTML(ret)
},
"Sukebei": config.IsSukebei,
"getDefaultLanguage": languages.GetDefaultLanguage,
"getDefaultLanguage": publicSettings.GetDefaultLanguage,
"getAvatar": func(hash string, size int) string {
return "https://www.gravatar.com/avatar/" + hash + "?s=" + strconv.Itoa(size)
},
@ -180,23 +180,23 @@ var FuncMap = template.FuncMap{
}
return ""
},
"fileSize": func(filesize int64, T languages.TemplateTfunc) template.HTML {
"fileSize": func(filesize int64, T publicSettings.TemplateTfunc) template.HTML {
if filesize == 0 {
return T("unknown")
}
return template.HTML(util.FormatFilesize(filesize))
},
"makeCaptchaData": func(captchaID string, T languages.TemplateTfunc) captchaData {
"makeCaptchaData": func(captchaID string, T publicSettings.TemplateTfunc) captchaData {
return captchaData{captchaID, T}
},
"DefaultUserSettings": func(s string) bool {
return config.DefaultUserSettings[s]
},
"makeTreeViewData": func(f *filelist.FileListFolder, nestLevel int, T languages.TemplateTfunc, identifierChain string) interface{} {
"makeTreeViewData": func(f *filelist.FileListFolder, nestLevel int, T publicSettings.TemplateTfunc, identifierChain string) interface{} {
return struct{
Folder *filelist.FileListFolder
NestLevel int
T languages.TemplateTfunc
T publicSettings.TemplateTfunc
IdentifierChain string
}{ f, nestLevel, T, identifierChain }
},

Voir le fichier

@ -9,7 +9,7 @@ import (
"github.com/NyaaPantsu/nyaa/service/user"
userForms "github.com/NyaaPantsu/nyaa/service/user/form"
"github.com/NyaaPantsu/nyaa/util/filelist"
"github.com/NyaaPantsu/nyaa/util/languages"
"github.com/NyaaPantsu/nyaa/util/publicSettings"
"github.com/gorilla/mux"
)
@ -74,6 +74,16 @@ type changeLanguageVariables struct {
Languages map[string]string
}
type ChangeThemeVariables struct {
commonTemplateVariables
}
type publicSettingsVariables struct {
commonTemplateVariables
Language string
Languages map[string]string
}
/* MODERATION Variables */
type panelIndexVbs struct {
@ -91,7 +101,8 @@ type panelIndexVbs struct {
type commonTemplateVariables struct {
Navigation navigation
Search searchForm
T languages.TemplateTfunc
T publicSettings.TemplateTfunc
Theme string
User *model.User
URL *url.URL // for parsing URL in templates
Route *mux.Route // for getting current route in templates
@ -140,7 +151,8 @@ func newCommonVariables(r *http.Request) commonTemplateVariables {
return commonTemplateVariables{
Navigation: newNavigation(),
Search: newSearchForm(),
T: languages.GetTfuncFromRequest(r),
T: publicSettings.GetTfuncFromRequest(r),
Theme: publicSettings.GetThemeFromRequest(r),
User: getUser(r),
URL: r.URL,
Route: mux.CurrentRoute(r),

Voir le fichier

@ -16,7 +16,7 @@ import (
"github.com/NyaaPantsu/nyaa/service/upload"
"github.com/NyaaPantsu/nyaa/service/user"
"github.com/NyaaPantsu/nyaa/service/user/permission"
"github.com/NyaaPantsu/nyaa/util/languages"
"github.com/NyaaPantsu/nyaa/util/publicSettings"
"github.com/NyaaPantsu/nyaa/util/log"
msg "github.com/NyaaPantsu/nyaa/util/messages"
)
@ -109,7 +109,7 @@ func UploadPostHandler(w http.ResponseWriter, r *http.Request) {
for _, follower := range user.Followers {
follower.ParseSettings() // We need to call it before checking settings
if follower.Settings.Get("new_torrent") {
T, _, _ := languages.TfuncAndLanguageWithFallback(follower.Language, follower.Language) // We need to send the notification to every user in their language
T, _, _ := publicSettings.TfuncAndLanguageWithFallback(follower.Language, follower.Language) // We need to send the notification to every user in their language
notifierService.NotifyUser(&follower, torrent.Identifier(), fmt.Sprintf(T("new_torrent_uploaded"), torrent.Name, user.Username), url.String(), follower.Settings.Get("new_torrent_email"))
}

Voir le fichier

@ -12,7 +12,7 @@ import (
"github.com/NyaaPantsu/nyaa/service/user/form"
"github.com/NyaaPantsu/nyaa/service/user/permission"
"github.com/NyaaPantsu/nyaa/util/crypto"
"github.com/NyaaPantsu/nyaa/util/languages"
"github.com/NyaaPantsu/nyaa/util/publicSettings"
msg "github.com/NyaaPantsu/nyaa/util/messages"
"github.com/NyaaPantsu/nyaa/util/modelHelper"
"github.com/gorilla/mux"
@ -72,7 +72,7 @@ func UserProfileHandler(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
vars := mux.Vars(r)
id := vars["id"]
Ts, _ := languages.GetTfuncAndLanguageFromRequest(r)
Ts, _ := publicSettings.GetTfuncAndLanguageFromRequest(r)
messages := msg.GetMessages(r)
userProfile, _, errorUser := userService.RetrieveUserForAdmin(id)
@ -125,7 +125,7 @@ func UserDetailsHandler(w http.ResponseWriter, r *http.Request) {
if userPermission.CurrentOrAdmin(currentUser, userProfile.ID) {
b := form.UserForm{}
modelHelper.BindValueForm(&b, r)
availableLanguages := languages.GetAvailableLanguages()
availableLanguages := publicSettings.GetAvailableLanguages()
userProfile.ParseSettings()
htv := userProfileEditVariables{newCommonVariables(r), &userProfile, b, messages.GetAllErrors(), messages.GetAllInfos(), availableLanguages}
err := viewProfileEditTemplate.ExecuteTemplate(w, "index.html", htv)
@ -154,7 +154,7 @@ func UserProfileFormHandler(w http.ResponseWriter, r *http.Request) {
userForm := form.UserForm{}
userSettingsForm := form.UserSettingsForm{}
Ts, _ := languages.GetTfuncAndLanguageFromRequest(r)
Ts, _ := publicSettings.GetTfuncAndLanguageFromRequest(r)
if len(r.PostFormValue("email")) > 0 {
form.EmailValidation(r.PostFormValue("email"), messages)
@ -189,7 +189,7 @@ func UserProfileFormHandler(w http.ResponseWriter, r *http.Request) {
}
}
}
availableLanguages := languages.GetAvailableLanguages()
availableLanguages := publicSettings.GetAvailableLanguages()
upev := userProfileEditVariables{
commonTemplateVariables: newCommonVariables(r),
UserProfile: &userProfile,
@ -325,7 +325,7 @@ func UserNotificationsHandler(w http.ResponseWriter, r *http.Request) {
currentUser := getUser(r)
if currentUser.ID > 0 {
messages := msg.GetMessages(r)
Ts, _ := languages.GetTfuncAndLanguageFromRequest(r)
Ts, _ := publicSettings.GetTfuncAndLanguageFromRequest(r)
if r.URL.Query()["clear"] != nil {
notifierService.DeleteAllNotifications(currentUser.ID)
messages.AddInfo("infos", Ts("notifications_cleared"))
@ -348,7 +348,7 @@ func UserAPIKeyResetHandler(w http.ResponseWriter, r *http.Request) {
id := vars["id"]
currentUser := getUser(r)
Ts, _ := languages.GetTfuncAndLanguageFromRequest(r)
Ts, _ := publicSettings.GetTfuncAndLanguageFromRequest(r)
messages := msg.GetMessages(r)
userProfile, _, errorUser := userService.RetrieveUserForAdmin(id)
if errorUser != nil || !userPermission.CurrentOrAdmin(currentUser, userProfile.ID) || userProfile.ID == 0 {

Voir le fichier

@ -17,7 +17,7 @@ import (
"github.com/NyaaPantsu/nyaa/service/user/permission"
"github.com/NyaaPantsu/nyaa/util"
"github.com/NyaaPantsu/nyaa/util/filelist"
"github.com/NyaaPantsu/nyaa/util/languages"
"github.com/NyaaPantsu/nyaa/util/publicSettings"
"github.com/NyaaPantsu/nyaa/util/log"
msg "github.com/NyaaPantsu/nyaa/util/messages"
"github.com/gorilla/mux"
@ -113,7 +113,7 @@ func PostCommentHandler(w http.ResponseWriter, r *http.Request) {
url, err := Router.Get("view_torrent").URL("id", strconv.FormatUint(uint64(torrent.ID), 10))
torrent.Uploader.ParseSettings()
if torrent.Uploader.Settings.Get("new_comment") {
T, _, _ := languages.TfuncAndLanguageWithFallback(torrent.Uploader.Language, torrent.Uploader.Language) // We need to send the notification to every user in their language
T, _, _ := publicSettings.TfuncAndLanguageWithFallback(torrent.Uploader.Language, torrent.Uploader.Language) // We need to send the notification to every user in their language
notifierService.NotifyUser(torrent.Uploader, comment.Identifier(), fmt.Sprintf(T("new_comment_on_torrent"), torrent.Name), url.String(), torrent.Uploader.Settings.Get("new_comment_email"))
}

Voir le fichier

@ -11,7 +11,7 @@ import (
"github.com/NyaaPantsu/nyaa/db"
"github.com/NyaaPantsu/nyaa/model"
"github.com/NyaaPantsu/nyaa/util/email"
"github.com/NyaaPantsu/nyaa/util/languages"
"github.com/NyaaPantsu/nyaa/util/publicSettings"
"github.com/NyaaPantsu/nyaa/util/timeHelper"
"github.com/gorilla/securecookie"
)
@ -20,7 +20,7 @@ var verificationHandler = securecookie.New(config.EmailTokenHashKey, nil)
// SendEmailVerification sends an email verification token via email.
func SendEmailVerification(to string, token string) error {
T, err := languages.GetDefaultTfunc()
T, err := publicSettings.GetDefaultTfunc()
if err != nil {
return err
}

Voir le fichier

@ -12,24 +12,18 @@
<!-- RSS Feed with Context -->
<link href="{{ block "rss_link" . }}{{ genRouteWithQuery "feed" .URL }}{{end}}" rel="alternate" type="application/rss+xml" title="Nyaa Pantsu - {{block "rsstitle" .}}Last torrents{{end}} RSS Feed" />
<!-- do NOT move -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css">
<link rel="stylesheet" id="style" href="{{.URL.Parse "/css/main.css"}}?v=3">
<link rel="stylesheet" id="theme" href="">
<!-- Base theme -->
<link rel="stylesheet" id="style" href="{{.URL.Parse "/css/main.css"}}?v=2">
<!-- User selected theme, if any -->
{{if $.Theme}}<link rel="stylesheet" id="theme" href="/css/{{$.Theme}}.css">{{end}}
<!-- Search Box for Google -->
<script type="application/ld+json">{"@context":"https://schema.org","@type":"WebSite","url":"https://nyaa.pantsu.cat/","potentialAction":{"@type":"SearchAction","target":"https://nyaa.pantsu.cat/search?q={search_term_string}","query-input":"required name=search_term_string"}}</script>
<script>
// We need this inline javascript for preventing theme flickering
function changeTheme(opt) {
theme = opt.value;
localStorage.setItem("theme", theme);
document.getElementById("theme").href = "/css/" + theme;
console.log(theme);
}
function toggleMascot(btn) {
var state= btn.value;
if (state == "hide") {
@ -42,24 +36,10 @@
btn.value = "hide";
}
}
function setTheme() {
var themeFromStorage = localStorage.getItem('theme');
document.getElementById('theme').href = "/css/" + themeFromStorage;
window.addEventListener("load", () => {
var selectOptions = document.getElementById("theme_select").children
for (var option of selectOptions) {
option.selected = option.value == themeFromStorage;
}
});
}
</script>
<!-- Fix theme switching for google chrome where onload doesn't work -->
<script type="text/javascript">
setTheme();
</script>
{{ block "additional_header" .}}{{end}}
</head>
<body onload="setTheme();">
<body>
<nav id="header" class="header">
<div class="container">
<div class="h-left">
@ -108,15 +88,8 @@
<div class="container footer center">
<div class="footer-opt">
<select onchange="changeTheme(this.options[this.selectedIndex])" name="Theme" id="theme_select" class="form-input">
<option value="">Default</option>
<option value="g.css">/g/ Anon</option>
<option value="tomorrow.css">Tomorrow</option>
</select>
<button class="form-input btn" onclick="toggleMascot(this)" value="hide"><span class="oi" data-glyph="eye"></span> Mascot</button>
<p><a href="/language">Change Language</a></p>
<p><a href="/settings">Change Settings</a></p>
</div>
<span><i>Powered by <a href="#">NyaaPantsu</a></i></span>

Voir le fichier

@ -11,8 +11,18 @@
<option value="{{ $tag }}" {{ if eq $currentLanguage $tag }}selected{{end}}>{{ $translatedName }}</option>
{{ end }}
</select>
<h3>{{call $.T "theme"}}</h3>
<select id="theme-selector" name="theme" class="form-input" onchange="switchThemes()">
<option value="{{$.Theme}}" selected>{{call $.T "select"}}</option>
<option value="g">/g/</option>
<option value="tomorrow">Tomorrow</option>
<option value="">None</option>
</select>
</br>
</br>
<button type="submit" class="form-input btn">{{call $.T "save_changes"}}</button>
</div>
</form>
<div style="padding-bottom: 1em"></div>
</div>

Voir le fichier

@ -4,7 +4,7 @@ import (
"fmt"
"net/http"
"github.com/NyaaPantsu/nyaa/util/languages"
"github.com/NyaaPantsu/nyaa/util/publicSettings"
"github.com/gorilla/context"
"github.com/nicksnyder/go-i18n/i18n"
)
@ -24,13 +24,13 @@ type Messages struct {
func GetMessages(r *http.Request) *Messages {
if rv := context.Get(r, MessagesKey); rv != nil {
mes := rv.(*Messages)
T, _ := languages.GetTfuncAndLanguageFromRequest(r)
T, _ := publicSettings.GetTfuncAndLanguageFromRequest(r)
mes.T = T
mes.r = r
return mes
}
context.Set(r, MessagesKey, &Messages{})
T, _ := languages.GetTfuncAndLanguageFromRequest(r)
T, _ := publicSettings.GetTfuncAndLanguageFromRequest(r)
return &Messages{make(map[string][]string), make(map[string][]string), r, T}
}

Voir le fichier

@ -1,4 +1,4 @@
package languages
package publicSettings
import (
"errors"
@ -133,6 +133,19 @@ func GetTfuncFromRequest(r *http.Request) TemplateTfunc {
}
}
// GetThemeFromRequest: Gets the user selected theme from the request
func GetThemeFromRequest(r *http.Request) string {
user, _ := getCurrentUser(r)
if user.ID > 0 {
return user.Theme
}
cookie, err := r.Cookie("theme")
if err == nil {
return cookie.Value
}
return ""
}
func getCurrentUser(r *http.Request) (model.User, error) {
if userRetriever == nil {
return model.User{}, errors.New("failed to get current user: no user retriever set")

Voir le fichier

@ -1,4 +1,4 @@
package languages
package publicSettings
import (
"path"