Update.
This commit is contained in:
parent
987bd3a1c7
commit
92573ebeb4
src/snek
@ -176,7 +176,9 @@ class ChatInputComponent extends HTMLElement {
|
||||
});
|
||||
|
||||
this.appendChild(this.uploadButton);
|
||||
|
||||
this.textarea.addEventListener("blur", () => {
|
||||
this.updateFromInput("");
|
||||
});
|
||||
this.textarea.addEventListener("keyup", (e) => {
|
||||
if (e.key === "Enter" && !e.shiftKey) {
|
||||
|
||||
|
@ -17,15 +17,20 @@ export class Container extends EventHandler{
|
||||
this._container = el
|
||||
this.terminal.open(this._container)
|
||||
|
||||
this.terminal.onData(data => this.ws.send(new TextEncoder().encode(data)));
|
||||
|
||||
this.terminal.onData(data => {
|
||||
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
||||
this.ws.send(data);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
this._fitAddon.fit();
|
||||
this.refresh()
|
||||
|
||||
this.terminal.focus()
|
||||
}
|
||||
refresh(){
|
||||
this._fitAddon.fit();
|
||||
this.terminal.write("\x0C");
|
||||
//this._fitAddon.fit();
|
||||
this.ws.send("\x0C");
|
||||
}
|
||||
toggle(){
|
||||
this._container.classList.toggle("hidden")
|
||||
@ -34,7 +39,10 @@ export class Container extends EventHandler{
|
||||
|
||||
constructor(channelUid,log){
|
||||
super()
|
||||
this.terminal = new Terminal({ cursorBlink: true });
|
||||
this.terminal = new Terminal({ cursorBlink: true ,theme: {
|
||||
background: 'rgba(0, 0, 0, 0)', // Fully transparent
|
||||
}
|
||||
});
|
||||
this._fitAddon = new FitAddon.FitAddon();
|
||||
this.terminal.loadAddon(this._fitAddon);
|
||||
window.addEventListener("resize", () => this._fitAddon.fit());
|
||||
|
@ -3,6 +3,8 @@ import json
|
||||
import yaml
|
||||
import asyncio
|
||||
import subprocess
|
||||
import pty
|
||||
import os
|
||||
|
||||
class ComposeFileManager:
|
||||
def __init__(self, compose_path="docker-compose.yml",event_handler=None):
|
||||
@ -31,17 +33,19 @@ class ComposeFileManager:
|
||||
return False
|
||||
proc = self.running_instances.get(container_name)
|
||||
if not proc:
|
||||
return False
|
||||
return False
|
||||
|
||||
async def reader(event_handler,stream):
|
||||
loop = asyncio.get_event_loop()
|
||||
while True:
|
||||
line = await stream.read(1024)
|
||||
line = await loop.run_in_executor(None,os.read,stream,1024)
|
||||
print("XXX",line)
|
||||
if not line:
|
||||
break
|
||||
await event_handler(container_name,"stdout",line)
|
||||
await self.stop(container_name)
|
||||
asyncio.create_task(reader(self.event_handler,proc.stdout))
|
||||
asyncio.create_task(reader(self.event_handler,proc.stderr))
|
||||
asyncio.create_task(reader(self.event_handler,proc['master']))
|
||||
|
||||
|
||||
|
||||
def create_instance(
|
||||
@ -123,7 +127,7 @@ class ComposeFileManager:
|
||||
if not proc:
|
||||
return False
|
||||
try:
|
||||
proc.stdin.write(data.encode())
|
||||
os.write(proc['master'], data.encode())
|
||||
return True
|
||||
except Exception as ex:
|
||||
print(ex)
|
||||
@ -178,13 +182,16 @@ class ComposeFileManager:
|
||||
if proc.returncode != 0:
|
||||
print(f"Failed to start {name}: {stderr.decode(errors='ignore')}")
|
||||
return False
|
||||
|
||||
|
||||
master, slave = pty.openpty()
|
||||
proc = await asyncio.create_subprocess_exec(
|
||||
"docker", "compose", "-f", self.compose_path, "exec", name, "/bin/bash",
|
||||
stdin=asyncio.subprocess.PIPE,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
stdin=slave,
|
||||
stdout=slave,
|
||||
stderr=slave,
|
||||
)
|
||||
|
||||
proc = {'proc':proc,'master':master,'slave':slave}
|
||||
# stdin,stderr = await proc.communicate()
|
||||
self.running_instances[name] = proc
|
||||
#if stdout:
|
||||
|
@ -54,7 +54,28 @@
|
||||
<script type="module">
|
||||
import { app } from "/app.js";
|
||||
import { Container } from "/container.js";
|
||||
{% if channel %}
|
||||
let prevKey = null;
|
||||
document.addEventListener("keydown", () => {
|
||||
if(prevKey == "Escape"){
|
||||
document.querySelector("chat-input").querySelector("textarea").value = "";
|
||||
}
|
||||
if(prevKey == "Escape" && event.key == "t"){
|
||||
app.starField.shuffleAll(5000)
|
||||
|
||||
}
|
||||
|
||||
prevKey = event.key
|
||||
if(event.key == "," && event.ctrlKey){
|
||||
event.preventDefault();
|
||||
let textAreas = document.querySelectorAll("textarea")
|
||||
textAreas.forEach(textArea => {
|
||||
if(document.activeElement != textArea)
|
||||
setTimeout(() => textArea.focus(), 300)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
{% if channel %}
|
||||
app.channelUid = '{{ channel.uid.value }}'
|
||||
|
||||
window.getContainer = function(){
|
||||
|
@ -56,12 +56,13 @@ chatInputField.autoCompletions = {
|
||||
"/help": showHelp,
|
||||
"/container": async() =>{
|
||||
if(container == null){
|
||||
container = await window.getContainer()
|
||||
const terminal = document.querySelector("#terminal")
|
||||
terminal.classList.toggle("hidden")
|
||||
container.render(terminal)
|
||||
window.c = await window.getContainer()
|
||||
await window.c.start()
|
||||
window.t = document.querySelector("#terminal")
|
||||
window.t.classList.toggle("hidden")
|
||||
window.c.render(window.t)
|
||||
}
|
||||
containerDialog.openWithStatus()
|
||||
//containerDialog.openWithStatus()
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user