Fix bundling/path errors, sidecar support, iOS/Android simulator support, asset hotreload fixes, serverfn hotrelad, native tailwind support (#2779)
* wip: fix manganis import path * upgrade tauri bundler, convert todo!() to unimplemented!() * feat: mobile hotreloading + ios asset configuration * remove oid demo and its associated env vars * nuke all the things that cause cache thrashing * swap to Asset type * add some more logs * display impl for attrvalue * dont panic on collect failure * cut down web deps to 150 * clean up deps in a lot of places, simplify build scripts * clean up asset resolution and cli-dev profile * wire up absolute paths for manganis asset in a particular mode * move document related things around to shorten compile times * move most things to `document::Item` and then decompose the cli-config * switch link to stylesheet for clarity in examples * move manganis workspace example to examples folder * decompose manganis-cli-support * dont need mobile demo anymore * remove gloo dialogs * html doesnt need document * rename hotreload to devtools * really clean up the html crate * fix weird rsx spacing * clean up desktop to use callback * clean up document a bit * re-wire up devsocket * fix utf css * yeeeet that js out of here * synthetic web system works * web crate almost done being cleaned up * desktop mostly cleaned up too * clean up cli a bit * more cli cleanup * cli builds again * clean up cli, inline structs, cut down number of unique types where possible * hotreload works again for desktop and this time, mobile too * cfg out tungstenite * devserver err * more refactor to cli builder * switch to unbounded_send * new structure is much cleaner * add http serve subcommand * bundled hotreload * kick stylsheets * clean up a bit more, split up eventloop * amazingly serve seems done * change from pub to pub(crate) in cli * remove tools * bit more polish to cli * fix issue with join * gracefully handle fullstack without a server * fullstack mobile demo * fix launch function, move projects into example-projects folder * hoist examples * add "run" command * clean up launch * remove old manual websocket receiver * doctor command * allow desktop to scroll * cut apart router crate * dont put launch in prelude * use dioxus::launch where possible * rename rsx, cut out hotreload tests * remove liveview project * bump native * fix compile for renderers * move sync event response out of interpreter * move render in serve * rollback settings change * cli compiles, huzzah! * change uris for asset * fix asset * new tui screen * new cargo-like tui works * very very verty close * it works! very small bug with incorrect grapheme calc * Clean up devserver a bit * status sytem * tidy up debug filters * clean up logging situation * Fix a number of bugs with log printing * new printing system is more reliable * wire up more stuff * things working but fullstack is having issues * fullstack works again! * hotreloading bundled assets works again * bundled hotreload and beginnings of macos bundling * Hotreload desktop * combined server builds * add build handle * fix fullstack assets * make open async, add some hooks for ios * migrate filemap to runner * wip global crate system * fixup bundles + organize asset * fix asset location bug * all the bundled reloading! * open ios simulator! * full hotreload support for mobile + serverfn * basic cleanups * clean up dx * Move filemap * fix cutting of newlines * assets workibg, some android * hoist wry/tao * use sync locks and headers to fix issues with android * desktop -> mac/win/linux with alias * better logging * feat: workspace (entire computer!) hotreload * should rebuild toggle, ios simulator bootup * proper mobile support in launch * more robust handling of assets * fix cargo * bring back some of tauri bundle * make warnings go away, clippy happy on cli * some final clippy cleanups * fmt * move manganis to its own folder * upgrade bundle to stable * drastically slim down manganis, prepping for merge * typos, failing test, docsrs config * remove static gen test * nix static gen test * we use --platform web instead of --platform fullstack now * only bind dev urls in desktop/mobile * install gtk * nix static gen * split build dir by app name
This commit is contained in:
1 parent
ef436e4ed0
commit
7ec3453ca3
156 files changed
+11544
-9005
No files matched your search
@@ -0,0 +1,172 @@
|
||||
use ratatui::prelude::*;
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
|
||||
/// A buffer that can be rendered to and then dumped as raw ansi codes
|
||||
///
|
||||
/// This is taken from a PR on the ratatui repo (https://github.com/ratatui/ratatui/pull/1065) and
|
||||
/// modified to be more appropriate for our use case.
|
||||
pub struct AnsiStringBuffer {
|
||||
buf: Buffer,
|
||||
}
|
||||
|
||||
// The sentinel character used to mark the end of the ansi string so when we dump it, we know where to stop
|
||||
// Not sure if we actually still need this....
|
||||
const SENTINEL: &str = "✆";
|
||||
|
||||
impl AnsiStringBuffer {
|
||||
/// Creates a new `AnsiStringBuffer` with the given width and height.
|
||||
pub(crate) fn new(width: u16, height: u16) -> Self {
|
||||
Self {
|
||||
buf: Buffer::empty(Rect::new(0, 0, width, height)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Renders the given widget to the buffer, returning the string with the ansi codes
|
||||
pub(crate) fn render(mut self, widget: impl Widget) -> String {
|
||||
widget.render(self.buf.area, &mut self.buf);
|
||||
self.trim_end();
|
||||
self.to_string()
|
||||
}
|
||||
|
||||
/// Trims the buffer to the last line, returning the number of cells to be rendered
|
||||
#[allow(deprecated)]
|
||||
fn trim_end(&mut self) {
|
||||
for y in 0..self.buf.area.height {
|
||||
let start_x = self.buf.area.width;
|
||||
let mut first_non_empty = start_x - 1;
|
||||
for x in (0..start_x).rev() {
|
||||
if self.buf.get(x, y) != &buffer::Cell::EMPTY {
|
||||
break;
|
||||
}
|
||||
first_non_empty = x;
|
||||
}
|
||||
self.buf.get_mut(first_non_empty, y).set_symbol(SENTINEL);
|
||||
}
|
||||
}
|
||||
|
||||
fn write_fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
let mut last_style = None;
|
||||
for y in 0..self.buf.area.height {
|
||||
for x in 0..self.buf.area.width {
|
||||
let cell = self.buf.cell((x, y)).unwrap();
|
||||
if cell.symbol() == SENTINEL {
|
||||
f.write_str("\n")?;
|
||||
break;
|
||||
}
|
||||
|
||||
let style = (cell.fg, cell.bg, cell.modifier);
|
||||
if last_style.is_none() || last_style != Some(style) {
|
||||
write_cell_style(f, cell)?;
|
||||
last_style = Some(style);
|
||||
}
|
||||
f.write_str(cell.symbol())?;
|
||||
}
|
||||
}
|
||||
f.write_str("\u{1b}[0m")
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for AnsiStringBuffer {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
self.write_fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
fn write_cell_style(f: &mut Formatter, cell: &buffer::Cell) -> fmt::Result {
|
||||
f.write_str("\u{1b}[")?;
|
||||
write_modifier(f, cell.modifier)?;
|
||||
write_fg(f, cell.fg)?;
|
||||
write_bg(f, cell.bg)?;
|
||||
f.write_str("m")
|
||||
}
|
||||
|
||||
fn write_modifier(f: &mut Formatter, modifier: Modifier) -> fmt::Result {
|
||||
if modifier.contains(Modifier::BOLD) {
|
||||
f.write_str("1;")?;
|
||||
}
|
||||
if modifier.contains(Modifier::DIM) {
|
||||
f.write_str("2;")?;
|
||||
}
|
||||
if modifier.contains(Modifier::ITALIC) {
|
||||
f.write_str("3;")?;
|
||||
}
|
||||
if modifier.contains(Modifier::UNDERLINED) {
|
||||
f.write_str("4;")?;
|
||||
}
|
||||
if modifier.contains(Modifier::SLOW_BLINK) {
|
||||
f.write_str("5;")?;
|
||||
}
|
||||
if modifier.contains(Modifier::RAPID_BLINK) {
|
||||
f.write_str("6;")?;
|
||||
}
|
||||
if modifier.contains(Modifier::REVERSED) {
|
||||
f.write_str("7;")?;
|
||||
}
|
||||
if modifier.contains(Modifier::HIDDEN) {
|
||||
f.write_str("8;")?;
|
||||
}
|
||||
if modifier.contains(Modifier::CROSSED_OUT) {
|
||||
f.write_str("9;")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_fg(f: &mut Formatter, color: Color) -> fmt::Result {
|
||||
f.write_str(match color {
|
||||
Color::Reset => "39",
|
||||
Color::Black => "30",
|
||||
Color::Red => "31",
|
||||
Color::Green => "32",
|
||||
Color::Yellow => "33",
|
||||
Color::Blue => "34",
|
||||
Color::Magenta => "35",
|
||||
Color::Cyan => "36",
|
||||
Color::Gray => "37",
|
||||
Color::DarkGray => "90",
|
||||
Color::LightRed => "91",
|
||||
Color::LightGreen => "92",
|
||||
Color::LightYellow => "93",
|
||||
Color::LightBlue => "94",
|
||||
Color::LightMagenta => "95",
|
||||
Color::LightCyan => "96",
|
||||
Color::White => "97",
|
||||
_ => "",
|
||||
})?;
|
||||
if let Color::Rgb(red, green, blue) = color {
|
||||
f.write_fmt(format_args!("38;2;{red};{green};{blue}"))?;
|
||||
}
|
||||
if let Color::Indexed(i) = color {
|
||||
f.write_fmt(format_args!("38;5;{i}"))?;
|
||||
}
|
||||
f.write_str(";")
|
||||
}
|
||||
|
||||
fn write_bg(f: &mut Formatter, color: Color) -> fmt::Result {
|
||||
f.write_str(match color {
|
||||
Color::Reset => "49",
|
||||
Color::Black => "40",
|
||||
Color::Red => "41",
|
||||
Color::Green => "42",
|
||||
Color::Yellow => "43",
|
||||
Color::Blue => "44",
|
||||
Color::Magenta => "45",
|
||||
Color::Cyan => "46",
|
||||
Color::Gray => "47",
|
||||
Color::DarkGray => "100",
|
||||
Color::LightRed => "101",
|
||||
Color::LightGreen => "102",
|
||||
Color::LightYellow => "103",
|
||||
Color::LightBlue => "104",
|
||||
Color::LightMagenta => "105",
|
||||
Color::LightCyan => "106",
|
||||
Color::White => "107",
|
||||
_ => "",
|
||||
})?;
|
||||
if let Color::Rgb(red, green, blue) = color {
|
||||
f.write_fmt(format_args!("48;2;{red};{green};{blue}"))?;
|
||||
}
|
||||
if let Color::Indexed(i) = color {
|
||||
f.write_fmt(format_args!("48;5;{i}"))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Reference in new issue
Block a user