pull/36/head
Evan 2021-10-23 12:55:05 +08:00
parent 3931d30181
commit 829e7637ca
15 changed files with 105 additions and 30 deletions

2
.gitignore vendored
View File

@ -1,5 +1,5 @@
dist
node_modules
.parcel-cache
public/css/main.css*
public/css/main.css.map
public/js/main.js*

View File

@ -4,13 +4,20 @@
* download files #26
* add goto last line toolbar #21
* use parcel to load main.js
* use icons
* bind ctrl-s (cmd-s) to fileSave
* refactor as lib #15
* Set Title to be changeable #24
* show run result below #33
* set font size #31
* Hide Config zone for other usage such as go playground #23
## Fix
* all cmds should be pass straight back to user
* timeout on none ending cmds #34
* all cmd output should be pass straight back to user
* timeout on none ending cmd #34
* add sys setting to conf #32
* Apply should save before taking action #19
# 0.1.1

View File

@ -23,10 +23,10 @@ run: build
.PHONY: web
web:
npm run build
npm run js-dev
# npm run js-dev
.PHONY: build
build: web
build:
go build ${LDFLAGS} -o dist/${PROJ} cmd/$(PROJ)/main.go

9
app.go
View File

@ -28,7 +28,10 @@ type Page struct {
Error string
File ActiveFile
Editor Editor
Static bool
Static bool
HideConfig bool
ResultBellow bool
}
func (cui *ConfigUI) App(w http.ResponseWriter, r *http.Request) {
@ -62,7 +65,9 @@ func (cui *ConfigUI) App(w http.ResponseWriter, r *http.Request) {
Editor: Editor{
Platform: plat,
},
Static: cui.NoReconfig,
Static: cui.NoReconfig,
HideConfig: cui.HideConfig,
ResultBellow: cui.ResultBellow,
}
content := ""

View File

@ -100,7 +100,7 @@ func main() {
// setup routes
server := &http.Server{
Addr: flagBind,
WriteTimeout: time.Second * 3,
WriteTimeout: time.Second * 30,
ReadTimeout: time.Second * 30,
Handler: cui,
}

View File

@ -48,7 +48,15 @@ type ConfigUI struct {
}
func New() *ConfigUI {
tmpl := template.Must(template.New("").ParseFS(tmplFS, "templates/*.tmpl", "templates/**/*.tmpl"))
tmpl := template.Must(template.New("").Funcs(template.FuncMap{
"step": func(from, to, step uint) []uint {
items := []uint{}
for i := from; i <= to; i += step {
items = append(items, i)
}
return items
},
}).ParseFS(tmplFS, "templates/*.tmpl", "templates/**/*.tmpl"))
return &ConfigUI{
fileIndex: map[string]int{},
AppName: "ConfigUI",

View File

@ -75,12 +75,12 @@ func (f *File) Do() (string, error) {
done <- string(out)
}()
select {
case <-time.After(5 * time.Second):
case <-time.After(10 * time.Second):
cmd.Process.Kill()
log.Println("timeout")
return "", errors.New("command timeout")
case out := <-done:
log.Println("\n", out)
log.Printf("\n%v", out)
return out, nil
}
}

View File

1
public/css/main.css Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,7 @@
{{define "base/script"}}
<script>
window.ToolIsFollow = false;
window.ContentChanged = false;
async function FileGet(follower=false){
let f = ''
@ -37,7 +38,10 @@ async function FileSave(){
'Content-Type': 'application/json'
})
}).catch(err=>{console.log(err);return;});
if (res.ok) window.location.reload();
if (res.ok) {
window.location.reload();
window.ContentChanged = false
}
else Catch(res)
}
else {
@ -49,6 +53,7 @@ async function FileSave(){
})
}).catch(err=>{console.log(err);return;});
if(!res.ok) Catch(res)
else window.ContentChanged = false
}
}
@ -71,13 +76,25 @@ async function FileApply(){
}
async function Catch(res){
console.trace()
console.log(res)
{{/* console.trace()
console.log(res) */}}
const msg = await res.text()
ShowError(msg)
return msg
}
function setResult(){
var result_editor = ace.edit("result_editor");
window.result_editor = result_editor
result_editor.setTheme("ace/theme/monokai");
result_editor.session.setMode("ace/mode/sh");
result_editor.setReadOnly(true);
result_editor.setOptions({
maxLines: 1000
});
}
// starting point
(function(){

View File

@ -15,6 +15,21 @@ function setEditor(){
editor.session.setUseWrapMode(false);
editor.session.setNewLineMode('{{.Editor.Platform}}')
editor.setReadOnly({{.File.RO}});
editor.session.on('change', function(delta) {
// delta.start, delta.end, delta.lines, delta.action
window.ContentChanged = true
});
editor.commands.addCommand({
name: 'SaveContent',
bindKey: {win: 'Ctrl-S', mac: 'Command-S'},
exec: function(editor) {
//...
FileSave()
},
readOnly: false // false if this command should not apply in readOnly mode
});
}
</script>
{{end}}

View File

@ -14,6 +14,7 @@
</li>
{{ end }}
</ul>
{{if not .HideConfig}}
<p class="menu-label">
System
</p>
@ -24,6 +25,7 @@
href="/"
>Config</a></li>
</ul>
{{end}}
</aside>
</section>
{{end}}

View File

@ -23,17 +23,6 @@
</div>
<script>
function setResult(){
var result_editor = ace.edit("result_editor");
window.result_editor = result_editor
result_editor.setTheme("ace/theme/monokai");
result_editor.session.setMode("ace/mode/sh");
result_editor.setReadOnly(true);
result_editor.setOptions({
maxLines: 1000
});
}
function ResultViewTog(){
let el = document.getElementById('result_view')
el.classList.toggle('is-active')

View File

@ -47,6 +47,16 @@
</select>
</div>
</p>
<p class="control">
<div class="select is-small">
<select onchange="toolSetFontSize(this)">
<option value="1rem">1rem</option>
{{range step 8 36 2}}
<option value="{{.}}px">{{.}}px</option>
{{end}}
</select>
</div>
</p>
</div>
</div>
@ -63,12 +73,14 @@
{{if not .File.RO}}
<p class="control">
{{if eq .File.Name .AppName}}
{{if not .Static}}
<button class="button is-small has-tooltip-arrow"
data-tooltip="Apply" onclick="toolSave()">
<span class="icon is-small"><span class="material-icons" id="toolSaveIco">
play_arrow
</span></span>
</button>
{{end}}
{{else}}
<button class="button is-small has-tooltip-arrow"
data-tooltip="Save" onclick="toolSave()">
@ -91,7 +103,6 @@
</p>
{{end}}
{{/* TEST */}}
<p class="control">
<a class="button is-small has-tooltip-arrow" data-tooltip="Download"
href="/api/export?name={{.File.Name}}">
@ -145,6 +156,12 @@ function toolFormat(){
beautify.beautify(editor.session);
}
function toolSetFontSize(obj){
let value = obj.value;
document.getElementById('editor').style.fontSize=value;
document.getElementById('result_editor').style.fontSize=value;
}
function toolFollow(){
if (ToolIsFollow){
ToolIsFollow = false
@ -184,12 +201,15 @@ async function toolSave(){
async function toolApply(){
let el = document.getElementById('toolApplyIco');
let originText = el.innerText;
el.innerText='refreash';
el.innerText='rotate_right';
el.classList.add("icn-loading")
FileApply()
if (window.ContentChanged){
await FileSave()
}
await FileApply()
el.innerText=originText;
el.classList.remove("icn-loading")
ResultViewTog()
{{if not .ResultBellow}}ResultViewTog(){{end}}
}
</script>
{{end}}

View File

@ -24,10 +24,21 @@ var Active = "{{.File.Name}}";
</div>
<div class="column">
<div class="box">
{{if and .HideConfig (eq .File.Name .AppName)}}
Home
{{else}}
{{template "components/editor" .}}
{{end}}
</div>
{{if .ResultBellow}}
<div class="box">
<div id="result_editor"></div>
</div>
{{end}}
</div>
</div>
{{if not .ResultBellow}}
{{template "components/result" .}}
{{end}}
{{template "base/footer" .}}
{{end}}