210 lines
5.2 KiB
Go
Executable file
210 lines
5.2 KiB
Go
Executable file
package main
|
|
|
|
import (
|
|
"html/template"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type UserSettings struct {
|
|
Theme string
|
|
SiteLanguage string
|
|
SearchLanguage string
|
|
SafeSearch string
|
|
IsThemeDark bool
|
|
}
|
|
|
|
func loadUserSettings(w http.ResponseWriter, r *http.Request) UserSettings {
|
|
var settings UserSettings
|
|
saveRequired := false
|
|
|
|
// Load theme
|
|
if cookie, err := r.Cookie("theme"); err == nil {
|
|
settings.Theme = cookie.Value
|
|
} else {
|
|
settings.Theme = "dark"
|
|
saveRequired = true
|
|
}
|
|
|
|
// Load site language
|
|
if cookie, err := r.Cookie("site_language"); err == nil {
|
|
settings.SiteLanguage = cookie.Value
|
|
} else {
|
|
// If no site language is set, use Accept-Language or default to "en"
|
|
acceptLang := r.Header.Get("Accept-Language")
|
|
if acceptLang != "" {
|
|
settings.SiteLanguage = normalizeLangCode(strings.Split(acceptLang, ",")[0])
|
|
} else {
|
|
settings.SiteLanguage = "en" // Default language
|
|
}
|
|
saveRequired = true
|
|
}
|
|
|
|
// Load search language (can be empty)
|
|
if cookie, err := r.Cookie("search_language"); err == nil {
|
|
settings.SearchLanguage = cookie.Value
|
|
}
|
|
|
|
// Load safe search
|
|
if cookie, err := r.Cookie("safe"); err == nil {
|
|
settings.SafeSearch = cookie.Value
|
|
} else {
|
|
settings.SafeSearch = ""
|
|
saveRequired = true
|
|
}
|
|
|
|
if saveRequired {
|
|
saveUserSettings(w, settings)
|
|
}
|
|
|
|
return settings
|
|
}
|
|
|
|
func saveUserSettings(w http.ResponseWriter, settings UserSettings) {
|
|
expiration := time.Now().Add(90 * 24 * time.Hour)
|
|
|
|
http.SetCookie(w, &http.Cookie{
|
|
Name: "theme",
|
|
Value: settings.Theme,
|
|
Path: "/",
|
|
Expires: expiration,
|
|
Secure: true,
|
|
SameSite: http.SameSiteStrictMode,
|
|
})
|
|
http.SetCookie(w, &http.Cookie{
|
|
Name: "site_language",
|
|
Value: settings.SiteLanguage,
|
|
Path: "/",
|
|
Expires: expiration,
|
|
Secure: true,
|
|
SameSite: http.SameSiteStrictMode,
|
|
})
|
|
http.SetCookie(w, &http.Cookie{
|
|
Name: "search_language",
|
|
Value: settings.SearchLanguage,
|
|
Path: "/",
|
|
Expires: expiration,
|
|
Secure: true,
|
|
SameSite: http.SameSiteStrictMode,
|
|
})
|
|
http.SetCookie(w, &http.Cookie{
|
|
Name: "safe",
|
|
Value: settings.SafeSearch,
|
|
Path: "/",
|
|
Expires: expiration,
|
|
Secure: true,
|
|
SameSite: http.SameSiteStrictMode,
|
|
})
|
|
|
|
printDebug("settings saved: %v", settings)
|
|
}
|
|
|
|
func handleSaveSettings(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method == "POST" {
|
|
// Load current settings
|
|
settings := loadUserSettings(w, r)
|
|
|
|
// Update only the settings that were submitted in the form
|
|
if theme := r.FormValue("theme"); theme != "" {
|
|
settings.Theme = theme
|
|
}
|
|
|
|
// Update site language if provided
|
|
if siteLang := r.FormValue("site_lang"); siteLang != "" {
|
|
settings.SiteLanguage = siteLang
|
|
} else {
|
|
// If site_lang is empty, try to get from Accept-Language header
|
|
acceptLang := r.Header.Get("Accept-Language")
|
|
if acceptLang != "" {
|
|
settings.SiteLanguage = strings.Split(acceptLang, ",")[0]
|
|
}
|
|
}
|
|
|
|
// Update search language if provided
|
|
if searchLang := r.FormValue("search_lang"); searchLang != "" {
|
|
settings.SearchLanguage = searchLang
|
|
}
|
|
|
|
// Update safe search if provided
|
|
if safe := r.FormValue("safe"); safe != "" {
|
|
settings.SafeSearch = safe
|
|
}
|
|
|
|
// Save the updated settings
|
|
saveUserSettings(w, settings)
|
|
|
|
// Redirect back to the previous page or settings page
|
|
http.Redirect(w, r, r.FormValue("past"), http.StatusSeeOther)
|
|
}
|
|
}
|
|
|
|
func handleSettings(w http.ResponseWriter, r *http.Request) {
|
|
// Load user settings
|
|
settings = loadUserSettings(w, r)
|
|
|
|
data := struct {
|
|
LanguageOptions []LanguageOption
|
|
CurrentSiteLang string
|
|
CurrentSearchLang string
|
|
Theme string
|
|
Safe string
|
|
IsThemeDark bool
|
|
}{
|
|
LanguageOptions: languageOptions,
|
|
CurrentSiteLang: settings.SiteLanguage,
|
|
CurrentSearchLang: settings.SearchLanguage,
|
|
Theme: settings.Theme,
|
|
Safe: settings.SafeSearch,
|
|
IsThemeDark: settings.IsThemeDark,
|
|
}
|
|
|
|
printDebug("Rendering settings with data: %+v", data)
|
|
|
|
tmpl, err := template.ParseFiles("templates/settings.html")
|
|
if err != nil {
|
|
printErr("Error parsing template: %s", err)
|
|
http.Error(w, "Internal Server Error", 500)
|
|
return
|
|
}
|
|
|
|
err = tmpl.Execute(w, data)
|
|
if err != nil {
|
|
printErr("Error executing template: %s", err)
|
|
http.Error(w, "Internal Server Error", 500)
|
|
return
|
|
}
|
|
}
|
|
|
|
// Helper function to normalize language codes
|
|
func normalizeLangCode(lang string) string {
|
|
lang = strings.ToLower(lang)
|
|
|
|
// First, check if the language code is already valid
|
|
if isValidLangCode(lang) {
|
|
return lang
|
|
}
|
|
|
|
// Strip regional codes (e.g., en-US -> en)
|
|
if strings.Contains(lang, "-") {
|
|
lang = strings.Split(lang, "-")[0]
|
|
}
|
|
|
|
// Re-check if the normalized version is valid
|
|
if isValidLangCode(lang) {
|
|
return lang
|
|
}
|
|
|
|
// If the language is not recognized, default to "en"
|
|
return "en"
|
|
}
|
|
|
|
// Helper function to check if a language code exists in the language options
|
|
func isValidLangCode(lang string) bool {
|
|
for _, opt := range languageOptions {
|
|
if opt.Code == lang {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|