"""主页装配视图;只创建控件并连接控制器回调。"""
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')