Add history calendar export view
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"vrc_osc_go/internal/common"
|
||||
)
|
||||
@@ -32,14 +33,20 @@ type VrcLogConfig struct {
|
||||
}
|
||||
|
||||
type GUIConfig struct {
|
||||
TopMost bool
|
||||
FontSize int
|
||||
TopMost bool
|
||||
FontSize int
|
||||
AutoUnmuteOnSelfLeave bool
|
||||
RefreshIntervalValue int
|
||||
RefreshIntervalUnit string
|
||||
HistoryRegex string
|
||||
HistoryFromDate string
|
||||
HistoryToDate string
|
||||
}
|
||||
|
||||
func Load(path string) (*Config, error) {
|
||||
cfg := &Config{
|
||||
OSC: OSCConfig{Host: "127.0.0.1", Port: 9001},
|
||||
GUI: GUIConfig{FontSize: 18},
|
||||
GUI: GUIConfig{FontSize: 18, RefreshIntervalValue: 2, RefreshIntervalUnit: "sec"},
|
||||
}
|
||||
if path == "" {
|
||||
path = filepath.Join(common.RootDir(), "config", "config.toml")
|
||||
@@ -114,9 +121,29 @@ func Load(path string) (*Config, error) {
|
||||
if n, err := strconv.Atoi(val); err == nil && n > 0 {
|
||||
cfg.GUI.FontSize = n
|
||||
}
|
||||
case "auto_unmute_on_self_leave":
|
||||
cfg.GUI.AutoUnmuteOnSelfLeave = parseBool(val, cfg.GUI.AutoUnmuteOnSelfLeave)
|
||||
case "refresh_interval_value":
|
||||
if n, err := strconv.Atoi(val); err == nil && n > 0 {
|
||||
cfg.GUI.RefreshIntervalValue = n
|
||||
}
|
||||
case "refresh_interval_unit":
|
||||
cfg.GUI.RefreshIntervalUnit = normalizeRefreshIntervalUnit(val)
|
||||
case "history_regex":
|
||||
cfg.GUI.HistoryRegex = val
|
||||
case "history_from":
|
||||
cfg.GUI.HistoryFromDate = normalizeHistoryDate(val)
|
||||
case "history_to":
|
||||
cfg.GUI.HistoryToDate = normalizeHistoryDate(val)
|
||||
}
|
||||
}
|
||||
}
|
||||
if cfg.GUI.RefreshIntervalValue <= 0 {
|
||||
cfg.GUI.RefreshIntervalValue = 2
|
||||
}
|
||||
cfg.GUI.RefreshIntervalUnit = normalizeRefreshIntervalUnit(cfg.GUI.RefreshIntervalUnit)
|
||||
cfg.GUI.HistoryFromDate = normalizeHistoryDate(cfg.GUI.HistoryFromDate)
|
||||
cfg.GUI.HistoryToDate = normalizeHistoryDate(cfg.GUI.HistoryToDate)
|
||||
if cfg.VrcLog.GuestFile != "" {
|
||||
if !filepath.IsAbs(cfg.VrcLog.GuestFile) {
|
||||
cfg.VrcLog.GuestFile = filepath.Join(common.RootDir(), cfg.VrcLog.GuestFile)
|
||||
@@ -222,13 +249,56 @@ func upsertGUISection(existing string, gui GUIConfig) string {
|
||||
}
|
||||
|
||||
func appendGUISection(out *[]string, gui GUIConfig) {
|
||||
gui.RefreshIntervalUnit = normalizeRefreshIntervalUnit(gui.RefreshIntervalUnit)
|
||||
if gui.RefreshIntervalValue <= 0 {
|
||||
gui.RefreshIntervalValue = 2
|
||||
}
|
||||
*out = append(*out,
|
||||
"[gui]",
|
||||
fmt.Sprintf("top_most = %t", gui.TopMost),
|
||||
fmt.Sprintf("font_size = %d", gui.FontSize),
|
||||
fmt.Sprintf("auto_unmute_on_self_leave = %t", gui.AutoUnmuteOnSelfLeave),
|
||||
fmt.Sprintf("refresh_interval_value = %d", gui.RefreshIntervalValue),
|
||||
fmt.Sprintf("refresh_interval_unit = %q", gui.RefreshIntervalUnit),
|
||||
fmt.Sprintf("history_regex = %q", gui.HistoryRegex),
|
||||
fmt.Sprintf("history_from = %q", gui.HistoryFromDate),
|
||||
fmt.Sprintf("history_to = %q", gui.HistoryToDate),
|
||||
)
|
||||
}
|
||||
|
||||
func normalizeRefreshIntervalUnit(unit string) string {
|
||||
switch strings.ToLower(strings.TrimSpace(unit)) {
|
||||
case "min", "minute", "minutes":
|
||||
return "min"
|
||||
default:
|
||||
return "sec"
|
||||
}
|
||||
}
|
||||
|
||||
func (g GUIConfig) RefreshInterval() time.Duration {
|
||||
value := g.RefreshIntervalValue
|
||||
if value <= 0 {
|
||||
value = 2
|
||||
}
|
||||
switch normalizeRefreshIntervalUnit(g.RefreshIntervalUnit) {
|
||||
case "min":
|
||||
return time.Duration(value) * time.Minute
|
||||
default:
|
||||
return time.Duration(value) * time.Second
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeHistoryDate(value string) string {
|
||||
value = strings.TrimSpace(value)
|
||||
if value == "" {
|
||||
return ""
|
||||
}
|
||||
if _, err := time.Parse("2006-01-02", value); err != nil {
|
||||
return ""
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
func loadLines(path string) ([]string, error) {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
|
||||
@@ -35,14 +35,14 @@ func TestLoadOSCValues(t *testing.T) {
|
||||
func TestLoadGUIValues(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "config.toml")
|
||||
if err := os.WriteFile(path, []byte("[gui]\ntop_most = true\nfont_size = 24\n"), 0o600); err != nil {
|
||||
if err := os.WriteFile(path, []byte("[gui]\ntop_most = true\nfont_size = 24\nauto_unmute_on_self_leave = true\nrefresh_interval_value = 5\nrefresh_interval_unit = \"min\"\nhistory_regex = \"[wip]\"\nhistory_from = \"2026-01-01\"\nhistory_to = \"2026-01-31\"\n"), 0o600); err != nil {
|
||||
t.Fatalf("WriteFile: %v", err)
|
||||
}
|
||||
cfg, err := Load(path)
|
||||
if err != nil {
|
||||
t.Fatalf("Load returned error: %v", err)
|
||||
}
|
||||
if cfg.GUI.TopMost != true || cfg.GUI.FontSize != 24 {
|
||||
if cfg.GUI.TopMost != true || cfg.GUI.FontSize != 24 || cfg.GUI.AutoUnmuteOnSelfLeave != true || cfg.GUI.RefreshIntervalValue != 5 || cfg.GUI.RefreshIntervalUnit != "min" || cfg.GUI.HistoryRegex != "[wip]" || cfg.GUI.HistoryFromDate != "2026-01-01" || cfg.GUI.HistoryToDate != "2026-01-31" {
|
||||
t.Fatalf("unexpected gui values: %+v", cfg.GUI)
|
||||
}
|
||||
}
|
||||
@@ -54,14 +54,14 @@ func TestSaveGUIUpdatesSection(t *testing.T) {
|
||||
if err := os.WriteFile(path, initial, 0o600); err != nil {
|
||||
t.Fatalf("WriteFile: %v", err)
|
||||
}
|
||||
if err := SaveGUI(path, GUIConfig{TopMost: true, FontSize: 26}); err != nil {
|
||||
if err := SaveGUI(path, GUIConfig{TopMost: true, FontSize: 26, AutoUnmuteOnSelfLeave: true, RefreshIntervalValue: 3, RefreshIntervalUnit: "sec", HistoryRegex: "[wip]", HistoryFromDate: "2026-01-01", HistoryToDate: "2026-01-31"}); err != nil {
|
||||
t.Fatalf("SaveGUI returned error: %v", err)
|
||||
}
|
||||
cfg, err := Load(path)
|
||||
if err != nil {
|
||||
t.Fatalf("Load returned error: %v", err)
|
||||
}
|
||||
if cfg.GUI.TopMost != true || cfg.GUI.FontSize != 26 {
|
||||
if cfg.GUI.TopMost != true || cfg.GUI.FontSize != 26 || cfg.GUI.AutoUnmuteOnSelfLeave != true || cfg.GUI.RefreshIntervalValue != 3 || cfg.GUI.RefreshIntervalUnit != "sec" || cfg.GUI.HistoryRegex != "[wip]" || cfg.GUI.HistoryFromDate != "2026-01-01" || cfg.GUI.HistoryToDate != "2026-01-31" {
|
||||
t.Fatalf("unexpected saved gui values: %+v", cfg.GUI)
|
||||
}
|
||||
data, err := os.ReadFile(path)
|
||||
|
||||
Reference in New Issue
Block a user