Skip to content

Feature: web preview - #741

Open
rusudorin wants to merge 2 commits into
fatihak:mainfrom
rusudorin:feature/web-preview
Open

Feature: web preview#741
rusudorin wants to merge 2 commits into
fatihak:mainfrom
rusudorin:feature/web-preview

Conversation

@rusudorin

Copy link
Copy Markdown
Contributor

Introduces a new button where one can preview the plugin before updating the screen.

rusudorin and others added 2 commits August 16, 2026 13:55
Render a plugin's output in the browser without pushing it to the
e-ink display. Adds a POST /preview_plugin route that runs the same
orientation/resize/enhancement pipeline as the display and returns the
result as a base64 PNG, plus a Preview button and modal in the plugin
settings UI.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The preview route rendered the plugin image inline in the single
Waitress worker thread, blocking the whole web UI and running a second
Chromium screenshot process concurrently with the background refresh
thread, which could hang indefinitely.

Route previews through the background refresh task (like Update Now) so
rendering is serialized, and capture the processed image instead of
displaying it. Falls back to inline rendering only when the refresh task
is not running (dev mode).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings August 16, 2026 12:37
@rusudorin

Copy link
Copy Markdown
Contributor Author

Note: I'm playing with github copilot with features I would find interesting. Wanted to share with you also if this is something you consider.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a “Preview” workflow that renders a plugin image using the same display-processing pipeline as a real update, but returns it to the web UI without pushing anything to the device.

Changes:

  • Adds a Preview button + modal to the plugin settings page and calls a new backend endpoint to fetch a rendered image.
  • Introduces a /preview_plugin Flask route that generates and base64-encodes a processed PNG preview.
  • Refactors display processing into DisplayManager.process_image() and adds a PreviewRefresh action to serialize preview rendering via the background refresh thread.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/templates/plugin.html Adds Preview button, JS handler to POST form data, and a preview modal to display the returned image.
src/static/styles/main.css Adds styling for the preview modal hint text and image container.
src/refresh_task.py Adds PreviewRefresh and a preview() entry point to render via the background worker without updating the device.
src/display/display_manager.py Extracts image orientation/resize/enhancement pipeline into process_image() and reuses it in display_image().
src/blueprints/plugin.py Adds /preview_plugin route to generate a processed image preview and return it as a base64 data URL.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +57 to +75
def process_image(self, image, image_settings=[]):

"""
Applies the same orientation, resize and enhancement pipeline used when
rendering to the device, without pushing the result to any display.

Args:
image (PIL.Image): The image to be processed.
image_settings (list, optional): List of settings to modify image rendering.

Returns:
PIL.Image: The processed image as it would appear on the device.
"""

image = change_orientation(image, self.device_config.get_config("orientation"))
image = resize_image(image, self.device_config.get_resolution(), image_settings)
if self.device_config.get_config("inverted_image"): image = image.rotate(180)
image = apply_image_enhancement(image, self.device_config.get_config("image_settings"))
return image
Comment thread src/refresh_task.py
Comment on lines +179 to +182
self.refresh_event.wait()
if self.refresh_result.get("exception"):
raise self.refresh_result.get("exception")
return self.refresh_result.get("preview_image")
Comment thread src/blueprints/plugin.py
Comment on lines +239 to +242
plugin_settings = parse_form(request.form)
plugin_settings.update(handle_request_files(request.files))
plugin_id = plugin_settings.pop("plugin_id")

Comment thread src/blueprints/plugin.py
Comment on lines +264 to +266
except Exception as e:
logger.exception(f"Error in preview_plugin: {str(e)}")
return jsonify({"error": f"An error occurred: {str(e)}"}), 500
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants