Widget system Phase 4a: widget CRUD + grid placement UI
Adds the actual "Android home screen" placement experience: a new Layout tab with a pointer-driven canvas for dragging/resizing widgets and adding new ones from a type picker. Backed by a new routers/api_widgets.py (create/move/delete), which re-validates bounds, minimum footprint, and no-overlap server-side regardless of what the client already checked. A widget added without an explicit position lands in the first open space that fits it (grid.find_open_rect), so users don't have to hunt for empty space themselves. Also fixes a real latent bug this surfaced: changing a frame's orientation swaps the widget grid's long/short axis, which left existing widget placements out of bounds on the new grid with no render-time safeguard. Orientation changes now reset the layout to a single full-panel widget (keeping the first widget's type, dropping the rest), with a client-side confirm before it happens.
This commit is contained in:
@@ -60,6 +60,11 @@ def frame_photos_page(frame_id: int, request: Request, db: Session = Depends(get
|
||||
)
|
||||
|
||||
|
||||
@router.get("/frames/{frame_id}/layout", response_class=HTMLResponse)
|
||||
def frame_layout_page(frame_id: int, request: Request, db: Session = Depends(get_db)):
|
||||
return _frame_page(request, db, frame_id, "frame_layout.html", "layout")
|
||||
|
||||
|
||||
def _user_available_calendars(user: User) -> list[dict]:
|
||||
"""This user's full set of calendars available to add to any frame:
|
||||
the single ICS subscription (if set) plus every CalDAV calendar last
|
||||
|
||||
Reference in New Issue
Block a user