Skip to content

feat(community): community fixes #27

Merged
keyldev merged 12 commits into
mainfrom
feat/phase-19-community
Jun 21, 2026
Merged

feat(community): community fixes #27
keyldev merged 12 commits into
mainfrom
feat/phase-19-community

Conversation

@keyldev

@keyldev keyldev commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

19.1 Tabbed layouts

  • Named layouts as tabs over the grid: create / rename / delete / drag-reorder.
  • Each layout keeps its own cameras and grid size, persisted across restarts (migration 012, LayoutTiles many-to-many).
  • Per-layout camera picker dialog (tab-strip button) with search + live count — the discoverable way to populate a tab.

19.2 Config export / import

  • One-JSON backup of cameras + layouts with an import preview. Passwords are never written to the file.

19.3 Notifications

  • Coordinator policy: per-camera cooldown, quiet hours, per-type toggles.
  • Android notification channel + a custom Telegram-style desktop corner toast (stacks, auto-dismiss). Settings panel + "Send test notification".

Fixes & polish

  • Grid: tap-vs-drag — tapping a tile button no longer opens the camera; tab switching / tile-open work again.
  • Snapshot: "no frame yet" returns empty instead of throwing (no exception flood / hang on HD grab).
  • Talk: no exception when a camera has no backchannel; friendly hint + mic button hidden.
  • App version derived from the git tag (About no longer shows 1.0.0.0).
  • Lightweight issue-reporter: "Report a problem" opens a pre-filled GitHub issue + "Open logs".

Deferred (by decision)

  • 19.6 granular RBAC — low value without a server/cloud; documented model-threat note.
  • 19.4 white-label branding.json.
  • iOS notification sink (desktop + Android only for now).

Related

Type

  • Bug fix
  • Feature
  • Refactor / cleanup
  • Docs / CI
  • Other:

Checklist

  • Builds with 0 warnings (TreatWarningsAsErrors=true).
  • Tests pass (dotnet test); new Core logic has unit tests.
  • No layering violation — App references Core only (Infrastructure / Video / Devices wired via DI in a head).
  • Scope stays within one phase (didn't pull work from a later phase's "Не входит").
  • README / docs updated if public commands, options, or setup changed.

Platforms tested

  • Windows
  • Linux
  • macOS
  • Android
  • iOS
  • CI build only

Screenshots / notes

keyldev added 12 commits June 21, 2026 03:42
@
feat(layouts): tabbed-layout data model + repo + migration (phase 19.1)

- GridLayout/LayoutId entities, ILayoutRepository + SqliteLayoutRepository
- migration 012: Layouts + LayoutTiles, seed Default layout from IncludedInGrid
- GetTiles joins Cameras so deleted cameras leave no ghost tiles
- repo tests green
@
@
feat(layouts): tab bar + grid reads active layout (phase 19.1)

- GridPageViewModel: Layouts/ActiveLayout, switch/add/rename/delete tabs, grid size per layout
- grid tiles come from the active layout; tile reorder persists to it
- active layout persisted in UserSettings; library "include in grid" targets the active layout
- tab strip UI with active-tab highlight; tests green
@
@
feat(layouts): tab drag-reorder + library checkbox per active layout (phase 19.1)

- drag tabs to reorder; persists SortOrder via ILayoutRepository.ReorderAsync
- library "in grid" checkbox now reflects active-layout membership, not the global flag
- GetActiveLayoutCameraIdsAsync seeds the checkbox without triggering a persist
@
@
feat(backup): config export/import service (phase 19.2)

- IConfigBackupService + SqliteConfigBackupService: export to JSON, preview, import
- cameras upsert by GUID, layouts appended with tiles; schemaVersion gated
- no secrets exported (entity holds none); groups/settings deferred
- round-trip + preview + schema-reject tests green
@
@
feat(backup): export/import UI in Settings (phase 19.2)

- Settings → Backup & restore: Export/Import buttons, file pick, import preview confirm
- ConfigImportedMessage reloads grid + library after import (no restart)
- settings export still deferred; cameras + layouts only
@
@
feat(notifications): coordinator policy engine + settings (phase 19.3)

- INotificationService + NotificationCoordinator: per-kind toggles, per-camera cooldown, quiet hours over the event stream
- ShouldNotify/InQuietHours pure + unit-tested (13 tests)
- settings + DI wiring; eager Start() per head; Null sink until native delivery lands
@
@
feat(notifications): settings UI + Android sink (phase 19.3)

- Settings → Advanced: enable, motion/detection toggles, cooldown, quiet hours
- AndroidNotificationService (NotificationManager channel); POST_NOTIFICATIONS requested at startup
- desktop + iOS sinks still pending; Android delivers, others no-op via Null sink
@
- add a camera-picker dialog per layout, opened from the tab strip; toggling adds/removes tiles live against the layout
- start tile/tab drag only past a threshold so a plain click switches tabs and opens cameras again
- ignore tile taps that originate on the snapshot/listen buttons
- SnapshotAsync returns an empty array while the stream warms up instead of throwing
- stops the InvalidOperationException flood (and the perceived hang) when grabbing an HD snapshot off a freshly opened mainstream
- document the contract on IVideoSession; FfmpegPlaybackSession matches
- SetVersionFromGit runs `git describe --tags` and feeds InformationalVersion + numeric AssemblyVersion
- fallback Version 0.1.9 for tagless/tarball builds so it's never 1.0.0.0
- suppress the SDK "+commit" suffix so About shows a clean tag
- desktop notification sink: borderless Telegram-style corner toast, stacks up to 4, auto-dismiss + click-to-close (phase 19.3)
- "Send test notification" button to preview it from settings
- "Report a problem" + "Open logs" buttons opening the repo issues page with version/OS prefilled (phase 19.5)
- About now reads the git-tag InformationalVersion
- OpenAsync returns null instead of throwing NotSupportedException when the camera advertises no backchannel track
- StartAsync reports Unsupported; the page shows a friendly "no two-way audio" hint and hides the mic button
- stops the first-chance exception flood on pressing the mic
@keyldev keyldev merged commit 51c99e6 into main Jun 21, 2026
5 checks passed
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.

1 participant