7
33
Fork
You've already forked sentryshot
7

Feature improvement #85

Open
opened 2025年09月05日 05:25:18 +02:00 by henryouly · 8 comments
Collaborator
Copy link

Hi,

Really great project. I was using Frigate for my NVR system but the failing GPU acceleration on object detection nudged me to find alternatives. I've tried OS-NVR at first and finally got here.

I'd like to suggest some feature improvement. Some of these ideas I've already implemented in my forked github repository.

  1. A modern web UI. See this PR. I started hacking into the main app.rs and later realized I could just make a plugin, and there it is. I know having a fancy UI is probably not the starting goal, but with some reasonable work, I have built a Vite project with React + Tailwind CSS + Shadcn, like the modern web UI would look like today.
  2. Status plugin. See this PR. This is just copying the same idea I like from OS-NVR.
  3. A object detection client that talks to the OpenVino model server. See this PR. This is my original motivation to move away from Frigate openvino detector and embrace a server based architecture for running object detection.

I primarily use github for development, however when I tried to drop a PR I don't get much response, so I trace back here to see if you are interested in accepting any contributions and how. Appreicate your time and feedback on these improvement ideas.

Hi, Really great project. I was using Frigate for my NVR system but the failing GPU acceleration on object detection nudged me to find alternatives. I've tried [OS-NVR](https://github.com/OSNVR/OS-NVR) at first and finally got here. I'd like to suggest some feature improvement. Some of these ideas I've already implemented in my [forked github repository](https://github.com/henryouly/sentryshot). 1. A modern web UI. See this [PR](https://github.com/henryouly/sentryshot/pull/15). I started hacking into the main app.rs and later realized I could just make a plugin, and there it is. I know having a fancy UI is probably not the starting goal, but with some reasonable work, I have built a Vite project with React + Tailwind CSS + Shadcn, like the modern web UI would look like today. 2. Status plugin. See this [PR](https://github.com/henryouly/sentryshot/pull/12). This is just copying the same idea I like from OS-NVR. 3. A object detection client that talks to the [OpenVino model server](https://github.com/openvinotoolkit/model_server). See this [PR](https://github.com/henryouly/sentryshot/pull/1). This is my original motivation to move away from Frigate openvino detector and embrace a server based architecture for running object detection. I primarily use github for development, however when I tried to drop a PR I don't get much response, so I trace back here to see if you are interested in accepting any contributions and how. Appreicate your time and feedback on these improvement ideas.
Author
Collaborator
Copy link

btw, my master branch will be released to docker hub nightly, so to try out my implementation, one can just pull the docker image and then enable the plugin manually in sentryshot.toml.

