JJ_MKVMaker/lib/ui/setup_dialog.dart

74 lines
2.9 KiB
Dart

import 'package:flutter/material.dart';
import '../services/app_shell.dart';
import 'theme.dart';
/// 필수 프로그램 점검. 없으면 물어보고 내려받은 뒤 다시 시작한다.
/// [quietIfOk] 가 false 면 모두 있을 때도 알려 준다 (환경 설정에서 누른 경우).
Future<void> checkRequiredTools(BuildContext context, AppShell shell, {bool quietIfOk = true}) async {
final missing = await shell.missingTools();
if (!context.mounted) return;
if (missing.isEmpty) {
if (!quietIfOk) {
ScaffoldMessenger.of(context)
.showSnackBar(const SnackBar(content: Text('필수 프로그램이 모두 설치되어 있습니다.')));
}
return;
}
final go = await showDialog<bool>(
context: context,
builder: (ctx) => AlertDialog(
title: const Text('필수 프로그램 설치'),
content: Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [
const Text('아래 프로그램이 없어 일부 기능을 쓸 수 없습니다. 공식 배포처에서 내려받아 프로그램 폴더에 설치할까요?'),
const SizedBox(height: 12),
for (final m in missing) Text('• $m'),
const SizedBox(height: 12),
const Text('설치가 끝나면 프로그램이 다시 시작됩니다.', style: TextStyle(fontSize: 12, color: JjColors.textDim)),
]),
actions: [
TextButton(onPressed: () => Navigator.pop(ctx, false), child: const Text('나중에')),
FilledButton(onPressed: () => Navigator.pop(ctx, true), child: const Text('내려받기')),
],
),
);
if (go != true || !context.mounted) return;
final progress = ValueNotifier<(String, double)>(('', 0));
String? error;
showDialog<void>(
context: context,
barrierDismissible: false,
builder: (ctx) => AlertDialog(
title: const Text('내려받는 중'),
content: ValueListenableBuilder<(String, double)>(
valueListenable: progress,
builder: (_, v, _) => Column(mainAxisSize: MainAxisSize.min, children: [
Text(v.$1.isEmpty ? '준비 중…' : '${v.$1} ${(v.$2 * 100).round()}%'),
const SizedBox(height: 12),
LinearProgressIndicator(value: v.$1.isEmpty ? null : v.$2),
]),
),
),
);
try {
await shell.installMissingTools((name, p) => progress.value = (name, p));
} catch (e) {
error = '$e';
}
if (!context.mounted) return;
Navigator.of(context).pop();
if (error != null) {
await showDialog<void>(
context: context,
builder: (ctx) => AlertDialog(
title: const Text('설치 실패'),
content: SelectableText('인터넷 연결을 확인한 뒤 환경 설정 > 필수 프로그램 점검에서 다시 시도하세요.\n\n$error'),
actions: [TextButton(onPressed: () => Navigator.pop(ctx), child: const Text('닫기'))],
),
);
return;
}
await shell.restart();
}