diff --git a/Dockerfile b/Dockerfile index 84e81022..ec0f3dcf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,6 +8,7 @@ COPY ./dist $APP_DIR WORKDIR $APP_DIR ENV CELERSERVER_LOG=INFO +ENV CELERSERVER_ANSI=0 ENV CELERSERVER_PORT=80 ENV CELERSERVER_DOCS_DIR=/opt/app/docs ENV CELERSERVER_APP_DIR=/opt/app/app diff --git a/web-client/src/common.css b/web-client/src/common.css index ddcd9f06..7507bcba 100644 --- a/web-client/src/common.css +++ b/web-client/src/common.css @@ -15,13 +15,25 @@ color: #ff8888; fill: #ff8888; } +@media (prefers-color-scheme: light) { + .color-success { + color: #44cc44; + fill: #44cc44; + } -.color-success { - color: #88ff88; - fill: #88ff88; + .color-progress { + color: #cc8844; + fill: #cc8844; + } } +@media (prefers-color-scheme: dark) { + .color-success { + color: #88ff88; + fill: #88ff88; + } -.color-progress { - color: #ffcc88; - fill: #ffcc88; + .color-progress { + color: #ffcc88; + fill: #ffcc88; + } } diff --git a/web-client/src/core/kernel/editor/EditorKernelImpl.ts b/web-client/src/core/kernel/editor/EditorKernelImpl.ts index 88c3f1fc..ff83b546 100644 --- a/web-client/src/core/kernel/editor/EditorKernelImpl.ts +++ b/web-client/src/core/kernel/editor/EditorKernelImpl.ts @@ -140,9 +140,11 @@ export class EditorKernelImpl implements EditorKernel { if (isUserAction) { this.idleMgr.notifyActivity(); } - return await this.idleMgr.pauseIdleScope(async () => { + const result = await this.idleMgr.pauseIdleScope(async () => { return await this.fileMgr.loadChangesFromFs(); }); + this.compile(); + return result; } public async saveChangesToFs( @@ -202,9 +204,6 @@ export class EditorKernelImpl implements EditorKernel { if (!this.fileMgr.isFsLoaded()) { return; } - EditorLog.info( - "idle" + (isLong ? " (long)" : "") + ` duration= ${duration}ms`, - ); const { autoLoadActive, unsavedFiles } = viewSelector( this.store.getState(), ); @@ -225,7 +224,6 @@ export class EditorKernelImpl implements EditorKernel { if (autoLoadActive) { if (autoLoadEnabled) { - EditorLog.info("auto loading changes..."); await this.loadChangesFromFs(false /* isUserAction */); // make sure file system view is rerendered in case there are directory updates shouldRerenderFs = true; @@ -245,7 +243,6 @@ export class EditorKernelImpl implements EditorKernel { } if (autoSaveEnabled) { - EditorLog.info("auto saving changes..."); await this.saveChangesToFs(false /* isUserAction */); // make sure file system view is rerendered in case there are directory updates shouldRerenderFs = true; @@ -257,10 +254,6 @@ export class EditorKernelImpl implements EditorKernel { // do this last so we can get the latest save status after auto-save this.fileMgr.updateDirtyFileList(unsavedFiles); - - // if (!shouldRecompile && await this.fileMgr.needsRecompile()) { - // shouldRecompile = true; - // } if (shouldRecompile) { this.compile(); } diff --git a/web-client/src/core/layout/utils.ts b/web-client/src/core/layout/utils.ts index 9eb31746..b90217ff 100644 --- a/web-client/src/core/layout/utils.ts +++ b/web-client/src/core/layout/utils.ts @@ -239,6 +239,6 @@ export const getAvailableToolbarLocations = ( return []; } return WidgetTypes.map((type) => { - return layout[type] ? null : type; + return layout[type] ? type : null; }).filter(Boolean) as WidgetType[]; }; diff --git a/web-client/src/ui/doc/Doc.css b/web-client/src/ui/doc/Doc.css index 3f38ced9..5d1a6a56 100644 --- a/web-client/src/ui/doc/Doc.css +++ b/web-client/src/ui/doc/Doc.css @@ -99,11 +99,12 @@ .docnote-container { display: none; /* hide by default */ transition-duration: 0.1s; + left: 0px; + right: 0px; } .docnote-container-expanded { - /* make the notes stick to the right side*/ - right: 0px; + left: unset; z-index: 100; } diff --git a/web-client/src/ui/editor/Editor.css b/web-client/src/ui/editor/Editor.css index 53f5a13a..8f0db3ac 100644 --- a/web-client/src/ui/editor/Editor.css +++ b/web-client/src/ui/editor/Editor.css @@ -14,13 +14,20 @@ flex-grow: 1; display: flex; flex-direction: column; + box-sizing: border-box; } @media (prefers-color-scheme: dark) { #editor-panel { + border-left: 1px solid #333; background-color: #1e1e1e; } } +@media (prefers-color-scheme: light) { + #editor-panel { + border-left: 1px solid #ccc; + } +} #editor-file-name { padding: 4px; diff --git a/web-client/src/ui/editor/tree/EditorTree.css b/web-client/src/ui/editor/tree/EditorTree.css index 6faae012..84164d91 100644 --- a/web-client/src/ui/editor/tree/EditorTree.css +++ b/web-client/src/ui/editor/tree/EditorTree.css @@ -57,5 +57,8 @@ .file-type-md { color: #61afef; - fill: #61afef; +} + +.file-type-image { + color: #af81af; } diff --git a/web-client/src/ui/editor/tree/TreeIcon.tsx b/web-client/src/ui/editor/tree/TreeIcon.tsx index 247bd9c2..1f25e199 100644 --- a/web-client/src/ui/editor/tree/TreeIcon.tsx +++ b/web-client/src/ui/editor/tree/TreeIcon.tsx @@ -1,6 +1,7 @@ import { Folder16Filled, - Document16Filled, + Document16Regular, + Image16Filled, Info16Filled, CodeJs16Filled, CodeTs16Filled, @@ -23,30 +24,28 @@ const getFileTypeAndIcon = ({ if (isDirectory) { return ["folder", ]; } - if ( - file.endsWith(".js") || - file.endsWith(".jsx") || - file.endsWith(".mjs") || - file.endsWith(".cjs") - ) { + if (file.match(/\.(m|c)?jsx?$/i)) { return ["js", ]; } - if (file.endsWith(".ts") || file.endsWith(".tsx")) { + if (file.match(/\.(m|c)?tsx?$/i)) { return ["ts", ]; } - if (file.endsWith(".py")) { + if (file.match(/\.py$/i)) { return ["py", ]; } - if (file.endsWith(".json")) { + if (file.match(/\.json$/i)) { return ["json", ]; } - if (file.endsWith(".yaml") || file.endsWith(".yml")) { + if (file.match(/\.ya?ml$/i)) { return ["yaml", ]; } - if (file.endsWith(".md")) { + if (file.match(/\.md$/i)) { return ["md", ]; } - return ["unknown", ]; + if (file.match(/\.(png|jpe?g|gif|webp)$/i)) { + return ["image", ]; + } + return ["unknown", ]; }; export const TreeIcon: React.FC = (props) => { diff --git a/web-server/Cargo.toml b/web-server/Cargo.toml index 62aa5f60..e236490d 100644 --- a/web-server/Cargo.toml +++ b/web-server/Cargo.toml @@ -16,7 +16,7 @@ tokio = { version = "1.32.0", features=["macros", "rt-multi-thread"] } tower = "0.4.13" tower-http = { version = "0.4.4", features = ["fs", "trace"] } tracing = "0.1.37" -tracing-subscriber = "0.3.17" +tracing-subscriber = { version = "0.3.17", features = ["ansi"] } [[bin]] name = "celerserver" diff --git a/web-server/Taskfile.yml b/web-server/Taskfile.yml index 199a09a5..97c12355 100644 --- a/web-server/Taskfile.yml +++ b/web-server/Taskfile.yml @@ -6,6 +6,7 @@ tasks: aliases: [d] env: CELERSERVER_LOG: INFO + CELERSERVER_ANSI: 1 CELERSERVER_PORT: 8173 CELERSERVER_DOCS_DIR: ../docs/src/.vitepress/dist CELERSERVER_APP_DIR: ../web-client/dist diff --git a/web-server/src/env.rs b/web-server/src/env.rs index d6c50bea..bc58c7f7 100644 --- a/web-server/src/env.rs +++ b/web-server/src/env.rs @@ -5,6 +5,8 @@ use tracing::Level; pub struct Environment { /// If server is running in debug mode pub logging_level: Level, + /// If ANSI formatting is enabled in logs + pub ansi: bool, /// Port to listen on pub port: u16, /// Directory to serve docs @@ -18,6 +20,7 @@ impl Environment { pub fn parse() -> Self { let mut logging_level = Level::INFO; let mut port = 8173; + let mut ansi = true; if let Ok(x) = env::var("CELERSERVER_LOG") { match x.to_uppercase().as_ref() { @@ -43,6 +46,12 @@ impl Environment { } } + if let Ok(x) = env::var("CELERSERVER_ANSI") { + if x == "0" { + ansi = false; + } + } + let docs_dir = if let Ok(x) = env::var("CELERSERVER_DOCS_DIR") { x } else { @@ -63,6 +72,7 @@ impl Environment { Self { logging_level, + ansi, port, docs_dir, app_dir, diff --git a/web-server/src/main.rs b/web-server/src/main.rs index ea2ffe5f..5cd2c96f 100644 --- a/web-server/src/main.rs +++ b/web-server/src/main.rs @@ -21,6 +21,7 @@ async fn main() -> Result<(), Box> { let env = Environment::parse(); tracing_subscriber::fmt() .compact() + .with_ansi(env.ansi) .with_max_level(env.logging_level) .init(); info!("configuring routes..."); diff --git a/web-themes/src/default.css b/web-themes/src/default.css index 797c1a13..4978ec44 100644 --- a/web-themes/src/default.css +++ b/web-themes/src/default.css @@ -101,3 +101,8 @@ background-color: #bbbbbb !important; } } + +/* Ending block */ +#doc-end { + background-color: #001a00; +} diff --git a/web-themes/src/granatus.css b/web-themes/src/granatus.css index f4d6c454..c27f9a3b 100644 --- a/web-themes/src/granatus.css +++ b/web-themes/src/granatus.css @@ -90,3 +90,6 @@ background-color: rgba(255, 255, 255, 0.1) !important; } } +#doc-end { + background-color: #cccccc; +}