btw, my master branch will be released to [docker hub](https://hub.docker.com/r/henryouly/sentryshot) nightly, so to try out my implementation, one can just pull the docker image and then enable the plugin manually in `sentryshot.toml`.
Owner
Copy link

Built your master branch from source and took a look at the frontend. I don't really think the design or style is objectively better, and I just want to mention that the js bundle is already 4x larger despite the recordings and settings page not being implemented. I wouldn't mind if you made a plugin that downloads and serves the bundle though.

Is there any particular reason you decided to use gRPC instead of the REST API for the model server?

Built your master branch from source and took a look at the frontend. I don't really think the design or style is objectively better, and I just want to mention that the js bundle is already 4x larger despite the recordings and settings page not being implemented. I wouldn't mind if you made a plugin that downloads and serves the bundle though. Is there any particular reason you decided to use gRPC instead of the REST API for the model server?
Author
Collaborator
Copy link

Thank you for doing the rigorous testing. Currently I'm just recreating the same UI (navigate sidebar + main panel for larger viewer), so nothing really changes. However, I am thinking to start adding new UI once I have the basic.

For example, one idea is to have a toggle button to switch between live view / timeline view. Using React, it's super easy to swap UI component on the fly without refreshing the page. My understanding is it's getting complex quickly to manually manupulate the DOM elements to do something similar. (It's possible, just prone to error)

The shadcn library is a toolkit of UI components that makes web UI development a lot easier.

  1. Sidebar can collaspe to icons (example). This allows small devices (phones) to still have a minimal sidebar.
  2. I use DataTable to construct the log UI, add a quick log search box, and move the filter of log level to the table header, which follows more closely to modern web development practices. Same can apply to other filters such as choosing log sources, but I still need to work on API (btw, I think the current way to inject global variables to window scope is not a recommended practice, so if the main app can implement a small json API to return the global variables it would be ideal, I currently just expose what the plugin has access but there are a few that it doesn't, such sa log sources)
  3. You can apply different color themes easily.
  4. They have a date picker component, fully customizable, that can go as simple or as fancy as possible.

So I'm excited not because what the new UI already does, but what it could do in the future.

Of course, these web frameworks comes with a size boost as you correctly pointed out, comparing to plain HTML / tpl framework. I think download size isn't a concern but website loading speed is. Vite / React stack is quite optimized for that, with the js compiler fully minify the script / gzip on load. The current size I've seen after gzip is ~150kB. Seems fair with a lot of UI improvements and the development velocity gain. Especially consider these are one-off cost, adding new pages isn't going to add more unless it introduces new components as dependency.

On the topic of gRPC instead of REST API. I did some quick benchmark when I chosen my logic in go (based on OS-NVR). gRPC is a few milliseconds faster per frame on my stress test (something like 43ms vs 46ms. In my use case, I have 4 camera with targeted 5fps, so I'll need the latency to be less than 50ms ideally to avoid dropping frames, so I decided to take the extra complexity in setting up gRPC. gRPC also provides stronger type enforcement as a bonus.

If you'd prefer a cleaner setup, one option might be to check in the generated protoc output rs files instead of source .proto files, or look into https://crates.io/crates/tensorflow-serving-client.

Thank you for doing the rigorous testing. Currently I'm just recreating the same UI (navigate sidebar + main panel for larger viewer), so nothing really changes. However, I am thinking to start adding new UI once I have the basic. For example, one idea is to have a toggle button to switch between live view / timeline view. Using React, it's super easy to swap UI component on the fly without refreshing the page. My understanding is it's getting complex quickly to manually manupulate the DOM elements to do something similar. (It's possible, just prone to error) The [shadcn](https://ui.shadcn.com/) library is a toolkit of UI components that makes web UI development a lot easier. 1. Sidebar can collaspe to icons ([example](https://ui.shadcn.com/docs/components/sidebar)). This allows small devices (phones) to still have a minimal sidebar. 2. I use [DataTable](https://ui.shadcn.com/docs/components/data-table) to construct the log UI, add a quick log search box, and move the filter of log level to the table header, which follows more closely to modern web development practices. Same can apply to other filters such as choosing log sources, but I still need to work on API (btw, I think the current way to inject global variables to `window` scope is not a recommended practice, so if the main app can implement a small json API to return the global variables it would be ideal, I currently just expose what the plugin has access but there are a few that it doesn't, such sa log sources) 3. You can apply [different color themes](https://ui.shadcn.com/themes#themes) easily. 4. They have a [date picker](https://ui.shadcn.com/docs/components/date-picker) component, fully customizable, that can go as simple or as fancy as possible. So I'm excited not because what the new UI already does, but what it could do in the future. Of course, these web frameworks comes with a size boost as you correctly pointed out, comparing to plain HTML / tpl framework. I think download size isn't a concern but website loading speed is. Vite / React stack is quite optimized for that, with the js compiler fully minify the script / gzip on load. The current size I've seen after gzip is ~150kB. Seems fair with a lot of UI improvements and the development velocity gain. Especially consider these are one-off cost, adding new pages isn't going to add more unless it introduces new components as dependency. On the topic of gRPC instead of REST API. I did some quick benchmark when I chosen my logic in go (based on OS-NVR). gRPC is a few milliseconds faster per frame on my stress test (something like 43ms vs 46ms. In my use case, I have 4 camera with targeted 5fps, so I'll need the latency to be less than 50ms ideally to avoid dropping frames, so I decided to take the extra complexity in setting up gRPC. gRPC also provides stronger type enforcement as a bonus. If you'd prefer a cleaner setup, one option might be to check in the generated protoc output rs files instead of source `.proto` files, or look into https://crates.io/crates/tensorflow-serving-client.
Owner
Copy link

Sidebar can collaspe to icons (example). This allows small devices (phones) to still have a minimal sidebar.

Phones in portrait mode don't have enough real estate for a permanent sidebar. Would be nice on desktop though.

I use DataTable to construct the log UI, add a quick log search box, and move the filter of log level to the table header

Your table header has a lot of horizontal overflow on mobile right now. I'm not sure if it's possible to make it fit nicely, but I like the idea.

btw, I think the current way to inject global variables to window scope is not a recommended practice

This is a good point. The original idea was to let plugins that modifies deeply nested JS have easier access to the data. But you're absolutely right that there's no reason for everything else to use globals.

You can apply different color themes easily

Easier than we already can?

They have a date picker component, fully customizable, that can go as simple or as fancy as possible.

you don't like my date picker 😢

Of course, these web frameworks comes with a size boost as you correctly pointed out, comparing to plain HTML / tpl framework.

No, compared to vanilla JS. The settings page is by far the largest, and combining it with all the other pages would barely make it any bigger.

I think download size isn't a concern but website loading speed is. Vite / React stack is quite optimized for that, with the js compiler fully minify the script / gzip on load.

How do you plan to let plugins patch the page if it's minified at build time? I'm aware that it's sub-optimal to not bundle all the JS files. I've considered pulling one of the JS bundlers written in Rust and running it after the plugins have been loaded, but it's low on the todo list.

If we were to abandon the idea of plugins patching JS and switch to a high-maintenance JS framework, why should we choose legacy technology with pure overhead? Both Svelte and Solid have shadcn forks. The Rust GUI frameworks that compile to WASM would be another option.

> Sidebar can collaspe to icons (example). This allows small devices (phones) to still have a minimal sidebar. Phones in portrait mode don't have enough real estate for a permanent sidebar. Would be nice on desktop though. > I use DataTable to construct the log UI, add a quick log search box, and move the filter of log level to the table header Your table header has a lot of horizontal overflow on mobile right now. I'm not sure if it's possible to make it fit nicely, but I like the idea. > btw, I think the current way to inject global variables to window scope is not a recommended practice This is a good point. The original idea was to let plugins that modifies deeply nested JS have easier access to the data. But you're absolutely right that there's no reason for everything else to use globals. > You can apply different color themes easily Easier than we already [can](https://codeberg.org/SentryShot/sentryshot/src/commit/bfc2217acda83b786f8093d156668516defc8b6e/web/assets/style/style.css#L278-L298)? > They have a date picker component, fully customizable, that can go as simple or as fancy as possible. you don't like my date picker 😢 > Of course, these web frameworks comes with a size boost as you correctly pointed out, comparing to plain HTML / tpl framework. No, compared to vanilla JS. The settings page is by far the largest, and combining it with all the other pages would barely make it any bigger. > I think download size isn't a concern but website loading speed is. Vite / React stack is quite optimized for that, with the js compiler fully minify the script / gzip on load. How do you plan to let plugins patch the page if it's minified at build time? I'm aware that it's sub-optimal to not bundle all the JS files. I've considered pulling one of the JS bundlers written in Rust and running it after the plugins have been loaded, but it's low on the todo list. If we were to abandon the idea of plugins patching JS and switch to a high-maintenance JS framework, why should we choose [legacy technology](https://infrequently.org/2024/11/if-not-react-then-what/) with [pure overhead](https://svelte.dev/blog/virtual-dom-is-pure-overhead)? Both Svelte and [Solid](https://dev.to/ryansolid/thinking-granular-how-is-solidjs-so-performant-4g37) have shadcn forks. The Rust GUI frameworks that compile to WASM would be another option.
Author
Collaborator
Copy link

@Curid wrote in #85 (comment):

Sidebar can collaspe to icons (example). This allows small devices (phones) to still have a minimal sidebar.

Phones in portrait mode don't have enough real estate for a permanent sidebar. Would be nice on desktop though.

I agree. but let's say the high customizable sidebar to adopt to device dimension is a "feature"

For a little real life example, I have a 10 inch cheap Amazon tablet that I put it on a wall mounted dock for all my security cameras. It's better than a phone, but still far less than a 4k monitor. Icon sidebar would fit that use case nicely.

What I could do is for this "medium tier", use the icon sidebar. For phone, sidebar will slide in from the left. For desktop, it's the full text + icon version. https://ui.shadcn.com/docs/components/sidebar#collapsible. This will be a lot of work with our own crafted sidebar component, but I think it's achieveable with the shadcn sidebar component.

I use DataTable to construct the log UI, add a quick log search box, and move the filter of log level to the table header

Your table header has a lot of horizontal overflow on mobile right now. I'm not sure if it's possible to make it fit nicely, but I like the idea.

Good point. Now I see why you put the filter in a secondary sidebar.

Yeah that's a trade-off for a table design. I certainly can hide some columns when on the phone, but that would need a different design how to apply filters. I'll need to put more thought on this.

btw, is it actually what you would do to check running logs on phone? I personally feel I would always have my laptop with me when I need to check logs / put in some search keywords. Typing on phone is painful 😆

btw, I think the current way to inject global variables to window scope is not a recommended practice

This is a good point. The original idea was to let plugins that modifies deeply nested JS have easier access to the data. But you're absolutely right that there's no reason for everything else to use globals.

You can apply different color themes easily

Easier than we already can?

These are nice. I think they follow similar CSS concepts. But shadcn's theming is a big community behind it. For example:
https://www.shadcn.studio/
https://www.reddit.com/r/tailwindcss/comments/1jvxkj4/i_created_a_shadcn_theme_generator/

It would just apply to all shadcn components out of the box with zero efforts.

They have a date picker component, fully customizable, that can go as simple or as fancy as possible.

you don't like my date picker 😢

Lol. Your date picker is fine, but I'm just thinking why to reinvent the wheel when something could just work?
https://daypicker.dev/
shadcn is a UI layer on top of it, just make it seamlessly unified to the style.

Of course, these web frameworks comes with a size boost as you correctly pointed out, comparing to plain HTML / tpl framework.

No, compared to vanilla JS. The settings page is by far the largest, and combining it with all the other pages would barely make it any bigger.

I haven't looked into settings yet and a little surprised to hear that setting page is the largest. They looks just like fields / onClick event hooks. What makes them complex?

I think download size isn't a concern but website loading speed is. Vite / React stack is quite optimized for that, with the js compiler fully minify the script / gzip on load.

How do you plan to let plugins patch the page if it's minified at build time? I'm aware that it's sub-optimal to not bundle all the JS files. I've considered pulling one of the JS bundlers written in Rust and running it after the plugins have been loaded, but it's low on the todo list.

If we were to abandon the idea of plugins patching JS and switch to a high-maintenance JS framework, why should we choose legacy technology with pure overhead? Both Svelte and Solid have shadcn forks. The Rust GUI frameworks that compile to WASM would be another option.

I was thinking the plugin could return a small json object with a special hook, e.g.
{div_id: 'sidebar_status_placeholder', element: '<html_tag>...'}

The main rust app should aggregate all such information in its main '/api/plugin_setup' API route, and the javascript frontend will have the information to do the DOM tree injection.

Nothing really fancy, but it should work.

Thanks for the info on Svelte and Solid. I often see those React hates on the web. As a React developer I'm generally happy with it comparing to writing vanilla JS due to choice of community packages and support. LLM also seems to understand react better than other framework. I'm open to check other better web frameworks though, just not a strength of mine to contribute to this project yet. 😉

@Curid wrote in https://codeberg.org/SentryShot/sentryshot/issues/85#issuecomment-7025141: > > Sidebar can collaspe to icons (example). This allows small devices (phones) to still have a minimal sidebar. > > Phones in portrait mode don't have enough real estate for a permanent sidebar. Would be nice on desktop though. I agree. but let's say the high customizable sidebar to adopt to device dimension is a "feature" For a little real life example, I have a 10 inch cheap Amazon tablet that I put it on a wall mounted dock for all my security cameras. It's better than a phone, but still far less than a 4k monitor. Icon sidebar would fit that use case nicely. What I could do is for this "medium tier", use the icon sidebar. For phone, sidebar will slide in from the left. For desktop, it's the full text + icon version. https://ui.shadcn.com/docs/components/sidebar#collapsible. This will be a lot of work with our own crafted sidebar component, but I think it's achieveable with the shadcn sidebar component. > > > I use DataTable to construct the log UI, add a quick log search box, and move the filter of log level to the table header > > Your table header has a lot of horizontal overflow on mobile right now. I'm not sure if it's possible to make it fit nicely, but I like the idea. Good point. Now I see why you put the filter in a secondary sidebar. Yeah that's a trade-off for a table design. I certainly can hide some columns when on the phone, but that would need a different design how to apply filters. I'll need to put more thought on this. btw, is it actually what you would do to check running logs on phone? I personally feel I would always have my laptop with me when I need to check logs / put in some search keywords. Typing on phone is painful 😆 > > > btw, I think the current way to inject global variables to window scope is not a recommended practice > > This is a good point. The original idea was to let plugins that modifies deeply nested JS have easier access to the data. But you're absolutely right that there's no reason for everything else to use globals. > > > You can apply different color themes easily > > Easier than we already [can](https://codeberg.org/SentryShot/sentryshot/src/commit/bfc2217acda83b786f8093d156668516defc8b6e/web/assets/style/style.css#L278-L298)? These are nice. I think they follow similar CSS concepts. But shadcn's theming is a big community behind it. For example: https://www.shadcn.studio/ https://www.reddit.com/r/tailwindcss/comments/1jvxkj4/i_created_a_shadcn_theme_generator/ It would just apply to all shadcn components out of the box with zero efforts. > > > They have a date picker component, fully customizable, that can go as simple or as fancy as possible. > > you don't like my date picker :cry: Lol. Your date picker is fine, but I'm just thinking why to reinvent the wheel when something could just work? https://daypicker.dev/ shadcn is a UI layer on top of it, just make it seamlessly unified to the style. > > > Of course, these web frameworks comes with a size boost as you correctly pointed out, comparing to plain HTML / tpl framework. > > No, compared to vanilla JS. The settings page is by far the largest, and combining it with all the other pages would barely make it any bigger. I haven't looked into settings yet and a little surprised to hear that setting page is the largest. They looks just like fields / onClick event hooks. What makes them complex? > > > I think download size isn't a concern but website loading speed is. Vite / React stack is quite optimized for that, with the js compiler fully minify the script / gzip on load. > > How do you plan to let plugins patch the page if it's minified at build time? I'm aware that it's sub-optimal to not bundle all the JS files. I've considered pulling one of the JS bundlers written in Rust and running it after the plugins have been loaded, but it's low on the todo list. > > If we were to abandon the idea of plugins patching JS and switch to a high-maintenance JS framework, why should we choose [legacy technology](https://infrequently.org/2024/11/if-not-react-then-what/) with [pure overhead](https://svelte.dev/blog/virtual-dom-is-pure-overhead)? Both Svelte and [Solid](https://dev.to/ryansolid/thinking-granular-how-is-solidjs-so-performant-4g37) have shadcn forks. The Rust GUI frameworks that compile to WASM would be another option. I was thinking the plugin could return a small json object with a special hook, e.g. `{div_id: 'sidebar_status_placeholder', element: '<html_tag>...'}` The main rust app should aggregate all such information in its main '/api/plugin_setup' API route, and the javascript frontend will have the information to do the DOM tree injection. Nothing really fancy, but it should work. Thanks for the info on Svelte and Solid. I often see those React hates on the web. As a React developer I'm generally happy with it comparing to writing vanilla JS due to choice of community packages and support. LLM also seems to understand react better than other framework. I'm open to check other better web frameworks though, just not a strength of mine to contribute to this project yet. 😉
Author
Collaborator
Copy link

Just quickly checked out Svelte and Solid JS. Solid JS looks like a "solid" choice. The lack of community packages probably isn't that matter in this project IMO as long as shadcn / tanstack has the support already. I will spend some time to play with it to get familiar.

Just quickly checked out Svelte and Solid JS. Solid JS looks like a "solid" choice. The lack of community packages probably isn't that matter in this project IMO as long as shadcn / tanstack has the support already. I will spend some time to play with it to get familiar.
Owner
Copy link

This will be a lot of work with our own crafted sidebar component, but I think it's achieveable with the shadcn sidebar component.

I gave it a try.

btw, is it actually what you would do to check running logs on phone?

I do check logs on the phone occasionally.

I haven't looked into settings yet and a little surprised to hear that setting page is the largest. They looks just like fields / onClick event hooks. What makes them complex?

I forgot that it doesn't pull the player from the recordings page. The motion and object detection plugins each have a thousand lines. They also pull the live feed and polygon editor.

> This will be a lot of work with our own crafted sidebar component, but I think it's achieveable with the shadcn sidebar component. I gave it a [try](https://codeberg.org/SentryShot/sentryshot/commit/827d33dd9c870b2432ca37f8dba885e57940b5eb). > btw, is it actually what you would do to check running logs on phone? I do check logs on the phone occasionally. > I haven't looked into settings yet and a little surprised to hear that setting page is the largest. They looks just like fields / onClick event hooks. What makes them complex? I forgot that it doesn't pull the player from the recordings page. The motion and object detection plugins each have a thousand lines. They also pull the live feed and polygon editor.
Author
Collaborator
Copy link

I gave it a try.

That's cool. I'm consistently impressed by how far CSS can do without JS.

Just quickly checked out Svelte and Solid JS. Solid JS looks like a "solid" choice. The lack of community packages probably isn't that matter in this project IMO as long as shadcn / tanstack has the support already. I will spend some time to play with it to get familiar.

In an effort to migrate everything to SolidJS: https://github.com/henryouly/sentryshot/pull/18. Feel free to check out and build the branch and see whether anything you'd like to adopt. I finally added a theme switcher button. 😆

> > I gave it a [try](https://codeberg.org/SentryShot/sentryshot/commit/827d33dd9c870b2432ca37f8dba885e57940b5eb). > That's cool. I'm consistently impressed by how far CSS can do without JS. > Just quickly checked out Svelte and Solid JS. Solid JS looks like a "solid" choice. The lack of community packages probably isn't that matter in this project IMO as long as shadcn / tanstack has the support already. I will spend some time to play with it to get familiar. In an effort to migrate everything to SolidJS: https://github.com/henryouly/sentryshot/pull/18. Feel free to check out and build the branch and see whether anything you'd like to adopt. I finally added a theme switcher button. 😆
Sign in to join this conversation.
No Branch/Tag specified
master
sub_rec
recdb_v2
vino
sidebar
temp
range-streamer
logdb
v0.3.11
v0.3.10
v0.3.9
v0.3.8
v0.3.7
v0.3.6
v0.3.5
v0.3.4
v0.3.3
v0.3.2
v0.3.1
v0.3.0
v0.2.26
v0.2.25
v0.2.24
v0.2.23
v0.2.22
v0.2.21
v0.2.20
v0.2.19
v0.2.18
v0.2.17
v0.2.16
v0.2.15
v0.2.14
v0.2.13
v0.2.12
v0.2.11
v0.2.10
v0.2.9
v0.2.8
v0.2.7
v0.2.6
v0.2.5
v0.2.4
v0.2.3
v0.2.2
v0.2.1
v0.2.0
v0.1.3
v0.1.2
v0.1.1
v0.1.0
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
SentryShot/sentryshot#85
Reference in a new issue
SentryShot/sentryshot
No description provided.
Delete branch "%!s()"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?