Skip to content

Commit

Permalink
add change theme on settings page
Browse files Browse the repository at this point in the history
  • Loading branch information
smart7even committed Aug 6, 2023
1 parent 332c0c1 commit a842062
Show file tree
Hide file tree
Showing 5 changed files with 262 additions and 44 deletions.
62 changes: 62 additions & 0 deletions lib/common/utils/colors_utils.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import 'package:flutter/material.dart';

MaterialColor getColorFromString(String color) {
switch (color) {
case 'blue':
return Colors.blue;
case 'red':
return Colors.red;
case 'green':
return Colors.green;
case 'yellow':
return Colors.yellow;
case 'orange':
return Colors.orange;
case 'pink':
return Colors.pink;
case 'purple':
return Colors.purple;
case 'indigo':
return Colors.indigo;
case 'teal':
return Colors.teal;
case 'cyan':
return Colors.cyan;
case 'brown':
return Colors.brown;
case 'grey':
return Colors.grey;
default:
return Colors.blue;
}
}

String getStringFromColor(MaterialColor color) {
if (color == Colors.blue) {
return 'blue';
} else if (color == Colors.red) {
return 'red';
} else if (color == Colors.green) {
return 'green';
} else if (color == Colors.yellow) {
return 'yellow';
} else if (color == Colors.orange) {
return 'orange';
} else if (color == Colors.pink) {
return 'pink';
} else if (color == Colors.purple) {
return 'purple';
} else if (color == Colors.indigo) {
return 'indigo';
} else if (color == Colors.teal) {
return 'teal';
} else if (color == Colors.cyan) {
return 'cyan';
} else if (color == Colors.brown) {
return 'brown';
} else if (color == Colors.grey) {
return 'grey';
} else {
return 'blue';
}
}
13 changes: 13 additions & 0 deletions lib/feature/settings/data/settings_local_data_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ abstract class ISettingsLocalDataProvider {
Future<Group?> getGroup();
Future<void> saveLanguage(String language);
Future<String?> getLanguage();
Future<void> saveTheme(String theme);
Future<String?> getTheme();
}

