def motion_portraits_content()

in experiments/veo-app/pages/portraits.py [0:0]


def motion_portraits_content(app_state: me.state):
    """Motion portraits Mesop Page"""

    state = me.state(PageState)

    with page_scaffold():  # pylint: disable=not-context-manager
        with page_frame():  # pylint: disable=not-context-manager
            header("Motion Portraits", "portrait")

            with me.box(
                style=me.Style(
                    display="flex",
                    flex_direction="row",
                    gap=20,
                )
            ):
                # Uploaded image
                with me.box(style=_BOX_STYLE_CENTER_DISTRIBUTED):
                    me.text("Portrait")

                    if state.reference_image_uri:
                        output_url = state.reference_image_uri
                        print(f"Displaying reference image: {output_url}")
                        me.image(
                            src=output_url,
                            style=me.Style(
                                height=200, border_radius=12, object_fit="contain"
                            ),
                            key=str(state.reference_image_file_key),
                        )
                    else:
                        # me.image(src=None, style=me.Style(height=200))
                        me.box(
                            style=me.Style(
                                height=200,
                                width=200,
                                display="flex",
                                align_items="center",
                                justify_content="center",
                                background=me.theme_var(
                                    "sys-color-surface-container-highest"
                                ),
                                border_radius=12,
                                border=me.Border.all(
                                    me.BorderSide(
                                        color=me.theme_var("sys-color-outline")
                                    )
                                ),
                            )
                        )

                    # uploader controls
                    with me.box(
                        style=me.Style(
                            display="flex",
                            flex_direction="row",
                            gap=10,
                            margin=me.Margin(top=10),
                        )
                    ):
                        # me.button(label="Upload", type="flat", disabled=True)
                        me.uploader(
                            label="Upload",
                            accepted_file_types=["image/jpeg", "image/png"],
                            on_upload=on_click_upload,
                            type="flat",
                            color="primary",
                            style=me.Style(font_weight="bold"),
                        )
                        me.button(
                            label="Clear",
                            on_click=on_click_clear_reference_image,
                        )

                with me.box(
                    style=me.Style(
                        display="flex",
                        flex_direction="column",
                        gap=15,
                        padding=me.Padding.all(12),
                        flex_grow=1,
                    )
                ):
                    me.text(
                        "Video options",
                        style=me.Style(font_size="1.1em", font_weight="bold"),
                    )
                    with me.box(
                        style=me.Style(display="flex", flex_direction="row", gap=5)
                    ):
                        me.select(
                            label="aspect",
                            appearance="outline",
                            options=[
                                me.SelectOption(label="16:9 widescreen", value="16:9"),
                                me.SelectOption(label="9:16 portrait", value="9:16"),
                            ],
                            value=state.aspect_ratio,
                            on_selection_change=on_selection_change_aspect,
                        )
                        me.select(
                            label="length",
                            options=[
                                me.SelectOption(label="5 seconds", value="5"),
                                me.SelectOption(label="6 seconds", value="6"),
                                me.SelectOption(label="7 seconds", value="7"),
                                me.SelectOption(label="8 seconds", value="8"),
                            ],
                            appearance="outline",
                            style=me.Style(),
                            value=f"{state.video_length}",
                            on_selection_change=on_selection_change_length,
                        )
                        me.checkbox(
                            label="auto-enhance prompt",
                            checked=state.auto_enhance_prompt,
                            on_change=on_change_auto_enhance_prompt,
                        )

                    me.text(
                        "Style options",
                        style=me.Style(font_size="1.1em", font_weight="bold"),
                    )
                    with me.box(
                        style=me.Style(display="flex", flex_direction="row", gap=5)
                    ):
                        for option in modifier_options:
                            is_selected = option["key"] in state.modifier_array

                            # Use me.content_button. We'll place an icon and text inside.
                            with me.content_button(
                                key=f"mod_btn_{option['key']}",
                                # key=option["key"],  # Crucial for identifying the button in the event handler
                                on_click=on_modifier_click,
                                # Optional: Add some styling to make the buttons look more like selectable items
                                style=me.Style(
                                    padding=me.Padding.symmetric(
                                        vertical=8, horizontal=16
                                    ),
                                    border=me.Border.all(
                                        me.BorderSide(
                                            width=1,
                                            color=me.theme_var("sys-color-primary")
                                            if is_selected
                                            else me.theme_var("sys-color-outline"),
                                        )
                                    ),
                                    background=me.theme_var(
                                        "sys-color-primary-container"
                                    )
                                    if is_selected
                                    else "transparent",
                                    border_radius=20,  # Makes it more chip-like
                                ),
                            ):
                                # Use a horizontal box to arrange icon and text
                                with me.box(
                                    style=me.Style(
                                        display="flex",
                                        flex_direction="row",
                                        align_items="center",
                                        gap=6,  # Space between icon and text
                                    )
                                ):
                                    if is_selected:
                                        # Display a check icon when selected
                                        me.icon(
                                            "check",
                                            style=me.Style(
                                                color=me.theme_var(
                                                    "sys-color-on-primary-container"
                                                )
                                                if is_selected
                                                else me.theme_var(
                                                    "sys-color-on-surface"
                                                )
                                            ),
                                        )
                                    # else:
                                    # Optionally, a placeholder or different icon for unselected state
                                    # For now, no icon when not selected.
                                    # me.icon("add_circle_outline", style=me.Style(color=me.theme_var("sys-color-on-surface-variant")))

                                    # The label for the modifier
                                    me.text(
                                        option["label"],
                                        style=me.Style(
                                            color=me.theme_var(
                                                "sys-color-on-primary-container"
                                            )
                                            if is_selected
                                            else me.theme_var("sys-color-on-surface")
                                        ),
                                    )
                    if state.modifier_array:
                        me.text(
                            f"Active Modifiers: {', '.join(state.modifier_array)}",
                            style=me.Style(margin=me.Margin(top=10), font_size="0.9em"),
                        )

            with me.box(
                style=me.Style(
                    padding=me.Padding.all(16),
                    justify_content="center",
                    display="flex",
                )
            ):
                with me.content_button(
                    on_click=on_click_motion_portraits,
                    type="flat",
                    key="generate_motion_portrait_button",
                    disabled=state.is_loading or not state.reference_image_uri,
                ):
                    with me.box(
                        style=me.Style(
                            display="flex",
                            flex_direction="row",
                            align_items="center",
                            gap=2,
                        )
                    ):
                        if state.is_loading:
                            me.progress_spinner(diameter=20, stroke_width=3)
                            me.text("Generating...")
                        else:
                            me.icon("portrait")
                            me.text("Create Moving Portrait")

                me.box(style=me.Style(height=24))

            # Generated video and prompt section
            if (
                state.is_loading
                or state.result_video
                or state.error_message
                or state.generated_scene_direction
            ):
                with me.box(style=_BOX_STYLE_CENTER_DISTRIBUTED_MARGIN):
                    if state.is_loading:
                        me.text(
                            "Generating your moving portrait, please wait...",
                            style=me.Style(
                                font_size="1.1em", margin=me.Margin(bottom=10)
                            ),
                        )
                        me.progress_spinner(diameter=40)
                    elif state.result_video:
                        me.text(
                            "Motion Portrait",
                            style=me.Style(
                                font_size="1.2em",
                                font_weight="bold",
                                margin=me.Margin(bottom=10),
                            ),
                        )
                        video_url = state.result_video.replace(
                            "gs://", "https://storage.mtls.cloud.google.com/"
                        )
                        print(f"Displaying result video: {video_url}")
                        me.video(
                            src=video_url,
                            style=me.Style(
                                width="100%",
                                max_width="480px"
                                if state.aspect_ratio == "9:16"
                                else "720px",
                                border_radius=12,
                                margin=me.Margin(top=8),
                            ),
                            # autoplay=True,
                            # controls=True
                        )
                        if state.timing:
                            me.text(
                                state.timing,
                                style=me.Style(
                                    margin=me.Margin(top=10), font_size="0.9em"
                                ),
                            )

                    # Display generated scene direction
                    if state.generated_scene_direction and not state.is_loading:
                        me.text(
                            "Generated Scene Direction:",
                            style=me.Style(
                                font_size="1.1em",
                                font_weight="bold",
                                margin=me.Margin(top=15, bottom=5),
                            ),
                        )
                        me.text(
                            state.generated_scene_direction,
                            style=me.Style(
                                white_space="pre-wrap",
                                font_family="monospace",
                                background=me.theme_var("sys-color-surface-container"),
                                padding=me.Padding.all(10),
                                border_radius=8,
                            ),
                        )

                    # Display error message if any
                    if (
                        state.show_error_dialog
                        and state.error_message
                        and not state.is_loading
                    ):
                        me.text(
                            "Error",
                            style=me.Style(
                                font_size="1.2em",
                                font_weight="bold",
                                color="red",
                                margin=me.Margin(top=15, bottom=5),
                            ),
                        )
                        me.text(
                            state.error_message,
                            style=me.Style(color="red", white_space="pre-wrap"),
                        )