"""主页装配视图;只创建控件并连接控制器回调。""" from typing import Any from nicegui import ui def build_page(controller: Any, *, motion_style: str, sponsor_notice_text: str) -> None: controller.client = ui.context.client ui.colors(primary='#4A90E2', secondary='#5E6C84', accent='#FF6B6B') ui.add_head_html(motion_style) ui.add_head_html(''' ''') controller._build_sponsor_dialog() controller._build_help_dialog() with ui.column().classes('w-full max-w-7xl mx-auto p-4 gap-3'): # ── 1. 搜索主路径 ── controller._build_search_card() # ── 2. 紧凑版本公告 ── controller._build_release_announcement() # ── 3. 工作区工具和已选标签(无需搜索即可恢复)── controller.workspace_card = ui.card().classes( 'w-full p-0 gap-0 overflow-hidden section-surface' ) with controller.workspace_card: controller._build_workspace_toolbar() controller._build_selection_bar() # ── 4~5. 搜索结果区域(搜索前隐藏)── controller.results_section = ui.column().classes('w-full gap-4').props( 'id="danbooru-results-section"' ) controller.results_section.set_visibility(False) with controller.results_section: # ── 4. 查询理解:来源筛选 + 概念覆盖 ── controller.coverage_container = ui.column().classes('w-full gap-2').props( 'id="danbooru-coverage-section"' ) # ── 5. 两栏结果 ── controller._build_results_columns() # ── 6. 页脚 ── with ui.element('div').classes('w-full text-center py-4 mt-2'): controller.search_count_label = ui.html('正在加载数据...').classes('text-xs text-gray-400') controller._update_footer_text() ui.button(sponsor_notice_text, on_click=controller.sponsor_dialog.open) \ .props('flat dense no-caps color=grey-6') \ .classes('text-xs mt-1') def render_service_status(controller: Any, status: dict) -> None: """根据控制器整理好的服务快照更新状态区域。""" controller.service_status_container.clear() with controller.service_status_container: if not status['ready']: with ui.row().classes( 'w-full items-center gap-2 service-state-panel loading' ): ui.spinner(size='18px', color='primary') ui.label('引擎初始化中,请稍候…约需 5~10 分钟').classes('font-medium') return with ui.row().classes( f'w-full items-center gap-2 service-state-panel ' f'{"busy" if status["busy"] else "ready"}' ): ui.icon( 'schedule' if status['busy'] else 'check_circle', size='18px', color='warning' if status['busy'] else 'positive', ) parts = [ '服务繁忙' if status['busy'] else '服务可用', f'{status["online_sessions"]} 个在线页面', ] if status['active'] > 0: parts.append(f'正在处理 {status["active"]} 个任务') if status['waiting'] > 0: parts.append(f'等待 {status["waiting"]} 个') ui.label(' · '.join(parts)).classes('font-medium') def build_release_announcement(controller: Any) -> None: controller.announcement_banner = ui.element('div').classes( 'w-full release-notice section-surface px-3 py-2' ) with controller.announcement_banner: with ui.row().classes('w-full items-center justify-between gap-2'): with ui.row().classes('items-center gap-2 min-w-0 flex-wrap'): ui.icon('new_releases', size='18px', color='primary') ui.label( '新版已加入标签工作区、Prompt 导入、Alias 纠错和分渠道统计。' ).classes('text-sm text-slate-700') ui.button( '查看详情', on_click=controller.help_dialog.open, ).props('flat dense no-caps color=primary').classes('text-xs') ui.button( icon='close', on_click=controller._dismiss_release_announcement, ).props('flat dense round color=grey-6')