update
parent
3931d30181
commit
829e7637ca
|
@ -1,5 +1,5 @@
|
|||
dist
|
||||
node_modules
|
||||
.parcel-cache
|
||||
public/css/main.css*
|
||||
public/css/main.css.map
|
||||
public/js/main.js*
|
13
CHANGELOG.md
13
CHANGELOG.md
|
@ -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
|
||||
|
||||
|
|
4
Makefile
4
Makefile
|
@ -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
|
||||
|
||||
|
||||
|
|
5
app.go
5
app.go
|
@ -28,7 +28,10 @@ type Page struct {
|
|||
Error string
|
||||
File ActiveFile
|
||||
Editor Editor
|
||||
|
||||
Static bool
|
||||
HideConfig bool
|
||||
ResultBellow bool
|
||||
}
|
||||
|
||||
func (cui *ConfigUI) App(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -63,6 +66,8 @@ func (cui *ConfigUI) App(w http.ResponseWriter, r *http.Request) {
|
|||
Platform: plat,
|
||||
},
|
||||
Static: cui.NoReconfig,
|
||||
HideConfig: cui.HideConfig,
|
||||
ResultBellow: cui.ResultBellow,
|
||||
}
|
||||
|
||||
content := ""
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
10
configui.go
10
configui.go
|
@ -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",
|
||||
|
|
4
file.go
4
file.go
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -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(){
|
||||
|
||||
|
|
|
@ -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}}
|
|
@ -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}}
|
|
@ -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')
|
||||
|
|
|
@ -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}}
|
|
@ -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>
|
||||
</div>
|
||||
{{if not .ResultBellow}}
|
||||
{{template "components/result" .}}
|
||||
{{end}}
|
||||
{{template "base/footer" .}}
|
||||
{{end}}
|
Loading…
Reference in New Issue