Added initial Settings

This commit is contained in:
Pablu23
2024-04-02 19:05:36 +02:00
parent c83a10823d
commit e45109fcd5
8 changed files with 148 additions and 11 deletions

View File

@@ -14,4 +14,10 @@ create table if not exists Chapter (
Number integer not null, Number integer not null,
TimeStampUnixEpoch integer not null, TimeStampUnixEpoch integer not null,
foreign key(MangaID) references Manga(ID) foreign key(MangaID) references Manga(ID)
);
create table if not exists Setting (
Name text not null primary key,
Value text,
DefaultValue text not null
); );

View File

@@ -11,6 +11,7 @@ type Manager struct {
db *sql.DB db *sql.DB
Mangas DbTable[int, Manga] Mangas DbTable[int, Manga]
Chapters DbTable[int, Chapter] Chapters DbTable[int, Chapter]
Settings DbTable[string, Setting]
CreateIfNotExists bool CreateIfNotExists bool
} }
@@ -18,8 +19,9 @@ func NewDatabase(connectionString string, createIfNotExists bool) Manager {
return Manager{ return Manager{
ConnectionString: connectionString, ConnectionString: connectionString,
db: nil, db: nil,
Mangas: NewDbTable[int, Manga](updateManga, insertManga, loadMangas, deleteManga), Mangas: NewDbTable(updateManga, insertManga, loadMangas, deleteManga),
Chapters: NewDbTable[int, Chapter](updateChapter, insertChapter, loadChapters, deleteChapter), Chapters: NewDbTable(updateChapter, insertChapter, loadChapters, deleteChapter),
Settings: NewDbTable(updateSetting, insertSetting, loadSettings, deleteSetting),
CreateIfNotExists: createIfNotExists, CreateIfNotExists: createIfNotExists,
} }
} }
@@ -75,8 +77,12 @@ func (dbMgr *Manager) Save() error {
if err != nil { if err != nil {
return err return err
} }
err = dbMgr.Chapters.Save(dbMgr.db)
if err != nil {
return err
}
return dbMgr.Chapters.Save(dbMgr.db) return dbMgr.Settings.Save(dbMgr.db)
} }
//go:embed createDb.sql //go:embed createDb.sql
@@ -98,5 +104,11 @@ func (dbMgr *Manager) load() error {
return err return err
} }
err = dbMgr.Settings.Load(dbMgr.db)
if err != nil {
return err
}
initSettings(&dbMgr.Settings)
return nil return nil
} }

View File

@@ -0,0 +1,65 @@
package database
import (
"database/sql"
)
type Setting struct {
Name string
Value string
Default string
}
func NewSetting(name string, defaultValue string) Setting {
return Setting{
Name: name,
Value: defaultValue,
Default: defaultValue,
}
}
func initSettings(settings *DbTable[string, Setting]) {
addSettingIfNotExists(NewSetting("theme", "white"), settings)
addSettingIfNotExists(NewSetting("order", "title"), settings)
}
func addSettingIfNotExists(setting Setting, settings *DbTable[string, Setting]) {
_, exists := settings.Get(setting.Name)
if !exists {
settings.Set(setting.Name, setting)
}
}
func updateSetting(db *sql.DB, s *Setting) error {
const cmd = "UPDATE Setting set Value = ? WHERE Name = ?"
_, err := db.Exec(cmd, s.Value, s.Name)
return err
}
func insertSetting(db *sql.DB, s *Setting) error {
const cmd = "INSERT INTO Setting(Name, Value, DefaultValue) VALUES(?, ?, ?)"
_, err := db.Exec(cmd, s.Name, s.Value, s.Default)
return err
}
func loadSettings(db *sql.DB) (map[string]Setting, error) {
const cmd = "SELECT Name, Value, DefaultValue from Setting"
rows, err := db.Query(cmd)
res := make(map[string]Setting)
for rows.Next() {
setting := Setting{}
if err = rows.Scan(&setting.Name, &setting.Value, &setting.Default); err != nil {
return nil, err
}
res[setting.Name] = setting
}
return res, err
}
func deleteSetting(db *sql.DB, key string) error {
const cmd = "UPDATE Setting set Value = DefaultValue WHERE Name = ?"
_, err := db.Exec(cmd, key)
return err
}

View File

