122 lines
4.3 KiB
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 'ゴシック (標準)';
|
|
}
|
|
}
|
|
}
|