"""Jellyfin library browser UI pieces.""" from __future__ import annotations from typing import Any import pandas as pd import streamlit as st from media_library_viewer.domain.media import media_streams from media_library_viewer.utils import ticks_to_minutes def show_item_card(client, item: dict[str, Any]) -> None: """Render a poster card in the Jellyfin library grid.""" try: st.image(client.image_url(item["Id"]), use_container_width=True) except Exception: st.caption("No image") st.markdown(f"**{item.get('Name', 'Untitled')}**") meta = [item.get("Type", "")] if item.get("ProductionYear"): meta.append(str(item["ProductionYear"])) minutes = ticks_to_minutes(item.get("RunTimeTicks")) if minutes: meta.append(f"{minutes} min") st.caption(" - ".join([m for m in meta if m])) if st.button("Open", key=f"open-{item['Id']}"): st.session_state["selected_item_id"] = item["Id"] def show_item_detail(client, item: dict[str, Any]) -> None: """Render detailed Jellyfin item metadata for the selected poster card.""" st.header(item.get("Name", "Untitled")) left, right = st.columns([1, 2]) with left: st.image(client.image_url(item["Id"]), use_container_width=True) with right: st.write(item.get("Overview") or "No overview.") st.write("**Path:**", item.get("Path") or "Not exposed by Jellyfin") st.write("**Genres:**", ", ".join(item.get("Genres", [])) or "-") st.write("**Rating:**", item.get("CommunityRating") or "-") st.write("**Official rating:**", item.get("OfficialRating") or "-") streams = media_streams(item) if streams: st.subheader("Jellyfin media streams") st.dataframe(pd.DataFrame(streams), use_container_width=True) with st.expander("Raw Jellyfin JSON"): st.json(item)