@@ -88,6 +88,16 @@ func (d *DbTable[K, T]) All() []T {
return res return res
} }
func (d *DbTable[K, T]) Map() map[K]T {
d.mutex.Lock()
defer d.mutex.Unlock()
res := make(map[K]T, len(d.items))
for k, manga := range d.items {
res[k] = manga
}
return res
}
func (d *DbTable[K, T]) Delete(db *sql.DB, key K) error { func (d *DbTable[K, T]) Delete(db *sql.DB, key K) error {
d.mutex.Lock() d.mutex.Lock()
defer d.mutex.Unlock() defer d.mutex.Unlock()

View File

@@ -136,7 +136,8 @@ func (s *Server) HandleMenu(w http.ResponseWriter, r *http.Request) {
fmt.Printf("Sorting took %d ms\n", (nex-n)/1000000) fmt.Printf("Sorting took %d ms\n", (nex-n)/1000000)
menuViewModel := view.MenuViewModel{ menuViewModel := view.MenuViewModel{
Mangas: mangaViewModels, Settings: s.DbMgr.Settings.Map(),
Mangas: mangaViewModels,
} }
err := tmpl.Execute(w, menuViewModel) err := tmpl.Execute(w, menuViewModel)
@@ -336,6 +337,23 @@ func (s *Server) HandlePrev(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/current/", http.StatusTemporaryRedirect) http.Redirect(w, r, "/current/", http.StatusTemporaryRedirect)
} }
func (s *Server) HandleSetting(w http.ResponseWriter, r *http.Request) {
settingName := r.PostFormValue("setting")
settingValue := r.PostFormValue(settingName)
setting, ok := s.DbMgr.Settings.Get(settingName)
if !ok {
s.DbMgr.Settings.Set(settingName, database.NewSetting(settingName, settingValue))
} else {
if setting.Value != settingValue {
setting.Value = settingValue
s.DbMgr.Settings.Set(settingName, setting)
}
}
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
}
func (s *Server) HandleNewQuery(w http.ResponseWriter, r *http.Request) { func (s *Server) HandleNewQuery(w http.ResponseWriter, r *http.Request) {
sub := r.PostFormValue("subUrl") sub := r.PostFormValue("subUrl")

View File

@@ -58,6 +58,7 @@ func (s *Server) Start(port int) error {
http.HandleFunc("POST /exit", s.HandleExit) http.HandleFunc("POST /exit", s.HandleExit)
http.HandleFunc("POST /delete", s.HandleDelete) http.HandleFunc("POST /delete", s.HandleDelete)
http.HandleFunc("/favicon.ico", s.HandleFavicon) http.HandleFunc("/favicon.ico", s.HandleFavicon)
http.HandleFunc("POST /setting/", s.HandleSetting)
// Update Latest Chapter every 5 Minutes // Update Latest Chapter every 5 Minutes
go func(s *Server) { go func(s *Server) {

View File

@@ -12,7 +12,7 @@
font-size: 25px; font-size: 25px;
} }
.dark-mode { .dark {
background-color: #171717; background-color: #171717;
color: white; color: white;
} }
@@ -101,17 +101,31 @@
text-align: center; text-align: center;
} }
label {
display: flex;
align-content: center;
justify-content: center;
margin: 0 auto;
}
select {
width: 10em;
margin-bottom: 10px;
margin-top: 10px;
}
</style> </style>
<script> <script>
function myFunction() { function myFunction(theme) {
var element = document.body; if (theme !== "white") {
element.classList.toggle("dark-mode"); var element = document.body;
element.classList.toggle(theme);
}
} }
</script> </script>
</head> </head>
<body> <body onload="myFunction({{(index .Settings "theme").Value}})">
<form method="post" action="/new/"> <form method="post" action="/new/">
<label> <label>
New Sub Url New Sub Url
@@ -119,7 +133,15 @@
</label> </label>
<input type="submit" value="Open" class="button-36"> <input type="submit" value="Open" class="button-36">
</form> </form>
<button onclick="myFunction()">Toggle dark mode</button>
<form method="post" action="/setting/">
<label for="theme">Theme</label>
<select onchange="this.form.submit()" id="theme" name="theme">
<option value="white">White</option>
<option value="dark">Dark</option>
</select>
<input type="hidden" name="setting" value="theme">
</form>
<table class="table"> <table class="table">
<tr> <tr>

View File

@@ -1,5 +1,7 @@
package view package view
import "mangaGetter/internal/database"
type Image struct { type Image struct {
Path string Path string
Index int Index int
@@ -21,5 +23,6 @@ type MangaViewModel struct {
} }
type MenuViewModel struct { type MenuViewModel struct {
Mangas []MangaViewModel Settings map[string]database.Setting
Mangas []MangaViewModel
} }