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.appendChild(this.uploadButton);
|
||||||
|
this.textarea.addEventListener("blur", () => {
|
||||||
|
this.updateFromInput("");
|
||||||
|
});
|
||||||
this.textarea.addEventListener("keyup", (e) => {
|
this.textarea.addEventListener("keyup", (e) => {
|
||||||
if (e.key === "Enter" && !e.shiftKey) {
|
if (e.key === "Enter" && !e.shiftKey) {
|
||||||
|
|
||||||
|
@ -17,15 +17,20 @@ export class Container extends EventHandler{
|
|||||||
this._container = el
|
this._container = el
|
||||||
this.terminal.open(this._container)
|
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.refresh()
|
||||||
|
this.terminal.focus()
|
||||||
}
|
}
|
||||||
refresh(){
|
refresh(){
|
||||||
this._fitAddon.fit();
|
//this._fitAddon.fit();
|
||||||
this.terminal.write("\x0C");
|
this.ws.send("\x0C");
|
||||||
}
|
}
|
||||||
toggle(){
|
toggle(){
|
||||||
this._container.classList.toggle("hidden")
|
this._container.classList.toggle("hidden")
|
||||||
@ -34,7 +39,10 @@ export class Container extends EventHandler{
|
|||||||
|
|
||||||
constructor(channelUid,log){
|
constructor(channelUid,log){
|
||||||
super()
|
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._fitAddon = new FitAddon.FitAddon();
|
||||||
this.terminal.loadAddon(this._fitAddon);
|
this.terminal.loadAddon(this._fitAddon);
|
||||||
window.addEventListener("resize", () => this._fitAddon.fit());
|
window.addEventListener("resize", () => this._fitAddon.fit());
|
||||||
|
@ -3,6 +3,8 @@ import json
|
|||||||
import yaml
|
import yaml
|
||||||
import asyncio
|
import asyncio
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import pty
|
||||||
|
import os
|
||||||
|
|
||||||
class ComposeFileManager:
|
class ComposeFileManager:
|
||||||
def __init__(self, compose_path="docker-compose.yml",event_handler=None):
|
def __init__(self, compose_path="docker-compose.yml",event_handler=None):
|
||||||
@ -31,17 +33,19 @@ class ComposeFileManager:
|
|||||||
return False
|
return False
|
||||||
proc = self.running_instances.get(container_name)
|
proc = self.running_instances.get(container_name)
|
||||||
if not proc:
|
if not proc:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
async def reader(event_handler,stream):
|
async def reader(event_handler,stream):
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
while True:
|
while True:
|
||||||
line = await stream.read(1024)
|
line = await loop.run_in_executor(None,os.read,stream,1024)
|
||||||
print("XXX",line)
|
print("XXX",line)
|
||||||
if not line:
|
if not line:
|
||||||
break
|
break
|
||||||
await event_handler(container_name,"stdout",line)
|
await event_handler(container_name,"stdout",line)
|
||||||
await self.stop(container_name)
|
await self.stop(container_name)
|
||||||
asyncio.create_task(reader(self.event_handler,proc.stdout))
|
asyncio.create_task(reader(self.event_handler,proc['master']))
|
||||||
asyncio.create_task(reader(self.event_handler,proc.stderr))
|
|
||||||
|
|
||||||
|
|
||||||
def create_instance(
|
def create_instance(
|
||||||
@ -123,7 +127,7 @@ class ComposeFileManager:
|
|||||||
if not proc:
|
if not proc:
|
||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
proc.stdin.write(data.encode())
|
os.write(proc['master'], data.encode())
|
||||||
return True
|
return True
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
print(ex)
|
print(ex)
|
||||||
@ -178,13 +182,16 @@ class ComposeFileManager:
|
|||||||
if proc.returncode != 0:
|
if proc.returncode != 0:
|
||||||
print(f"Failed to start {name}: {stderr.decode(errors='ignore')}")
|
print(f"Failed to start {name}: {stderr.decode(errors='ignore')}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
master, slave = pty.openpty()
|
||||||
proc = await asyncio.create_subprocess_exec(
|
proc = await asyncio.create_subprocess_exec(
|
||||||
"docker", "compose", "-f", self.compose_path, "exec", name, "/bin/bash",
|
"docker", "compose", "-f", self.compose_path, "exec", name, "/bin/bash",
|
||||||
stdin=asyncio.subprocess.PIPE,
|
stdin=slave,
|
||||||
stdout=asyncio.subprocess.PIPE,
|
stdout=slave,
|
||||||
stderr=asyncio.subprocess.PIPE,
|
stderr=slave,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
proc = {'proc':proc,'master':master,'slave':slave}
|
||||||
# stdin,stderr = await proc.communicate()
|
# stdin,stderr = await proc.communicate()
|
||||||
self.running_instances[name] = proc
|
self.running_instances[name] = proc
|
||||||
#if stdout:
|
#if stdout:
|
||||||
|
@ -54,7 +54,28 @@
|
|||||||
<script type="module">
|
<script type="module">
|
||||||
import { app } from "/app.js";
|
import { app } from "/app.js";
|
||||||
import { Container } from "/container.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 }}'
|
app.channelUid = '{{ channel.uid.value }}'
|
||||||
|
|
||||||
window.getContainer = function(){
|
window.getContainer = function(){
|
||||||
|
@ -56,12 +56,13 @@ chatInputField.autoCompletions = {
|
|||||||
"/help": showHelp,
|
"/help": showHelp,
|
||||||
"/container": async() =>{
|
"/container": async() =>{
|
||||||
if(container == null){
|
if(container == null){
|
||||||
container = await window.getContainer()
|
window.c = await window.getContainer()
|
||||||
const terminal = document.querySelector("#terminal")
|
await window.c.start()
|
||||||
terminal.classList.toggle("hidden")
|
window.t = document.querySelector("#terminal")
|
||||||
container.render(terminal)
|
window.t.classList.toggle("hidden")
|
||||||
|
window.c.render(window.t)
|
||||||
}
|
}
|
||||||
containerDialog.openWithStatus()
|
//containerDialog.openWithStatus()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user