func serverEULA(s data.Server, d string) func(dom.Element) { return func(c dom.Element) { t := xform.TextArea("eula", d) submit := xform.InputSubmit("Save") c.AppendChild(xjs.AppendChildren(xdom.Form(), xjs.AppendChildren(xdom.Fieldset(), xjs.SetInnerText(xdom.Legend(), "End User License Agreement"), xform.Label("EULA", "eula"), t, xdom.Br(), submit, ))) submit.AddEventListener("click", false, func(e dom.Event) { e.PreventDefault() submit.Disabled = true go func() { err := RPC.SetServerEULA(s.ID, t.Value) if err != nil { xjs.Alert("Error setting server EULA: %s", err) return } d = t.Value span := xdom.Span() span.Style().Set("color", "#f00") c.AppendChild(xjs.SetInnerText(span, "Saved!")) time.Sleep(5 * time.Second) c.RemoveChild(span) submit.Disabled = false }() }) } }
func settingsTab(c dom.Element) { s, err := RPC.Settings() if err != nil { xjs.Alert("Error reading settings: %s", err) return } sn := xform.InputText("serverName", s.ServerName) sn.Required = true la := xform.InputText("listenAddr", s.ListenAddr) la.Required = true sp := xform.InputText("serversPath", s.DirServers) sp.Required = true mp := xform.InputText("mapsPath", s.DirMaps) mp.Required = true gp := xform.InputText("gensPath", s.DirGenerators) gp.Required = true ge := xform.InputText("genExe", s.GeneratorExecutable) ge.Required = true mm := xform.InputNumber("maxMem", 100, 10000, float64(s.GeneratorMaxMem/1024/1024)) mm.Required = true sb := xform.InputSubmit("Save") sb.AddEventListener("click", false, func(e dom.Event) { if sn.Value == "" || la.Value == "" || sp.Value == "" || mp.Value == "" || gp.Value == "" || ge.Value == "" || !mm.CheckValidity() { return } e.PreventDefault() sb.Disabled = true go func() { s.ServerName = sn.Value s.ListenAddr = la.Value s.DirServers = sp.Value s.DirMaps = mp.Value s.DirGenerators = gp.Value s.GeneratorExecutable = ge.Value s.GeneratorMaxMem = uint64(mm.ValueAsNumber * 1024 * 1024) if err := RPC.SetSettings(s); err != nil { xjs.Alert("Error saving settings: %s", err) return } SetTitle(sn.Value) span := xdom.Span() span.Style().Set("color", "#f00") c.AppendChild(xjs.SetInnerText(span, "Saved!")) time.Sleep(5 * time.Second) c.RemoveChild(span) sb.Disabled = false }() }) xjs.AppendChildren(c, xjs.AppendChildren(xdom.Form(), xjs.AppendChildren(xdom.Fieldset(), xjs.SetInnerText(xdom.Legend(), "Change Settings"), xform.Label("Server Name", "serverName"), sn, xdom.Br(), xform.Label("Listen Address", "listenAddr"), la, xdom.Br(), xform.Label("Servers Path", "serversPath"), sp, xdom.Br(), xform.Label("Maps Path", "mapsPath"), mp, xdom.Br(), xform.Label("Generators Path", "gensPath"), gp, xdom.Br(), xform.Label("Generator Executable", "genExe"), ge, xdom.Br(), xform.Label("Generator Memory (MB)", "maxMem"), mm, xdom.Br(), sb, ))) }
func rangeWatch(r *dom.HTMLInputElement) dom.Element { s := xdom.Span() xjs.SetInnerText(s, r.Value) r.AddEventListener("input", false, func(dom.Event) { xjs.SetInnerText(s, r.Value) }) return s }
// InputSizeable returns a content-editable span that is style to look a text // input box func InputSizeable(id, value string) *dom.HTMLSpanElement { s := xdom.Span() s.Class().SetString("sizeableInput") s.SetContentEditable("true") s.Set("spellcheck", "false") if id != "" { s.SetID(id) } s.Underlying().Call("appendChild", js.Global.Get("document").Call("createTextNode", value)) return s }
func editProperties(c dom.Element, name string, id int, rpcGet func(int) (map[string]string, error), rpcSet func(id int, properties map[string]string) error) { sp, err := rpcGet(id) if err != nil { c.AppendChild(xjs.SetInnerText(xdom.Div(), "Failed to get properties: "+err.Error())) return } props := make(PropertyList, 0, len(sp)) for k, v := range sp { props = append(props, [2]string{k, v}) } sort.Sort(props) propE := make([][2]*dom.HTMLSpanElement, len(props)) df := xjs.DocumentFragment() toggleFunc := func(k, v *dom.HTMLSpanElement, toggle *dom.HTMLInputElement) func(dom.Event) { return func(dom.Event) { if toggle.Value == "-" { k.SetContentEditable("false") v.SetContentEditable("false") k.Style().SetProperty("background-color", "#888", "") v.Style().SetProperty("background-color", "#888", "") toggle.Value = "+" } else { k.SetContentEditable("true") v.SetContentEditable("true") k.Style().RemoveProperty("background-color") v.Style().RemoveProperty("background-color") toggle.Value = "-" } } } for i, prop := range props { k := xform.InputSizeable("", prop[0]) v := xform.InputSizeable("", prop[1]) toggle := xform.InputButton("", "-") toggle.AddEventListener("click", false, toggleFunc(k, v, toggle)) propE[i][0] = k propE[i][1] = v xjs.AppendChildren(df, toggle, k, xjs.SetInnerText(xdom.Span(), "="), v, xdom.Br(), ) } add := xform.InputButton("", "Add") submit := xform.InputButton("", "Save") fs := xjs.AppendChildren(xdom.Fieldset(), xjs.SetInnerText(xdom.Legend(), name+" Properties"), df, add, submit, ) add.AddEventListener("click", false, func(dom.Event) { k := xform.InputSizeable("", "") v := xform.InputSizeable("", "") toggle := xform.InputButton("", "-") toggle.AddEventListener("click", false, toggleFunc(k, v, toggle)) propE = append(propE, [2]*dom.HTMLSpanElement{k, v}) fs.InsertBefore(toggle, add) fs.InsertBefore(k, add) fs.InsertBefore(xjs.SetInnerText(xdom.Span(), "="), add) fs.InsertBefore(v, add) fs.InsertBefore(xdom.Br(), add) }) submit.AddEventListener("click", false, func(dom.Event) { submit.Disabled = true props := make(map[string]string, len(propE)) for _, spans := range propE { if spans[0].IsContentEditable() { props[spans[0].TextContent()] = spans[1].TextContent() } } go func() { err := rpcSet(id, props) if err != nil { xjs.Alert("Error setting "+name+" properties: %s", err) return } span := xdom.Span() span.Style().Set("color", "#f00") fs.AppendChild(xjs.SetInnerText(span, "Saved!")) time.Sleep(5 * time.Second) fs.RemoveChild(span) submit.Disabled = false }() }) xjs.AppendChildren(c, xjs.AppendChildren(xdom.Form(), fs)) }
func serverGeneral(s data.Server) func(dom.Element) { return func(c dom.Element) { go func() { maps, err := RPC.MapList() if err != nil { c.AppendChild(xjs.SetInnerText(xdom.Div(), "Error getting map list: "+err.Error())) return } name := xform.InputText("name", s.Name) name.Required = true opts := make([]xform.Option, 1, len(maps)+1) opts[0] = xform.Option{ Label: "-- None -- ", Value: "-1", Selected: s.Map == -1, } for i, m := range maps { n := m.Name if m.Server != -1 { if m.ID == s.Map { n = "* - " + n } else { n = "! - " + n } } else { n = " " + n } opts = append(opts, xform.Option{ Label: n, Value: strconv.Itoa(i), Selected: m.ID == s.Map, }) } args := xform.InputSizeableList(s.Args...) sel := xform.SelectBox("map", opts...) submit := xform.InputSubmit("Set") submit.AddEventListener("click", false, func(e dom.Event) { if s.State != data.StateStopped { xjs.Alert("Cannot modify these settings while the server is running") return } if name.Value == "" { return } sID, err := strconv.Atoi(sel.Value) if err != nil || sID < -1 || sID >= len(maps) { return } submit.Disabled = true e.PreventDefault() if sID >= 0 { m := maps[sID] sID = m.ID } go func() { err = RPC.SetServerMap(s.ID, sID) if err != nil { xjs.Alert("Error setting server map: %s", err) return } s.Name = name.Value s.Args = args.Values() err = RPC.SetServer(s) if err != nil { xjs.Alert("Error setting server data: %s", err) return } span := xdom.Span() span.Style().Set("color", "#f00") c.AppendChild(xjs.SetInnerText(span, "Saved!")) time.Sleep(5 * time.Second) c.RemoveChild(span) submit.Disabled = false }() }) xjs.AppendChildren(c, xjs.AppendChildren(xdom.Form(), xform.Label("Server Name", "name"), name, xdom.Br(), xform.Label("Arguments", "args"), args, xdom.Br(), xform.Label("Map Name", "map"), sel, xdom.Br(), submit, )) }() } }
func mapGeneral(m data.Map) func(dom.Element) { return func(c dom.Element) { go func() { servers, err := RPC.ServerList() if err != nil { c.AppendChild(xjs.SetInnerText(xdom.Div(), "Error getting server list: "+err.Error())) return } name := xform.InputText("name", m.Name) name.Required = true opts := make([]xform.Option, 1, len(servers)+1) opts[0] = xform.Option{ Label: "-- None --", Value: "-1", Selected: m.Server == -1, } var cs data.Server for i, s := range servers { n := s.Name if s.Map != -1 { if s.ID == m.Server { cs = s n = "* - " + n } else { n = "! - " + n } } else { n = " " + n } opts = append(opts, xform.Option{ Label: n, Value: strconv.Itoa(i), Selected: s.ID == m.Server, }) } sel := xform.SelectBox("server", opts...) submit := xform.InputSubmit("Set") submit.AddEventListener("click", false, func(e dom.Event) { if cs.State != data.StateStopped { xjs.Alert("Cannot modify these settings while connected server is running.") return } if name.Value == "" { return } mID, err := strconv.Atoi(sel.Value) if err != nil || mID < -1 || mID >= len(servers) { return } submit.Disabled = true e.PreventDefault() if mID >= 0 { s := servers[mID] mID = s.ID } go func() { err = RPC.SetServerMap(mID, m.ID) if err != nil { xjs.Alert("Error setting map server: %s", err) return } m.Name = name.Value err = RPC.SetMap(m) if err != nil { xjs.Alert("Error setting map data: %s", err) return } span := xdom.Span() span.Style().Set("color", "#f00") c.AppendChild(xjs.SetInnerText(span, "Saved!")) time.Sleep(5 * time.Second) c.RemoveChild(span) submit.Disabled = false }() }) xjs.AppendChildren(c, xjs.AppendChildren(xdom.Form(), xform.Label("Server Name", "name"), name, xdom.Br(), xform.Label("Server Name", "server"), sel, xdom.Br(), submit, )) }() } }