class SettingsLocalDataProvider implements ISettingsLocalDataProvider {
Expand All @@ -16,6 +18,7 @@ class SettingsLocalDataProvider implements ISettingsLocalDataProvider {
static const String _groupCourseKey = 'groupCourse';
static const String _groupFacultyIdKey = 'groupFacultyId';
static const String _languageKey = 'language';
static const String _themeKey = 'theme';

SettingsLocalDataProvider({required SharedPreferences prefs})
: _prefs = prefs;
Expand Down Expand Up @@ -59,4 +62,14 @@ class SettingsLocalDataProvider implements ISettingsLocalDataProvider {
Future<void> saveLanguage(String language) {
return _prefs.setString(_languageKey, language);
}

@override
Future<String?> getTheme() async {
return _prefs.getString(_themeKey);
}

@override
Future<void> saveTheme(String theme) {
return _prefs.setString(_themeKey, theme);
}
}
22 changes: 22 additions & 0 deletions lib/feature/settings/data/settings_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ abstract class ISettingsRepository {
Future<void> saveLanguage(String language);
Future<String?> getLanguage();
Stream<String> getLanguageChangedStream();
Future<void> saveTheme(String theme);
Future<String?> getTheme();
Stream<String> getThemeChangedStream();
}

class SettingsRepository implements ISettingsRepository {
Expand All @@ -20,6 +23,9 @@ class SettingsRepository implements ISettingsRepository {
final StreamController<String> _languageChangedController =
StreamController<String>.broadcast();

final StreamController<String> _themeChangedController =
StreamController<String>.broadcast();

@override
Future<Group?> getGroup() {
return _localDataProvider.getGroup();
Expand All @@ -44,4 +50,20 @@ class SettingsRepository implements ISettingsRepository {
@override
Stream<String> getLanguageChangedStream() =>
_languageChangedController.stream;

@override
Future<String?> getTheme() {
return _localDataProvider.getTheme();
}

@override
Stream<String> getThemeChangedStream() {
return _themeChangedController.stream;
}

@override
Future<void> saveTheme(String theme) async {
await _localDataProvider.saveTheme(theme);
_themeChangedController.add(theme);
}
}
184 changes: 141 additions & 43 deletions lib/feature/settings/widget/settings_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:uneconly/common/dependencies/dependencies_scope.dart';
import 'package:uneconly/common/localization/localization.dart';
import 'package:uneconly/common/utils/colors_utils.dart';

/// Flutter code sample for [CupertinoPicker].
Expand All @@ -23,6 +24,22 @@ class SettingsPage extends StatefulWidget {

class _SettingsPageState extends State<SettingsPage> {
int _selectedLanguage = 0;
int _selectedColor = 0;

List<MaterialColor> colors = [
Colors.blue,
Colors.red,
Colors.green,
Colors.yellow,
Colors.orange,
Colors.pink,
Colors.purple,
Colors.indigo,
Colors.teal,
Colors.cyan,
Colors.brown,
Colors.grey,
];

@override
void initState() {
Expand All @@ -47,6 +64,27 @@ class _SettingsPageState extends State<SettingsPage> {
});
}
});

RepositoryProvider.of<DependenciesScope>(context)
.settingsRepository
.getTheme()
.then((value) {
if (value == null) {
setState(() {
_selectedColor = 0;
});
} else {
final materialColor = getColorFromString(value);

final selectedColor = colors.indexWhere(
(element) => element == materialColor,
);

setState(() {
_selectedColor = selectedColor;
});
}
});
}

// This shows a CupertinoModalPopup with a reasonable fixed height which hosts CupertinoPicker.
Expand Down Expand Up @@ -85,53 +123,113 @@ class _SettingsPageState extends State<SettingsPage> {
fontSize: 22.0,
),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('${AppLocalizations.of(context)!.language}: '),
CupertinoButton(
padding: EdgeInsets.zero,
// Display a CupertinoPicker with list of fruits.
onPressed: () => _showDialog(
CupertinoPicker(
magnification: 1.22,
squeeze: 1.2,
useMagnifier: true,
itemExtent: _kItemExtent,
// This sets the initial item.
scrollController: FixedExtentScrollController(
initialItem: _selectedLanguage,
),
// This is called when selected item is changed.
onSelectedItemChanged: (int selectedItem) async {
setState(() {
_selectedLanguage = selectedItem;
});
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('${AppLocalizations.of(context)!.language}: '),
CupertinoButton(
padding: EdgeInsets.zero,
// Display a CupertinoPicker with list of fruits.
onPressed: () => _showDialog(
CupertinoPicker(
magnification: 1.22,
squeeze: 1.2,
useMagnifier: true,
itemExtent: _kItemExtent,
// This sets the initial item.
scrollController: FixedExtentScrollController(
initialItem: _selectedLanguage,
),
// This is called when selected item is changed.
onSelectedItemChanged: (int selectedItem) async {
setState(() {
_selectedLanguage = selectedItem;
});

if (_selectedLanguage == 0) {
await RepositoryProvider.of<DependenciesScope>(context)
.settingsRepository
.saveLanguage('ru');
} else {
await RepositoryProvider.of<DependenciesScope>(context)
.settingsRepository
.saveLanguage('en');
}
},
children: List<Widget>.generate(
_languageNames.length,
(int index) {
return Center(child: Text(_languageNames[index]));
},
if (_selectedLanguage == 0) {
await RepositoryProvider.of<DependenciesScope>(
context,
).settingsRepository.saveLanguage('ru');
} else {
await RepositoryProvider.of<DependenciesScope>(
context,
).settingsRepository.saveLanguage('en');
}
},
children: List<Widget>.generate(
_languageNames.length,
(int index) {
return Center(child: Text(_languageNames[index]));
},
),
),
),
// This displays the selected fruit name.
child: Text(
_languageNames[_selectedLanguage],
style: const TextStyle(
fontSize: 22.0,
),
),
),
],
),
// horizontal list of themes
Container(
height: 40,
padding: const EdgeInsets.symmetric(
horizontal: 10,
),
// This displays the selected fruit name.
child: Text(
_languageNames[_selectedLanguage],
style: const TextStyle(
fontSize: 22.0,
),
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: colors.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () async {
await context
.read<DependenciesScope>()
.settingsRepository
.saveTheme(
getStringFromColor(colors[index]),
);
setState(() {
_selectedColor = index;
});
},
child: Container(
width: 40,
height: 40,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
border: _selectedColor == index
? Border.all(
color: Colors.blue,
width: 2,
)
: null,
),
child: Center(
child: Container(
width: 32,
height: 32,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10 / 1.25),
color: colors[index],
),
),
),
),
);
},
separatorBuilder: (context, index) {
return const SizedBox(
width: 10,
);
},
),
),
],
Expand Down
Loading

0 comments on commit a842062

Please sign in to comment.