WIP: feat(ui): Migrate to new UI implementation
This commit is contained in:
@@ -0,0 +1,230 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:moonwell_launcher/app/design_system/mw_launcher_components.dart';
|
||||
import 'package:moonwell_launcher/core/moonwell_theme_variant.dart';
|
||||
import 'package:widgetbook/widgetbook.dart';
|
||||
import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook;
|
||||
|
||||
@widgetbook.UseCase(name: 'interactive', type: MwGameTile, path: '[Launcher]')
|
||||
Widget buildMwGameTileInteractiveUseCase(BuildContext context) {
|
||||
return SizedBox(
|
||||
width: context.knobs.double.slider(
|
||||
label: 'width',
|
||||
initialValue: 240,
|
||||
min: 72,
|
||||
max: 360,
|
||||
divisions: 36,
|
||||
),
|
||||
child: MwGameTile(
|
||||
title: context.knobs.string(label: 'title', initialValue: 'MoonWell'),
|
||||
subtitle: context.knobs.stringOrNull(
|
||||
label: 'subtitle',
|
||||
initialValue: 'Wrath of the Lich King',
|
||||
),
|
||||
icon: Icons.nights_stay_outlined,
|
||||
selected: context.knobs.boolean(label: 'selected', initialValue: true),
|
||||
enabled: context.knobs.boolean(label: 'enabled', initialValue: true),
|
||||
compact: context.knobs.boolean(label: 'compact', initialValue: false),
|
||||
onPressed: () => debugPrint('Game tile selected'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@widgetbook.UseCase(name: 'full', type: MwGameRail, path: '[Launcher]')
|
||||
Widget buildMwGameRailFullUseCase(BuildContext context) {
|
||||
return const SizedBox(width: 240, height: 560, child: MwGameRail());
|
||||
}
|
||||
|
||||
@widgetbook.UseCase(name: 'compact', type: MwGameRail, path: '[Launcher]')
|
||||
Widget buildMwGameRailCompactUseCase(BuildContext context) {
|
||||
return const SizedBox(
|
||||
width: 72,
|
||||
height: 560,
|
||||
child: MwGameRail(compact: true),
|
||||
);
|
||||
}
|
||||
|
||||
@widgetbook.UseCase(name: 'text_only', type: MwNewsItem, path: '[Launcher]')
|
||||
Widget buildMwNewsItemTextOnlyUseCase(BuildContext context) {
|
||||
return SizedBox(
|
||||
width: 620,
|
||||
child: MwNewsItem(
|
||||
item: MwNewsItemData(
|
||||
title: context.knobs.string(
|
||||
label: 'title',
|
||||
initialValue: 'Добро пожаловать в MoonWell',
|
||||
),
|
||||
body: context.knobs.string(
|
||||
label: 'body',
|
||||
initialValue: 'Приключение в Нордсколе начинается здесь.',
|
||||
),
|
||||
createdAt: DateTime(2026, 6, 22),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@widgetbook.UseCase(name: 'image_failure', type: MwNewsItem, path: '[Launcher]')
|
||||
Widget buildMwNewsItemImageFailureUseCase(BuildContext context) {
|
||||
return const SizedBox(
|
||||
width: 620,
|
||||
child: MwNewsItem(
|
||||
item: MwNewsItemData(
|
||||
title: 'Обновление игрового мира',
|
||||
body: 'Изображение недоступно, но публикация остаётся читаемой.',
|
||||
imageUrl: 'https://invalid.moonwell.local/news.jpg',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@widgetbook.UseCase(name: 'loading', type: MwNewsList, path: '[Launcher]')
|
||||
Widget buildMwNewsListLoadingUseCase(BuildContext context) {
|
||||
return const MwNewsList(state: MwNewsListState.loading);
|
||||
}
|
||||
|
||||
@widgetbook.UseCase(name: 'empty', type: MwNewsList, path: '[Launcher]')
|
||||
Widget buildMwNewsListEmptyUseCase(BuildContext context) {
|
||||
return const MwNewsList(state: MwNewsListState.empty);
|
||||
}
|
||||
|
||||
@widgetbook.UseCase(name: 'failure', type: MwNewsList, path: '[Launcher]')
|
||||
Widget buildMwNewsListFailureUseCase(BuildContext context) {
|
||||
return MwNewsList(
|
||||
state: MwNewsListState.failure,
|
||||
error: context.knobs.string(
|
||||
label: 'error',
|
||||
initialValue: 'Сервер новостей временно недоступен.',
|
||||
),
|
||||
onRetry: () => debugPrint('News reload requested'),
|
||||
);
|
||||
}
|
||||
|
||||
@widgetbook.UseCase(name: 'populated', type: MwNewsList, path: '[Launcher]')
|
||||
Widget buildMwNewsListPopulatedUseCase(BuildContext context) {
|
||||
final count = context.knobs.int.slider(
|
||||
label: 'itemCount',
|
||||
initialValue: 8,
|
||||
min: 1,
|
||||
max: 50,
|
||||
divisions: 49,
|
||||
);
|
||||
return MwNewsList(
|
||||
state: MwNewsListState.populated,
|
||||
items: List.generate(
|
||||
count,
|
||||
(index) => MwNewsItemData(
|
||||
title: 'Новость ${index + 1}',
|
||||
body:
|
||||
'Реалистичный текст публикации о событиях и обновлениях MoonWell.',
|
||||
createdAt: DateTime(2026, 6, 22).subtract(Duration(days: index)),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@widgetbook.UseCase(
|
||||
name: 'interactive',
|
||||
type: MwSyncActionArea,
|
||||
path: '[Launcher]',
|
||||
)
|
||||
Widget buildMwSyncActionAreaInteractiveUseCase(BuildContext context) {
|
||||
final state = context.knobs.object.dropdown<MwSyncPresentation>(
|
||||
label: 'state',
|
||||
initialOption: MwSyncPresentation.downloading,
|
||||
options: MwSyncPresentation.values,
|
||||
labelBuilder: (value) => value.name,
|
||||
);
|
||||
return SizedBox(
|
||||
width: 420,
|
||||
child: MwSyncActionArea(
|
||||
state: state,
|
||||
status: context.knobs.string(
|
||||
label: 'status',
|
||||
initialValue: 'Загружаем обновление клиента…',
|
||||
),
|
||||
progress: context.knobs.double.slider(
|
||||
label: 'progress',
|
||||
initialValue: .46,
|
||||
min: 0,
|
||||
max: 1,
|
||||
divisions: 100,
|
||||
),
|
||||
currentPath: context.knobs.stringOrNull(
|
||||
label: 'currentPath',
|
||||
initialValue: r'Data\ruRU\patch-ruRU.MPQ',
|
||||
),
|
||||
error: state == MwSyncPresentation.failure
|
||||
? context.knobs.string(
|
||||
label: 'error',
|
||||
initialValue: 'Проверка SHA-256 не пройдена.',
|
||||
)
|
||||
: null,
|
||||
onPrimary: () => debugPrint('Primary sync action requested: $state'),
|
||||
onPause: state == MwSyncPresentation.downloading
|
||||
? () => debugPrint('Sync pause requested')
|
||||
: null,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@widgetbook.UseCase(
|
||||
name: 'metadata',
|
||||
type: MwLauncherStatusBar,
|
||||
path: '[Launcher]',
|
||||
)
|
||||
Widget buildMwLauncherStatusBarMetadataUseCase(BuildContext context) {
|
||||
return MwLauncherStatusBar(
|
||||
status: context.knobs.string(
|
||||
label: 'status',
|
||||
initialValue: 'Загрузка игровых файлов',
|
||||
),
|
||||
fileCount: 'Файлы 124/480',
|
||||
speed: '12.4 MB/s',
|
||||
eta: 'ETA 00:01:42',
|
||||
buildHash: 'a93fd1c2',
|
||||
);
|
||||
}
|
||||
|
||||
@widgetbook.UseCase(
|
||||
name: 'default',
|
||||
type: MwAccountAffordance,
|
||||
path: '[Launcher]',
|
||||
)
|
||||
Widget buildMwAccountAffordanceUseCase(BuildContext context) {
|
||||
return MwAccountAffordance(
|
||||
onSettings: () => debugPrint('Settings requested'),
|
||||
onLogout: () => debugPrint('Logout requested'),
|
||||
);
|
||||
}
|
||||
|
||||
@widgetbook.UseCase(
|
||||
name: 'interactive',
|
||||
type: MwSettingsPanel,
|
||||
path: '[Launcher]',
|
||||
)
|
||||
Widget buildMwSettingsPanelInteractiveUseCase(BuildContext context) {
|
||||
final variant = context.knobs.object.dropdown<MoonWellThemeVariant>(
|
||||
label: 'themeVariant',
|
||||
initialOption: MoonWellThemeVariant.forest,
|
||||
options: MoonWellThemeVariant.values,
|
||||
labelBuilder: (value) => value.name,
|
||||
);
|
||||
return SizedBox(
|
||||
width: 420,
|
||||
child: MwSettingsPanel(
|
||||
installationPath: context.knobs.stringOrNull(
|
||||
label: 'installationPath',
|
||||
initialValue: r'C:\Games\MoonWell',
|
||||
),
|
||||
themeVariant: variant,
|
||||
syncActive: context.knobs.boolean(
|
||||
label: 'syncActive',
|
||||
initialValue: false,
|
||||
),
|
||||
onChooseDirectory: () => debugPrint('Directory selection requested'),
|
||||
onThemeChanged: (value) => debugPrint('Theme changed: ${value.name}'),
|
||||
onVerify: () => debugPrint('Manual verification requested'),
|
||||
onLogout: () => debugPrint('Logout requested'),
|
||||
),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user