Skip to content

Commit

Permalink
Merge pull request #152 from sparcs-kaist/feat@language-setting
Browse files Browse the repository at this point in the history
Resolve #134, Add language setting
  • Loading branch information
sboh1214 authored Sep 7, 2023
2 parents 04b6362 + c2e0a85 commit b7945c8
Show file tree
Hide file tree
Showing 6 changed files with 363 additions and 274 deletions.
6 changes: 5 additions & 1 deletion assets/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,18 @@
"deleted_account": "This is the deleted account."
},
"settings": {
"language": "Language",
"korean": "Korean",
"english": "English",
"send_error_log": "Send error log",
"send_error_log_desc": "Automatically collect logs without user reporting",
"send_anonymously": "Send anonymously",
"send_anonymously_desc": "Not including user ID in error logs",
"reset_all": "Reset all settings",
"reset_all_desc": "Are you really want to reset all data except login data?",
"throw_test": "Throw Test Exception",
"throw_test_desc": "for testing firebase crashlytics"
"throw_test_desc": "for testing firebase crashlytics",
"about": "About"
},
"department": {
"department": "Dept.",
Expand Down
6 changes: 5 additions & 1 deletion assets/translations/ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,18 @@
"deleted_account": "삭제된 계정입니다."
},
"settings": {
"language": "언어",
"korean": "한국어",
"english": "영어",
"send_error_log": "오류 로그 전송",
"send_error_log_desc": "사용자의 제보 없이 자동으로 오류를 수집합니다.",
"send_anonymously": "익명으로 전송",
"send_anonymously_desc": "오류 로그에 사용자 ID를 포함하지 않고 익명으로 전송합니다.",
"reset_all": "모든 설정 데이터 초기화",
"reset_all_desc": "정말 모든 설정 데이터를 초기화하시겠습니까? 로그인 정보는 초기화되지 않습니다.",
"throw_test": "테스트 오류 발생",
"throw_test_desc": "Firebase crashlytics 테스트용"
"throw_test_desc": "Firebase crashlytics 테스트용",
"about": "정보"
},
"department": {
"department": "학과",
Expand Down
178 changes: 129 additions & 49 deletions lib/pages/settings_page.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
import 'package:flutter/cupertino.dart';
import 'package:otlplus/constants/color.dart';
import 'package:otlplus/constants/text_styles.dart';
import 'package:otlplus/providers/settings_model.dart';
import 'package:otlplus/widgets/dropdown.dart';
import 'package:otlplus/widgets/responsive_button.dart';
import 'package:otlplus/utils/navigator.dart';
import 'package:otlplus/widgets/otl_scaffold.dart';
Expand All @@ -16,6 +17,8 @@ class SettingsPage extends StatelessWidget {

@override
Widget build(BuildContext context) {
final isEn = EasyLocalization.of(context)?.currentLocale == Locale('en');

return OTLScaffold(
child: OTLLayout(
middle: Text('title.settings'.tr(), style: titleBold),
Expand All @@ -25,33 +28,77 @@ class SettingsPage extends StatelessWidget {
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
ListTile(
title: Text(
"settings.send_error_log".tr(),
style: bodyBold,
),
subtitle: Text(
"settings.send_error_log_desc".tr(),
style: bodyRegular,
),
trailing: PlatformSwitch(
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"settings.language".tr(),
style: bodyBold,
),
Dropdown<bool>(
customButton: Container(
height: 34,
padding: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: OTLColor.pinksLight,
borderRadius: BorderRadius.circular(20),
),
child: Row(
children: [
Icon(
Icons.language,
color: OTLColor.pinksMain,
),
const SizedBox(width: 8),
Text(
isEn
? "settings.english".tr()
: "settings.korean".tr(),
style: bodyBold.copyWith(
height: 1.2, color: OTLColor.pinksMain),
)
],
),
),
items: [
ItemData(
value: false,
text: "settings.korean".tr(),
icon: !isEn ? Icons.check : null,
),
ItemData(
value: true,
text: "settings.english".tr(),
icon: isEn ? Icons.check : null,
),
],
isIconLeft: true,
offsetY: -6,
onChanged: (value) {
if (value!) {
EasyLocalization.of(context)?.setLocale(Locale('en'));
} else {
EasyLocalization.of(context)?.setLocale(Locale('ko'));
}
},
),
],
),
_buildListTile(
title: "settings.send_error_log".tr(),
subtitle: "settings.send_error_log_desc".tr(),
trailing: CupertinoSwitch(
value: context.watch<SettingsModel>().getSendCrashlytics(),
onChanged: (value) =>
context.read<SettingsModel>().setSendCrashlytics(value),
),
),
Visibility(
visible: context.watch<SettingsModel>().getSendCrashlytics(),
child: ListTile(
title: Text(
"settings.send_anonymously".tr(),
style: bodyBold,
),
subtitle: Text(
"settings.send_anonymously_desc".tr(),
style: bodyRegular,
),
trailing: PlatformSwitch(
child: _buildListTile(
title: "settings.send_anonymously".tr(),
subtitle: "settings.send_anonymously_desc".tr(),
trailing: CupertinoSwitch(
value: context
.watch<SettingsModel>()
.getSendCrashlyticsAnonymously(),
Expand All @@ -63,20 +110,14 @@ class SettingsPage extends StatelessWidget {
),
Visibility(
visible: kDebugMode,
child: ListTile(
title: Text(
"settings.throw_test".tr(),
style: bodyBold,
),
subtitle: Text(
"settings.throw_test_desc".tr(),
style: bodyRegular,
),
child: _buildListTile(
title: "settings.throw_test".tr(),
subtitle: "settings.throw_test_desc".tr(),
onTap: () => throw Exception(),
),
),
ListTile(
title: Text("settings.reset_all".tr(), style: bodyBold),
_buildListTile(
title: "settings.reset_all".tr(),
onTap: () {
OTLNavigator.pushDialog(
context: context,
Expand Down Expand Up @@ -116,23 +157,29 @@ class SettingsPage extends StatelessWidget {
);
},
),
AboutListTile(
applicationName: "",
applicationIcon:
Image.asset("assets/images/logo.png", height: 48.0),
aboutBoxChildren: <Widget>[
Text(
"Online Timeplanner with Lectures Plus @ KAIST",
style: bodyRegular,
),
IconTextButton(
padding: EdgeInsets.fromLTRB(0, 4, 10, 4),
onTap: () => launchUrl(Uri.parse("mailto:$contactEmail")),
text: contactEmail,
textStyle:
bodyRegular.copyWith(color: OTLColor.pinksMain),
)
],
_buildListTile(
title: "settings.about".tr(),
onTap: () => showAboutDialog(
context: context,
applicationName: "",
applicationIcon:
Image.asset("assets/images/logo.png", height: 48.0),
children: [
Text(
"Online Timeplanner with Lectures Plus @ KAIST",
style: bodyRegular,
),
IconTextButton(
padding: EdgeInsets.fromLTRB(0, 4, 10, 4),
onTap: () =>
launchUrl(Uri.parse("mailto:$contactEmail")),
text: contactEmail,
textStyle:
bodyRegular.copyWith(color: OTLColor.pinksMain),
)
],
),
hasTopPadding: false,
),
],
),
Expand All @@ -141,4 +188,37 @@ class SettingsPage extends StatelessWidget {
),
);
}

Widget _buildListTile(
{required String title,
String subtitle = '',
Widget? trailing,
void Function()? onTap,
bool hasTopPadding = true}) {
return Padding(
padding: EdgeInsets.only(top: hasTopPadding ? 16 : 0),
child: GestureDetector(
onTap: onTap,
behavior: HitTestBehavior.translucent,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title, style: bodyBold),
const SizedBox(height: 4),
Text(subtitle, style: bodyRegular),
],
),
),
if (trailing != null) trailing
],
),
),
),
);
}
}
123 changes: 123 additions & 0 deletions lib/widgets/dropdown.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import 'package:flutter/material.dart';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:otlplus/constants/color.dart';
import 'package:otlplus/constants/text_styles.dart';

class ItemData<T> {
final T value;
final String text;
final IconData? icon;
final Color textColor, iconColor;
final bool disabled;

ItemData({
required this.value,
required this.text,
this.icon,
this.textColor = OTLColor.grayF,
this.iconColor = OTLColor.grayF,
this.disabled = false,
});
}

class Dropdown<T> extends StatelessWidget {
const Dropdown({
Key? key,
required this.customButton,
required this.items,
this.isIconLeft = false,
this.offsetFromLeft = false,
this.offsetY = -8,
this.hasScrollbar = false,
required this.onChanged,
this.onMenuStateChange,
}) : super(key: key);

final Widget customButton;
final List<ItemData<T>> items;
final bool isIconLeft;
final bool offsetFromLeft;
final double offsetY;
final bool hasScrollbar;
final void Function(T?) onChanged;
final void Function(bool)? onMenuStateChange;

@override
Widget build(BuildContext context) {
return DropdownButtonHideUnderline(
child: DropdownButton2<T>(
customButton: customButton,
dropdownStyleData: DropdownStyleData(
direction:
offsetFromLeft ? DropdownDirection.right : DropdownDirection.left,
width: 200,
maxHeight: 237,
elevation: 0,
padding: EdgeInsets.zero,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: OTLColor.gray6,
),
offset: Offset(0, offsetY),
scrollbarTheme: hasScrollbar
? ScrollbarThemeData(
radius: Radius.circular(1.5),
mainAxisMargin: 11.5,
crossAxisMargin: 4.5,
thickness: MaterialStatePropertyAll(3),
thumbColor: MaterialStatePropertyAll(OTLColor.grayF),
)
: null,
),
menuItemStyleData: MenuItemStyleData(
height: 42,
padding: EdgeInsets.zero,
),
items: items.map((itemData) {
final children = [
Expanded(
child: Text(
itemData.text,
style: bodyRegular.copyWith(color: itemData.textColor),
),
),
Padding(
padding: EdgeInsets.only(right: isIconLeft ? 12 : 0),
child: Icon(
itemData.icon,
size: 16,
color: itemData.iconColor,
),
),
];
return DropdownMenuItem<T>(
value: itemData.value,
child: Stack(
alignment: AlignmentDirectional.bottomStart,
children: [
Opacity(
opacity: itemData.disabled ? 0.5 : 1,
child: Container(
height: 42,
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row(
children:
isIconLeft ? children.reversed.toList() : children,
),
),
),
if (itemData != items.last)
Container(
color: OTLColor.grayF.withOpacity(0.5),
height: 0.5,
),
],
),
);
}).toList(),
onChanged: onChanged,
onMenuStateChange: onMenuStateChange,
),
);
}
}
Loading

0 comments on commit b7945c8

Please sign in to comment.