71 lines
2.7 KiB
Dart
71 lines
2.7 KiB
Dart
|
|
import 'package:flutter/material.dart';
|
||
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||
|
|
import 'package:lucide_icons/lucide_icons.dart';
|
||
|
|
import '../../providers/theme_provider.dart';
|
||
|
|
import '../../theme/app_colors.dart';
|
||
|
|
|
||
|
|
class LanguageSelector extends ConsumerWidget {
|
||
|
|
const LanguageSelector({super.key});
|
||
|
|
|
||
|
|
@override
|
||
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
||
|
|
final currentLocale = ref.watch(userProfileProvider).locale;
|
||
|
|
final appColors = Theme.of(context).extension<AppColors>()!;
|
||
|
|
|
||
|
|
return ListTile(
|
||
|
|
leading: Icon(LucideIcons.languages, color: appColors.iconDefault),
|
||
|
|
title: Text('言語 / Language', style: TextStyle(color: appColors.textPrimary)),
|
||
|
|
subtitle: Text(_getLanguageLabel(currentLocale), style: TextStyle(color: appColors.textSecondary)),
|
||
|
|
trailing: Icon(LucideIcons.chevronRight, color: appColors.iconSubtle),
|
||
|
|
onTap: () => _showLanguageDialog(context, ref, currentLocale),
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
void _showLanguageDialog(BuildContext context, WidgetRef ref, String current) {
|
||
|
|
final appColors = Theme.of(context).extension<AppColors>()!;
|
||
|
|
final languages = [
|
||
|
|
{'code': 'ja', 'name': '日本語', 'flag': '🇯🇵'},
|
||
|
|
{'code': 'en', 'name': 'English', 'flag': '🇺🇸'},
|
||
|
|
// Phase 2: フランス語・ドイツ語を追加予定
|
||
|
|
// {'code': 'fr', 'name': 'Français', 'flag': '🇫🇷'},
|
||
|
|
// {'code': 'de', 'name': 'Deutsch', 'flag': '🇩🇪'},
|
||
|
|
];
|
||
|
|
|
||
|
|
showDialog(
|
||
|
|
context: context,
|
||
|
|
builder: (dialogContext) => SimpleDialog(
|
||
|
|
title: Text('言語選択 / Select Language', style: TextStyle(color: appColors.textPrimary)),
|
||
|
|
children: languages.map((lang) => SimpleDialogOption(
|
||
|
|
onPressed: () {
|
||
|
|
ref.read(userProfileProvider.notifier).setLocale(lang['code']!);
|
||
|
|
Navigator.pop(dialogContext);
|
||
|
|
},
|
||
|
|
child: Row(
|
||
|
|
children: [
|
||
|
|
Icon(
|
||
|
|
lang['code'] == current ? Icons.check_circle : Icons.circle_outlined,
|
||
|
|
size: 20,
|
||
|
|
color: lang['code'] == current ? appColors.brandPrimary : appColors.iconSubtle,
|
||
|
|
),
|
||
|
|
const SizedBox(width: 16),
|
||
|
|
Text(lang['flag']!, style: const TextStyle(fontSize: 24)),
|
||
|
|
const SizedBox(width: 12),
|
||
|
|
Text(lang['name']!, style: TextStyle(fontSize: 16, color: appColors.textPrimary)),
|
||
|
|
],
|
||
|
|
),
|
||
|
|
)).toList(),
|
||
|
|
),
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
String _getLanguageLabel(String code) {
|
||
|
|
switch (code) {
|
||
|
|
case 'ja': return '🇯🇵 日本語';
|
||
|
|
case 'en': return '🇺🇸 English';
|
||
|
|
case 'fr': return '🇫🇷 Français';
|
||
|
|
case 'de': return '🇩🇪 Deutsch';
|
||
|
|
default: return '🇯🇵 日本語';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|