mirror of
https://github.com/asciinema/asciinema.git
synced 2025-12-15 19:28:00 +01:00
Refactor metadata (header) handling
This commit is contained in:
@@ -38,6 +38,21 @@ pub enum EventData {
|
||||
Other(char, String),
|
||||
}
|
||||
|
||||
impl Default for Header {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
cols: 80,
|
||||
rows: 24,
|
||||
timestamp: None,
|
||||
idle_time_limit: None,
|
||||
command: None,
|
||||
title: None,
|
||||
env: None,
|
||||
theme: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn open_from_path<S: AsRef<Path>>(path: S) -> Result<Asciicast<'static>> {
|
||||
fs::File::open(path)
|
||||
.map(io::BufReader::new)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::Command;
|
||||
use crate::asciicast::{self, Header};
|
||||
use crate::asciicast;
|
||||
use crate::cli::{self, Format};
|
||||
use crate::config::Config;
|
||||
use crate::encoder::{self, AsciicastEncoder, EncoderExt, RawEncoder, TextEncoder};
|
||||
@@ -12,7 +12,7 @@ impl Command for cli::Convert {
|
||||
fn run(self, _config: &Config) -> Result<()> {
|
||||
let path = util::get_local_path(&self.input_filename)?;
|
||||
let cast = asciicast::open_from_path(&*path)?;
|
||||
let mut encoder = self.get_encoder(&cast.header);
|
||||
let mut encoder = self.get_encoder();
|
||||
let mut file = self.open_file()?;
|
||||
|
||||
encoder.encode_to_file(cast, &mut file)
|
||||
@@ -20,7 +20,7 @@ impl Command for cli::Convert {
|
||||
}
|
||||
|
||||
impl cli::Convert {
|
||||
fn get_encoder(&self, header: &Header) -> Box<dyn encoder::Encoder> {
|
||||
fn get_encoder(&self) -> Box<dyn encoder::Encoder> {
|
||||
let format = self.format.unwrap_or_else(|| {
|
||||
if self.output_filename.to_lowercase().ends_with(".txt") {
|
||||
Format::Txt
|
||||
@@ -30,7 +30,7 @@ impl cli::Convert {
|
||||
});
|
||||
|
||||
match format {
|
||||
Format::Asciicast => Box::new(AsciicastEncoder::new(false, 0, header.into())),
|
||||
Format::Asciicast => Box::new(AsciicastEncoder::new(false, 0)),
|
||||
Format::Raw => Box::new(RawEncoder::new(false)),
|
||||
Format::Txt => Box::new(TextEncoder::new()),
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
use super::Command;
|
||||
use crate::asciicast;
|
||||
use crate::asciicast::Header;
|
||||
use crate::cli;
|
||||
use crate::config::Config;
|
||||
use crate::encoder::{AsciicastEncoder, Encoder, Metadata, RawEncoder, TextEncoder};
|
||||
use crate::encoder::{AsciicastEncoder, Encoder, RawEncoder, TextEncoder};
|
||||
use crate::locale;
|
||||
use crate::logger;
|
||||
use crate::pty;
|
||||
use crate::recorder::Output;
|
||||
use crate::recorder::{self, KeyBindings};
|
||||
use crate::tty::{self, FixedSizeTty, Tty};
|
||||
use crate::tty::{self, FixedSizeTty};
|
||||
use anyhow::{bail, Result};
|
||||
use cli::Format;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
@@ -34,6 +35,7 @@ impl Command for cli::Record {
|
||||
let record_input = self.input || config.cmd_rec_input();
|
||||
let exec_command = super::build_exec_command(command.as_ref().cloned());
|
||||
let exec_extra_env = super::build_exec_extra_env(&[]);
|
||||
let output = self.get_output(file, format, append, time_offset, config);
|
||||
|
||||
logger::info!("Recording session started, writing to {}", self.path);
|
||||
|
||||
@@ -43,8 +45,6 @@ impl Command for cli::Record {
|
||||
|
||||
{
|
||||
let mut tty = self.get_tty()?;
|
||||
let theme = tty.get_theme();
|
||||
let output = self.get_output(file, format, append, time_offset, theme, config);
|
||||
let mut recorder = recorder::Recorder::new(output, record_input, keys, notifier);
|
||||
pty::exec(&exec_command, &exec_extra_env, &mut tty, &mut recorder)?;
|
||||
}
|
||||
@@ -170,20 +170,33 @@ impl cli::Record {
|
||||
format: Format,
|
||||
append: bool,
|
||||
time_offset: u64,
|
||||
theme: Option<tty::Theme>,
|
||||
config: &Config,
|
||||
) -> Box<dyn recorder::Output + Send> {
|
||||
let metadata = self.build_asciicast_metadata(config);
|
||||
|
||||
match format {
|
||||
Format::Asciicast => {
|
||||
let metadata = self.build_asciicast_metadata(theme, config);
|
||||
let file = io::LineWriter::new(file);
|
||||
let encoder = AsciicastEncoder::new(append, time_offset, metadata);
|
||||
let writer = io::LineWriter::new(file);
|
||||
let encoder = AsciicastEncoder::new(append, time_offset);
|
||||
|
||||
Box::new(FileOutput(file, encoder))
|
||||
Box::new(FileOutput {
|
||||
writer,
|
||||
encoder,
|
||||
metadata,
|
||||
})
|
||||
}
|
||||
|
||||
Format::Raw => Box::new(FileOutput(file, RawEncoder::new(append))),
|
||||
Format::Txt => Box::new(FileOutput(file, TextEncoder::new())),
|
||||
Format::Raw => Box::new(FileOutput {
|
||||
writer: file,
|
||||
encoder: RawEncoder::new(append),
|
||||
metadata,
|
||||
}),
|
||||
|
||||
Format::Txt => Box::new(FileOutput {
|
||||
writer: file,
|
||||
encoder: TextEncoder::new(),
|
||||
metadata,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,7 +204,7 @@ impl cli::Record {
|
||||
self.command.as_ref().cloned().or(config.cmd_rec_command())
|
||||
}
|
||||
|
||||
fn build_asciicast_metadata(&self, theme: Option<tty::Theme>, config: &Config) -> Metadata {
|
||||
fn build_asciicast_metadata(&self, config: &Config) -> Metadata {
|
||||
let idle_time_limit = self.idle_time_limit.or(config.cmd_rec_idle_time_limit());
|
||||
let command = self.get_command(config);
|
||||
|
||||
@@ -207,25 +220,52 @@ impl cli::Record {
|
||||
command,
|
||||
title: self.title.clone(),
|
||||
env: Some(capture_env(&env)),
|
||||
theme,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct FileOutput<W: Write, E: Encoder>(W, E);
|
||||
struct FileOutput<W: Write, E: Encoder> {
|
||||
writer: W,
|
||||
encoder: E,
|
||||
metadata: Metadata,
|
||||
}
|
||||
|
||||
pub struct Metadata {
|
||||
pub idle_time_limit: Option<f64>,
|
||||
pub command: Option<String>,
|
||||
pub title: Option<String>,
|
||||
pub env: Option<HashMap<String, String>>,
|
||||
}
|
||||
|
||||
impl<W: Write, E: Encoder> Output for FileOutput<W, E> {
|
||||
fn header(&mut self, time: SystemTime, tty_size: tty::TtySize) -> io::Result<()> {
|
||||
fn header(
|
||||
&mut self,
|
||||
time: SystemTime,
|
||||
tty_size: tty::TtySize,
|
||||
theme: Option<tty::Theme>,
|
||||
) -> io::Result<()> {
|
||||
let timestamp = time.duration_since(UNIX_EPOCH).unwrap().as_secs();
|
||||
self.0.write_all(&self.1.start(Some(timestamp), tty_size))
|
||||
|
||||
let header = Header {
|
||||
cols: tty_size.0,
|
||||
rows: tty_size.1,
|
||||
timestamp: Some(timestamp),
|
||||
theme,
|
||||
idle_time_limit: self.metadata.idle_time_limit,
|
||||
command: self.metadata.command.as_ref().cloned(),
|
||||
title: self.metadata.title.as_ref().cloned(),
|
||||
env: self.metadata.env.as_ref().cloned(),
|
||||
};
|
||||
|
||||
self.writer.write_all(&self.encoder.header(&header))
|
||||
}
|
||||
|
||||
fn event(&mut self, event: asciicast::Event) -> io::Result<()> {
|
||||
self.0.write_all(&self.1.event(event))
|
||||
self.writer.write_all(&self.encoder.event(event))
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.0.write_all(&self.1.finish())
|
||||
self.writer.write_all(&self.encoder.flush())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::locale;
|
||||
use crate::logger;
|
||||
use crate::pty;
|
||||
use crate::streamer::{self, KeyBindings};
|
||||
use crate::tty::{self, FixedSizeTty, Tty};
|
||||
use crate::tty::{self, FixedSizeTty};
|
||||
use crate::util;
|
||||
use anyhow::bail;
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
@@ -80,7 +80,6 @@ impl Command for cli::Stream {
|
||||
record_input,
|
||||
keys,
|
||||
notifier,
|
||||
tty.get_theme(),
|
||||
);
|
||||
|
||||
self.init_logging()?;
|
||||
|
||||
@@ -1,52 +1,24 @@
|
||||
use crate::asciicast::{Encoder, Event, Header};
|
||||
use crate::tty;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub struct AsciicastEncoder {
|
||||
inner: Encoder,
|
||||
append: bool,
|
||||
metadata: Metadata,
|
||||
}
|
||||
|
||||
pub struct Metadata {
|
||||
pub idle_time_limit: Option<f64>,
|
||||
pub command: Option<String>,
|
||||
pub title: Option<String>,
|
||||
pub env: Option<HashMap<String, String>>,
|
||||
pub theme: Option<tty::Theme>,
|
||||
}
|
||||
|
||||
impl AsciicastEncoder {
|
||||
pub fn new(append: bool, time_offset: u64, metadata: Metadata) -> Self {
|
||||
pub fn new(append: bool, time_offset: u64) -> Self {
|
||||
let inner = Encoder::new(time_offset);
|
||||
|
||||
Self {
|
||||
inner,
|
||||
append,
|
||||
metadata,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_header(&self, timestamp: Option<u64>, tty_size: &tty::TtySize) -> Header {
|
||||
Header {
|
||||
cols: tty_size.0,
|
||||
rows: tty_size.1,
|
||||
timestamp,
|
||||
idle_time_limit: self.metadata.idle_time_limit,
|
||||
command: self.metadata.command.clone(),
|
||||
title: self.metadata.title.clone(),
|
||||
env: self.metadata.env.clone(),
|
||||
theme: self.metadata.theme.clone(),
|
||||
}
|
||||
Self { inner, append }
|
||||
}
|
||||
}
|
||||
|
||||
impl super::Encoder for AsciicastEncoder {
|
||||
fn start(&mut self, timestamp: Option<u64>, tty_size: tty::TtySize) -> Vec<u8> {
|
||||
fn header(&mut self, header: &Header) -> Vec<u8> {
|
||||
if self.append {
|
||||
Vec::new()
|
||||
} else {
|
||||
self.inner.header(&self.build_header(timestamp, &tty_size))
|
||||
self.inner.header(header)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,19 +26,7 @@ impl super::Encoder for AsciicastEncoder {
|
||||
self.inner.event(&event)
|
||||
}
|
||||
|
||||
fn finish(&mut self) -> Vec<u8> {
|
||||
fn flush(&mut self) -> Vec<u8> {
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Header> for Metadata {
|
||||
fn from(header: &Header) -> Self {
|
||||
Metadata {
|
||||
idle_time_limit: header.idle_time_limit.as_ref().cloned(),
|
||||
command: header.command.as_ref().cloned(),
|
||||
title: header.title.as_ref().cloned(),
|
||||
env: header.env.as_ref().cloned(),
|
||||
theme: header.theme.as_ref().cloned(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,21 +2,19 @@ mod asciicast;
|
||||
mod raw;
|
||||
mod txt;
|
||||
|
||||
pub use asciicast::AsciicastEncoder;
|
||||
pub use asciicast::Metadata;
|
||||
pub use raw::RawEncoder;
|
||||
pub use txt::TextEncoder;
|
||||
|
||||
use crate::asciicast::Event;
|
||||
use crate::tty;
|
||||
use crate::asciicast::Header;
|
||||
use anyhow::Result;
|
||||
pub use asciicast::AsciicastEncoder;
|
||||
pub use raw::RawEncoder;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
pub use txt::TextEncoder;
|
||||
|
||||
pub trait Encoder {
|
||||
fn start(&mut self, timestamp: Option<u64>, tty_size: tty::TtySize) -> Vec<u8>;
|
||||
fn header(&mut self, header: &Header) -> Vec<u8>;
|
||||
fn event(&mut self, event: Event) -> Vec<u8>;
|
||||
fn finish(&mut self) -> Vec<u8>;
|
||||
fn flush(&mut self) -> Vec<u8>;
|
||||
}
|
||||
|
||||
pub trait EncoderExt {
|
||||
@@ -25,14 +23,13 @@ pub trait EncoderExt {
|
||||
|
||||
impl<E: Encoder + ?Sized> EncoderExt for E {
|
||||
fn encode_to_file(&mut self, cast: crate::asciicast::Asciicast, file: &mut File) -> Result<()> {
|
||||
let tty_size = tty::TtySize(cast.header.cols, cast.header.rows);
|
||||
file.write_all(&self.start(cast.header.timestamp, tty_size))?;
|
||||
file.write_all(&self.header(&cast.header))?;
|
||||
|
||||
for event in cast.events {
|
||||
file.write_all(&self.event(event?))?;
|
||||
}
|
||||
|
||||
file.write_all(&self.finish())?;
|
||||
file.write_all(&self.flush())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use crate::asciicast::{Event, EventData};
|
||||
use crate::tty;
|
||||
use crate::asciicast::{Event, EventData, Header};
|
||||
|
||||
pub struct RawEncoder {
|
||||
append: bool,
|
||||
@@ -12,11 +11,11 @@ impl RawEncoder {
|
||||
}
|
||||
|
||||
impl super::Encoder for RawEncoder {
|
||||
fn start(&mut self, _timestamp: Option<u64>, tty_size: tty::TtySize) -> Vec<u8> {
|
||||
fn header(&mut self, header: &Header) -> Vec<u8> {
|
||||
if self.append {
|
||||
Vec::new()
|
||||
} else {
|
||||
format!("\x1b[8;{};{}t", tty_size.1, tty_size.0).into_bytes()
|
||||
format!("\x1b[8;{};{}t", header.rows, header.cols).into_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +27,7 @@ impl super::Encoder for RawEncoder {
|
||||
}
|
||||
}
|
||||
|
||||
fn finish(&mut self) -> Vec<u8> {
|
||||
fn flush(&mut self) -> Vec<u8> {
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
@@ -36,18 +35,20 @@ impl super::Encoder for RawEncoder {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::RawEncoder;
|
||||
use crate::asciicast::Event;
|
||||
use crate::asciicast::{Event, Header};
|
||||
use crate::encoder::Encoder;
|
||||
use crate::tty::TtySize;
|
||||
|
||||
#[test]
|
||||
fn encoder() {
|
||||
let mut enc = RawEncoder::new(false);
|
||||
|
||||
assert_eq!(
|
||||
enc.start(None, TtySize(100, 50)),
|
||||
"\x1b[8;50;100t".as_bytes()
|
||||
);
|
||||
let header = Header {
|
||||
cols: 100,
|
||||
rows: 50,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
assert_eq!(enc.header(&header), "\x1b[8;50;100t".as_bytes());
|
||||
|
||||
assert_eq!(
|
||||
enc.event(Event::output(0, "he\x1b[1mllo\r\n".to_owned())),
|
||||
@@ -62,6 +63,6 @@ mod tests {
|
||||
assert!(enc.event(Event::input(2, ".".to_owned())).is_empty());
|
||||
assert!(enc.event(Event::resize(3, (80, 24))).is_empty());
|
||||
assert!(enc.event(Event::marker(4, ".".to_owned())).is_empty());
|
||||
assert!(enc.finish().is_empty());
|
||||
assert!(enc.flush().is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use crate::asciicast::{Event, EventData};
|
||||
use crate::tty;
|
||||
use crate::asciicast::{Event, EventData, Header};
|
||||
use avt::util::TextCollector;
|
||||
|
||||
pub struct TextEncoder {
|
||||
@@ -13,9 +12,9 @@ impl TextEncoder {
|
||||
}
|
||||
|
||||
impl super::Encoder for TextEncoder {
|
||||
fn start(&mut self, _timestamp: Option<u64>, tty_size: tty::TtySize) -> Vec<u8> {
|
||||
fn header(&mut self, header: &Header) -> Vec<u8> {
|
||||
let vt = avt::Vt::builder()
|
||||
.size(tty_size.0 as usize, tty_size.1 as usize)
|
||||
.size(header.cols as usize, header.rows as usize)
|
||||
.resizable(true)
|
||||
.scrollback_limit(100)
|
||||
.build();
|
||||
@@ -39,7 +38,7 @@ impl super::Encoder for TextEncoder {
|
||||
}
|
||||
}
|
||||
|
||||
fn finish(&mut self) -> Vec<u8> {
|
||||
fn flush(&mut self) -> Vec<u8> {
|
||||
text_lines_to_bytes(self.collector.take().unwrap().flush().iter())
|
||||
}
|
||||
}
|
||||
@@ -56,15 +55,20 @@ fn text_lines_to_bytes<S: AsRef<str>>(lines: impl Iterator<Item = S>) -> Vec<u8>
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::TextEncoder;
|
||||
use crate::asciicast::Event;
|
||||
use crate::asciicast::{Event, Header};
|
||||
use crate::encoder::Encoder;
|
||||
use crate::tty::TtySize;
|
||||
|
||||
#[test]
|
||||
fn encoder() {
|
||||
let mut enc = TextEncoder::new();
|
||||
|
||||
assert!(enc.start(None, TtySize(3, 1)).is_empty());
|
||||
let header = Header {
|
||||
cols: 3,
|
||||
rows: 1,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
assert!(enc.header(&header).is_empty());
|
||||
|
||||
assert!(enc
|
||||
.event(Event::output(0, "he\x1b[1mllo\r\n".to_owned()))
|
||||
@@ -74,6 +78,6 @@ mod tests {
|
||||
.event(Event::output(1, "world\r\n".to_owned()))
|
||||
.is_empty());
|
||||
|
||||
assert_eq!(enc.finish(), "hello\nworld\n".as_bytes());
|
||||
assert_eq!(enc.flush(), "hello\nworld\n".as_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
10
src/pty.rs
10
src/pty.rs
@@ -1,5 +1,5 @@
|
||||
use crate::io::set_non_blocking;
|
||||
use crate::tty::{Tty, TtySize};
|
||||
use crate::tty::{Theme, Tty, TtySize};
|
||||
use anyhow::{bail, Result};
|
||||
use nix::errno::Errno;
|
||||
use nix::libc::EIO;
|
||||
@@ -23,7 +23,7 @@ use std::time::{Duration, Instant};
|
||||
type ExtraEnv = HashMap<String, String>;
|
||||
|
||||
pub trait Handler {
|
||||
fn start(&mut self, tty_size: TtySize);
|
||||
fn start(&mut self, tty_size: TtySize, theme: Option<Theme>);
|
||||
fn output(&mut self, time: Duration, data: &[u8]) -> bool;
|
||||
fn input(&mut self, time: Duration, data: &[u8]) -> bool;
|
||||
fn resize(&mut self, time: Duration, tty_size: TtySize) -> bool;
|
||||
@@ -37,7 +37,7 @@ pub fn exec<S: AsRef<str>, T: Tty + ?Sized, H: Handler>(
|
||||
) -> Result<i32> {
|
||||
let winsize = tty.get_size();
|
||||
let epoch = Instant::now();
|
||||
handler.start(winsize.into());
|
||||
handler.start(winsize.into(), tty.get_theme());
|
||||
let result = unsafe { pty::forkpty(Some(&winsize), None) }?;
|
||||
|
||||
match result.fork_result {
|
||||
@@ -377,7 +377,7 @@ impl Drop for SignalFd {
|
||||
mod tests {
|
||||
use super::Handler;
|
||||
use crate::pty::ExtraEnv;
|
||||
use crate::tty::{FixedSizeTty, NullTty, TtySize};
|
||||
use crate::tty::{FixedSizeTty, NullTty, Theme, TtySize};
|
||||
use std::time::Duration;
|
||||
|
||||
#[derive(Default)]
|
||||
@@ -387,7 +387,7 @@ mod tests {
|
||||
}
|
||||
|
||||
impl Handler for TestHandler {
|
||||
fn start(&mut self, tty_size: TtySize) {
|
||||
fn start(&mut self, tty_size: TtySize, _theme: Option<Theme>) {
|
||||
self.tty_size = Some(tty_size);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,12 @@ pub struct Recorder {
|
||||
}
|
||||
|
||||
pub trait Output {
|
||||
fn header(&mut self, time: SystemTime, tty_size: tty::TtySize) -> io::Result<()>;
|
||||
fn header(
|
||||
&mut self,
|
||||
time: SystemTime,
|
||||
tty_size: tty::TtySize,
|
||||
theme: Option<tty::Theme>,
|
||||
) -> io::Result<()>;
|
||||
fn event(&mut self, event: Event) -> io::Result<()>;
|
||||
fn flush(&mut self) -> io::Result<()>;
|
||||
}
|
||||
@@ -77,9 +82,9 @@ impl Recorder {
|
||||
}
|
||||
|
||||
impl pty::Handler for Recorder {
|
||||
fn start(&mut self, tty_size: tty::TtySize) {
|
||||
fn start(&mut self, tty_size: tty::TtySize, theme: Option<tty::Theme>) {
|
||||
let mut output = self.output.take().unwrap();
|
||||
let _ = output.header(SystemTime::now(), tty_size);
|
||||
let _ = output.header(SystemTime::now(), tty_size, theme);
|
||||
let receiver = self.receiver.take().unwrap();
|
||||
let mut notifier = self.notifier.take().unwrap();
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ pub struct Streamer {
|
||||
prefix_mode: bool,
|
||||
listener: Option<net::TcpListener>,
|
||||
forward_url: Option<url::Url>,
|
||||
theme: Option<tty::Theme>,
|
||||
// XXX: field (drop) order below is crucial for correct shutdown
|
||||
pty_tx: mpsc::UnboundedSender<Event>,
|
||||
notifier_tx: std::sync::mpsc::Sender<String>,
|
||||
@@ -44,7 +43,6 @@ impl Streamer {
|
||||
record_input: bool,
|
||||
keys: KeyBindings,
|
||||
notifier: Box<dyn Notifier>,
|
||||
theme: Option<tty::Theme>,
|
||||
) -> Self {
|
||||
let (notifier_tx, notifier_rx) = std::sync::mpsc::channel();
|
||||
let (pty_tx, pty_rx) = mpsc::unbounded_channel();
|
||||
@@ -63,7 +61,6 @@ impl Streamer {
|
||||
prefix_mode: false,
|
||||
listener,
|
||||
forward_url,
|
||||
theme,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +79,7 @@ impl Streamer {
|
||||
}
|
||||
|
||||
impl pty::Handler for Streamer {
|
||||
fn start(&mut self, tty_size: tty::TtySize) {
|
||||
fn start(&mut self, tty_size: tty::TtySize, theme: Option<tty::Theme>) {
|
||||
let pty_rx = self.pty_rx.take().unwrap();
|
||||
let (clients_tx, mut clients_rx) = mpsc::channel(1);
|
||||
let shutdown_token = tokio_util::sync::CancellationToken::new();
|
||||
@@ -105,8 +102,6 @@ impl pty::Handler for Streamer {
|
||||
))
|
||||
});
|
||||
|
||||
let theme = self.theme.take();
|
||||
|
||||
self.event_loop_handle = wrap_thread_handle(thread::spawn(move || {
|
||||
runtime.block_on(async move {
|
||||
event_loop(pty_rx, &mut clients_rx, tty_size, theme).await;
|
||||
|
||||
Reference in New Issue
Block a user