ponshu-room-lite/lib/widgets/settings/app_settings_section.dart

122 lines
4.3 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';
class AppearanceSettingsSection extends ConsumerWidget {
const AppearanceSettingsSection({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final userProfile = ref.watch(userProfileProvider);
final themeMode = userProfile.themeMode;
final fontPref = userProfile.fontPreference;
final isDark = Theme.of(context).brightness == Brightness.dark;
return Column(
children: [
_buildSectionHeader(context, 'アプリ設定', LucideIcons.palette),
Card(
child: Column(
children: [
ListTile(
leading: Icon(LucideIcons.type, color: isDark ? Colors.grey[400] : null),
title: const Text('フォント'),
subtitle: Text(_getFontName(fontPref)),
trailing: PopupMenuButton<String>(
icon: Icon(LucideIcons.chevronRight, color: isDark ? Colors.grey[600] : null),
onSelected: (val) {
ref.read(userProfileProvider.notifier).setFontPreference(val);
},
itemBuilder: (context) => [
const PopupMenuItem(value: 'sans', child: Text('ゴシック (標準)')),
const PopupMenuItem(value: 'serif', child: Text('明朝 (上品)')),
const PopupMenuItem(value: 'digital', child: Text('ドット (レトロ)')),
],
),
),
const Divider(height: 1),
ListTile(
leading: Icon(LucideIcons.sunMoon, color: isDark ? Colors.grey[400] : null),
title: const Text('テーマ設定'),
subtitle: Text(_getThemeModeName(themeMode)),
trailing: Icon(LucideIcons.chevronRight, color: isDark ? Colors.grey[600] : null),
onTap: () => _showThemeDialog(context, ref, themeMode),
),
],
),
),
],
);
}
Widget _buildSectionHeader(BuildContext context, String title, IconData icon) {
final isDark = Theme.of(context).brightness == Brightness.dark;
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 4),
child: Row(
children: [
Icon(icon, size: 20, color: isDark ? Colors.orange[300] : Theme.of(context).primaryColor),
const SizedBox(width: 8),
Text(
title,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
color: isDark ? Colors.grey[300] : Theme.of(context).primaryColor,
),
),
],
),
);
}
String _getThemeModeName(String mode) {
switch (mode) {
case 'light': return 'ライト';
case 'dark': return 'ダーク';
default: return 'システム設定';
}
}
void _showThemeDialog(BuildContext context, WidgetRef ref, String current) {
showDialog(
context: context,
builder: (context) => SimpleDialog(
title: const Text('テーマ設定'),
children: [
_buildThemeOption(context, ref, 'system', 'システム設定', current),
_buildThemeOption(context, ref, 'light', 'ライトモード', current),
_buildThemeOption(context, ref, 'dark', 'ダークモード', current),
],
),
);
}
Widget _buildThemeOption(BuildContext context, WidgetRef ref, String value, String label, String current) {
return SimpleDialogOption(
onPressed: () {
ref.read(userProfileProvider.notifier).setThemeMode(value);
Navigator.pop(context);
},
child: Row(
children: [
Icon(
value == current ? Icons.radio_button_checked : Icons.radio_button_unchecked,
color: value == current ? Theme.of(context).primaryColor : Colors.grey,
),
const SizedBox(width: 12),
Text(label),
],
),
);
}
String _getFontName(String pref) {
switch (pref) {
case 'serif': return '明朝 (上品)';
case 'digital': return 'ドット (レトロ)';
default: return 'ゴシック (標準)';
}
}
}