import 'package:flutter/material.dart'; import 'package:moonwell_launcher/app/design_system/mw_authentication.dart'; import 'package:moonwell_launcher/app/design_system/mw_launcher_components.dart'; import 'package:moonwell_launcher/app/design_system/mw_shells.dart'; import 'package:widgetbook/widgetbook.dart'; import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook; VoidCallback _windowCallback(String action) { return () => debugPrint('Window action requested: $action'); } @widgetbook.UseCase(name: 'default', type: MwBrandMark, path: '[Foundations]') Widget buildMwBrandMarkUseCase(BuildContext context) { return MwBrandMark( width: context.knobs.double.slider( label: 'width', initialValue: 220, min: 96, max: 360, divisions: 33, ), ); } @widgetbook.UseCase( name: 'default', type: MwArtworkBackground, path: '[Foundations]', ) Widget buildMwArtworkBackgroundUseCase(BuildContext context) { return const MwArtworkBackground( assetPackage: 'moonwell_launcher', child: Center(child: Text('Safe content area')), ); } @widgetbook.UseCase(name: 'default', type: MwLoginShell, path: '[Compositions]') Widget buildMwLoginShellUseCase(BuildContext context) { return MwLoginShell( assetPackage: 'moonwell_launcher', form: MwAuthenticationForm( usernameController: TextEditingController(), passwordController: TextEditingController(), onSubmit: () => debugPrint('Login submitted'), ), onDrag: _windowCallback('drag'), onDoubleTap: _windowCallback('double_tap'), onMinimize: _windowCallback('minimize'), onMaximizeRestore: _windowCallback('maximize_restore'), onClose: _windowCallback('close'), ); } @widgetbook.UseCase( name: 'api_error', type: MwLoginShell, path: '[Compositions]', ) Widget buildMwLoginShellApiErrorUseCase(BuildContext context) { return MwLoginShell( assetPackage: 'moonwell_launcher', form: MwAuthenticationForm( usernameController: TextEditingController(text: 'moonwalker'), passwordController: TextEditingController(), error: context.knobs.string( label: 'error', initialValue: 'Неверный логин или пароль.', ), onSubmit: () => debugPrint('Login submitted after API error'), ), onDrag: _windowCallback('drag'), onDoubleTap: _windowCallback('double_tap'), onMinimize: _windowCallback('minimize'), onMaximizeRestore: _windowCallback('maximize_restore'), onClose: _windowCallback('close'), ); } @widgetbook.UseCase( name: 'restored_session_loading', type: MwLoginShell, path: '[Compositions]', ) Widget buildMwLoginShellRestoredSessionLoadingUseCase(BuildContext context) { return MwLoginShell( assetPackage: 'moonwell_launcher', form: const Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ CircularProgressIndicator(), SizedBox(height: 16), Text('Восстанавливаем защищённую сессию…'), ], ), ), onDrag: _windowCallback('drag'), onDoubleTap: _windowCallback('double_tap'), onMinimize: _windowCallback('minimize'), onMaximizeRestore: _windowCallback('maximize_restore'), onClose: _windowCallback('close'), ); } MwLauncherShell _launcherShell({ required MwNewsListState newsState, required MwSyncPresentation syncState, required String status, double? progress, String? error, }) { return MwLauncherShell( assetPackage: 'moonwell_launcher', news: MwNewsList( state: newsState, error: newsState == MwNewsListState.failure ? 'Сервер новостей временно недоступен.' : null, items: newsState == MwNewsListState.populated ? List.generate( 8, (index) => MwNewsItemData( title: 'Новость ${index + 1}', body: 'События игрового мира и важные обновления MoonWell.', createdAt: DateTime(2026, 6, 22 - index), ), ) : const [], onRetry: () => debugPrint('News reload requested'), ), syncActions: MwSyncActionArea( state: syncState, status: status, progress: progress, currentPath: syncState == MwSyncPresentation.downloading ? r'Data\ruRU\patch-ruRU.MPQ' : null, error: error, onPrimary: () => debugPrint('Primary sync action requested'), onPause: syncState == MwSyncPresentation.downloading ? () => debugPrint('Sync pause requested') : null, ), statusBar: const MwLauncherStatusBar( status: 'MoonWell Launcher · локальная установка', fileCount: '124/480', buildHash: 'a93fd1c2', ), account: MwAccountAffordance( onSettings: () => debugPrint('Settings requested'), onLogout: () => debugPrint('Logout requested'), ), onDrag: _windowCallback('drag'), onDoubleTap: _windowCallback('double_tap'), onMinimize: _windowCallback('minimize'), onMaximizeRestore: _windowCallback('maximize_restore'), onClose: _windowCallback('close'), ); } @widgetbook.UseCase( name: 'ready', type: MwLauncherShell, path: '[Compositions]', ) Widget buildMwLauncherShellReadyUseCase(BuildContext context) { return _launcherShell( newsState: MwNewsListState.populated, syncState: MwSyncPresentation.ready, status: 'Клиент готов к запуску.', ); } @widgetbook.UseCase( name: 'downloading', type: MwLauncherShell, path: '[Compositions]', ) Widget buildMwLauncherShellDownloadingUseCase(BuildContext context) { return _launcherShell( newsState: MwNewsListState.populated, syncState: MwSyncPresentation.downloading, status: 'Загружаем обновление клиента…', progress: context.knobs.double.slider( label: 'progress', initialValue: .46, min: 0, max: 1, divisions: 100, ), ); } @widgetbook.UseCase( name: 'paused', type: MwLauncherShell, path: '[Compositions]', ) Widget buildMwLauncherShellPausedUseCase(BuildContext context) { return _launcherShell( newsState: MwNewsListState.populated, syncState: MwSyncPresentation.paused, status: 'Обновление приостановлено.', progress: .46, ); } @widgetbook.UseCase( name: 'verifying', type: MwLauncherShell, path: '[Compositions]', ) Widget buildMwLauncherShellVerifyingUseCase(BuildContext context) { return _launcherShell( newsState: MwNewsListState.populated, syncState: MwSyncPresentation.verifying, status: 'Проверяем целостность установки…', ); } @widgetbook.UseCase( name: 'failure', type: MwLauncherShell, path: '[Compositions]', ) Widget buildMwLauncherShellFailureUseCase(BuildContext context) { return _launcherShell( newsState: MwNewsListState.failure, syncState: MwSyncPresentation.failure, status: 'Не удалось завершить обновление.', error: 'Проверка SHA-256 не пройдена.', ); } @widgetbook.UseCase( name: 'empty_news', type: MwLauncherShell, path: '[Compositions]', ) Widget buildMwLauncherShellEmptyNewsUseCase(BuildContext context) { return _launcherShell( newsState: MwNewsListState.empty, syncState: MwSyncPresentation.ready, status: 'Клиент готов к запуску.', ); }