Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
trungleduc committed Sep 17, 2024
1 parent 0ffd12a commit 86e60df
Show file tree
Hide file tree
Showing 10 changed files with 376 additions and 80 deletions.
136 changes: 104 additions & 32 deletions packages/voila/src/plugins/widget/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ import { VoilaApp } from '../../app';

import { Widget } from '@lumino/widgets';
import { RenderedCells } from './renderedcells';
import {
// OutputArea,
OutputAreaModel,
SimplifiedOutputArea
} from '@jupyterlab/outputarea';

const WIDGET_MIMETYPE = 'application/vnd.jupyter.widget-view+json';

Expand Down Expand Up @@ -123,40 +128,107 @@ export const renderOutputsPlugin: JupyterFrontEndPlugin<void> = {
rendermime.latexTypesetter?.typeset(md as HTMLElement);
});
// Render code cell
const cellOutputs = document.body.querySelectorAll(
'script[type="application/vnd.voila.cell-output+json"]'
);
cellOutputs.forEach(async (cellOutput) => {
const model = JSON.parse(cellOutput.innerHTML);

const mimeType = rendermime.preferredMimeType(model.data, 'any');

if (!mimeType) {
return null;
// const cellOutputs = document.body.querySelectorAll(
// 'script[type="application/vnd.voila.cell-output+json"]'
// );
// cellOutputs.forEach(async (cellOutput) => {
// const model = JSON.parse(cellOutput.innerHTML);

// const mimeType = rendermime.preferredMimeType(model.data, 'any');

// if (!mimeType) {
// return null;
// }
// const output = rendermime.createRenderer(mimeType);
// output.renderModel(model).catch((error) => {
// // Manually append error message to output
// const pre = document.createElement('pre');
// pre.textContent = `Javascript Error: ${error.message}`;
// output.node.appendChild(pre);

// // Remove mime-type-specific CSS classes
// pre.className = 'lm-Widget jp-RenderedText';
// pre.setAttribute('data-mime-type', 'application/vnd.jupyter.stderr');
// });

// output.addClass('jp-OutputArea-output');

// if (cellOutput.parentElement) {
// const container = cellOutput.parentElement;

// container.removeChild(cellOutput);

// // Attach output
// Widget.attach(output, container);
// }
// });
const kernelId = (app as VoilaApp).widgetManager?.kernel.id;
console.log('using kernel', kernelId);
const ws = new WebSocket(`ws://localhost:8866/voila/execution/${kernelId}`);
ws.onmessage = (msg) => {
const { action, payload } = JSON.parse(msg.data);
if (action === 'execution_result') {
const { cell_index, output_cell, request_kernel_id } = payload;
const element = document.querySelector(
`[cell-index="${cell_index + 1}"]`
);
if (element) {
const model = new OutputAreaModel({ trusted: true });
const area = new SimplifiedOutputArea({
model,
rendermime
});

const wrapper = document.createElement('div');
wrapper.classList.add('jp-Cell-outputWrapper');
const collapser = document.createElement('div');
collapser.classList.add(
'jp-Collapser',
'jp-OutputCollapser',
'jp-Cell-outputCollapser'
);
wrapper.appendChild(collapser);
element.lastElementChild?.appendChild(wrapper);

area.node.classList.add('jp-Cell-outputArea');

// Why do we need this? Are we missing a CSS class?
area.node.style.display = 'flex';
area.node.style.flexDirection = 'column';

Widget.attach(area, wrapper);
const skeleton = element
.getElementsByClassName('voila-skeleton-container')
.item(0);
if (skeleton) {
element.removeChild(skeleton);
}
const outputData = output_cell.outputs[0];
if (outputData) {
console.log(
'adding',
outputData,
'request_kernel_id',
request_kernel_id,
'kernelId',
kernelId
);
element.lastElementChild?.classList.remove(
'jp-mod-noOutputs',
'jp-mod-noInput'
);
model.add(outputData);
}
}
}
const output = rendermime.createRenderer(mimeType);
output.renderModel(model).catch((error) => {
// Manually append error message to output
const pre = document.createElement('pre');
pre.textContent = `Javascript Error: ${error.message}`;
output.node.appendChild(pre);

// Remove mime-type-specific CSS classes
pre.className = 'lm-Widget jp-RenderedText';
pre.setAttribute('data-mime-type', 'application/vnd.jupyter.stderr');
});

output.addClass('jp-OutputArea-output');

if (cellOutput.parentElement) {
const container = cellOutput.parentElement;

container.removeChild(cellOutput);
};
ws.onopen = () => {
console.log('opened');
ws.send(
JSON.stringify({ action: 'execute', payload: { kernel_id: kernelId } })
);
};

// Attach output
Widget.attach(output, container);
}
});
const node = document.getElementById('rendered_cells');
if (node) {
const cells = new RenderedCells({ node });
Expand Down
61 changes: 61 additions & 0 deletions share/jupyter/voila/templates/base/skeleton.macro.html.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{% macro css() %}
<!-- voila skeleton -->
<style>
.voila-skeleton-container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.voila-skeleton-post {
width: 220px;
height: 80px;
}
.voila-skeleton-post .voila-skeleton-avatar {
float: left;
width: 52px;
height: 52px;
background-color: #ccc;
border-radius: 25%;
margin: 8px;
background-image: linear-gradient(90deg, #ddd 0px, #e8e8e8 40px, #ddd 80px);
background-size: 600px;
animation: shine-avatar 1.6s infinite linear;
}
.voila-skeleton-post .voila-skeleton-line {
float: left;
width: 140px;
height: 16px;
margin-top: 12px;
border-radius: 7px;
background-image: linear-gradient(90deg, #ddd 0px, #e8e8e8 40px, #ddd 80px);
background-size: 600px;
animation: shine-lines 1.6s infinite linear;
}
.voila-skeleton-post .voila-skeleton-avatar + .voila-skeleton-line {
margin-top: 11px;
width: 100px;
}
.voila-skeleton-post .voila-skeleton-line ~ .voila-skeleton-line {
background-color: #ddd;
}
@keyframes shine-lines {
0% {
background-position: -100px;
}
40%, 100% {
background-position: 140px;
}
}
@keyframes shine-avatar {
0% {
background-position: -32px;
}
40%, 100% {
background-position: 208px;
}
}
</style>
{% endmacro %}
2 changes: 1 addition & 1 deletion share/jupyter/voila/templates/base/spinner.macro.html.j2
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
.voila-spinner-color2{
fill:#f8e14b;
}
}
</style>
{% endmacro %}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
spinner.style.display="flex";
}
var el = document.getElementById("loading_text");
innterText = text ?? `Executing ${cell_index} of ${cell_count}`
innterText = text ?? `Reading ${cell_index} of ${cell_count}`
if(el){
el.innerHTML = innterText;
}
Expand Down
9 changes: 9 additions & 0 deletions share/jupyter/voila/templates/lab/index.html.j2
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{%- extends 'nbconvert/templates/lab/index.html.j2' -%}
{% import "spinner.macro.html.j2" as spinner %}
{% import "skeleton.macro.html.j2" as skeleton %}
{% import "log.macro.html.j2" as log %}
{% from 'voila_setup.macro.html.j2' import voila_setup_helper_functions, voila_setup_labextensions with context %}

Expand All @@ -15,6 +16,7 @@
{% endif %}

{{ spinner.css() }}
{{ skeleton.css() }}

<style>
/*Hide empty cells*/
Expand Down Expand Up @@ -108,6 +110,13 @@
<script>
voila_process({{ cellloop.index }}, {{ cell_count }})
</script>
<div class="voila-skeleton-container">
<div class="voila-skeleton-post">
<div class="voila-skeleton-avatar"></div>
<div class="voila-skeleton-line"></div>
<div class="voila-skeleton-line"></div>
</div>
</div>
{{ super() }}
</div>
{%- endblock any_cell -%}
Expand Down
12 changes: 11 additions & 1 deletion voila/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import threading
import webbrowser

from .execution_request_handler import ExecutionRequestHandler

from .tornado.contentshandler import VoilaContentsHandler

from .voila_identity_provider import VoilaLoginHandler
Expand Down Expand Up @@ -715,7 +717,7 @@ def init_handlers(self) -> List:
]
)
handlers.extend(self.identity_provider.get_handlers())
if self.voila_configuration.preheat_kernel:
if self.voila_configuration.preheat_kernel or True:
handlers.append(
(
url_path_join(
Expand All @@ -724,6 +726,14 @@ def init_handlers(self) -> List:
RequestInfoSocketHandler,
)
)
handlers.append(
(
url_path_join(
self.server_url, r"/voila/execution/%s" % _kernel_id_regex
),
ExecutionRequestHandler,
)
)
# Serving JupyterLab extensions
handlers.append(
(
Expand Down
Loading

0 comments on commit 86e60df

Please sign in to comment.