init refilc-plus
This commit is contained in:
commit
6edc2029bd
37 changed files with 6988 additions and 0 deletions
242
lib/ui/mobile/settings/app_icon_screen.dart
Normal file
242
lib/ui/mobile/settings/app_icon_screen.dart
Normal file
|
@ -0,0 +1,242 @@
|
|||
import 'package:refilc/models/settings.dart';
|
||||
import 'package:refilc/theme/colors/colors.dart';
|
||||
import 'package:refilc_mobile_ui/common/panel/panel.dart';
|
||||
// import 'package:refilc_mobile_ui/common/panel/panel_button.dart';
|
||||
import 'package:refilc_plus/helpers/app_icon_helper.dart';
|
||||
// import 'package:refilc_plus/models/premium_scopes.dart';
|
||||
// import 'package:refilc_plus/providers/plus_provider.dart';
|
||||
// import 'package:refilc_plus/ui/mobile/plus/upsell.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'app_icon_screen.i18n.dart';
|
||||
|
||||
class PremiumCustomAppIconMenu extends StatelessWidget {
|
||||
const PremiumCustomAppIconMenu({super.key, required this.settings});
|
||||
|
||||
final SettingsProvider settings;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// return PanelButton(
|
||||
// onPressed: () {
|
||||
// if (!Provider.of<PlusProvider>(context, listen: false)
|
||||
// .hasScope(PremiumScopes.changeAppIcon)) {
|
||||
// PlusLockedFeaturePopup.show(
|
||||
// context: context, feature: PremiumFeature.appiconchange);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Navigator.of(context, rootNavigator: true).push(
|
||||
// CupertinoPageRoute(builder: (context) => const ModifyAppIcon()),
|
||||
// );
|
||||
// },
|
||||
// title: Text('custom_app_icon'.i18n),
|
||||
// leading: const Icon(FeatherIcons.edit),
|
||||
// );
|
||||
return const SizedBox(
|
||||
width: 0,
|
||||
height: 0,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ModifyAppIcon extends StatefulWidget {
|
||||
const ModifyAppIcon({super.key});
|
||||
|
||||
@override
|
||||
State<ModifyAppIcon> createState() => _ModifyAppIconState();
|
||||
}
|
||||
|
||||
class _ModifyAppIconState extends State<ModifyAppIcon> {
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
|
||||
late SettingsProvider settings;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
settings = Provider.of<SettingsProvider>(context);
|
||||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: AppBar(
|
||||
surfaceTintColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
leading: BackButton(color: AppColors.of(context).text),
|
||||
title: Text(
|
||||
"app_icons".i18n,
|
||||
style: TextStyle(color: AppColors.of(context).text),
|
||||
),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 24.0),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Panel(
|
||||
title: Text("basic".i18n),
|
||||
child: Column(
|
||||
children: [
|
||||
AppIconItem(
|
||||
iconName: 'refilc_default',
|
||||
iconPath: 'assets/launch_icons/refilc_default.png',
|
||||
displayName: 'reFilc Default',
|
||||
description: 'Az alapértelmezett ikon.',
|
||||
selected: settings.appIcon == 'refilc_default',
|
||||
selectCallback: () async {
|
||||
await AppIconHelper.setAppIcon('refilc_default');
|
||||
settings.update(appIcon: 'refilc_default');
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// const SizedBox(height: 16.0),
|
||||
// Panel(
|
||||
// title: Text("seasonal".i18n),
|
||||
// child: Column(
|
||||
// children: [
|
||||
// // AppIconItem(
|
||||
// // iconName: 'refilc_default',
|
||||
// // iconPath: 'assets/launch_icons/refilc_default.png',
|
||||
// // displayName: 'reFilc Default',
|
||||
// // description: 'Az alapértelmezett ikon.',
|
||||
// // selected: true,
|
||||
// // selectCallback: () {},
|
||||
// // ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
const SizedBox(height: 16.0),
|
||||
Panel(
|
||||
title: Text("special".i18n),
|
||||
child: Column(
|
||||
children: [
|
||||
AppIconItem(
|
||||
iconName: 'refilc_overcomplicated',
|
||||
iconPath:
|
||||
'assets/launch_icons/refilc_overcomplicated.png',
|
||||
displayName: 'Overcomplicated',
|
||||
// description: 'Egy túlkomplikált ikon.',
|
||||
selected: settings.appIcon == 'refilc_overcomplicated',
|
||||
selectCallback: () async {
|
||||
await AppIconHelper.setAppIcon(
|
||||
'refilc_overcomplicated');
|
||||
settings.update(appIcon: 'refilc_overcomplicated');
|
||||
},
|
||||
),
|
||||
AppIconItem(
|
||||
iconName: 'refilc_concept',
|
||||
iconPath: 'assets/launch_icons/refilc_concept.png',
|
||||
displayName: 'Modern Concept',
|
||||
// description: 'Egy modernebb, letisztultabb ikon.',
|
||||
selected: settings.appIcon == 'refilc_concept',
|
||||
selectCallback: () async {
|
||||
await AppIconHelper.setAppIcon('refilc_concept');
|
||||
settings.update(appIcon: 'refilc_concept');
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16.0),
|
||||
Panel(
|
||||
title: Text("other".i18n),
|
||||
child: Column(
|
||||
children: [
|
||||
AppIconItem(
|
||||
iconName: 'refilc_pride',
|
||||
iconPath: 'assets/launch_icons/refilc_pride.png',
|
||||
displayName: 'Pride',
|
||||
// description: '',
|
||||
selected: settings.appIcon == 'refilc_pride',
|
||||
selectCallback: () async {
|
||||
await AppIconHelper.setAppIcon('refilc_pride');
|
||||
settings.update(appIcon: 'refilc_pride');
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
class AppIconItem extends StatelessWidget {
|
||||
const AppIconItem({
|
||||
super.key,
|
||||
required this.iconName,
|
||||
required this.iconPath,
|
||||
required this.displayName,
|
||||
this.description,
|
||||
required this.selected,
|
||||
required this.selectCallback,
|
||||
});
|
||||
|
||||
final String iconName;
|
||||
final String iconPath;
|
||||
final String displayName;
|
||||
final String? description;
|
||||
final bool selected;
|
||||
final void Function() selectCallback;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListTile(
|
||||
minLeadingWidth: 32.0,
|
||||
dense: true,
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 0),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
|
||||
visualDensity: VisualDensity.compact,
|
||||
onTap: () {},
|
||||
leading: Container(
|
||||
height: 40,
|
||||
width: 40,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
image: DecorationImage(
|
||||
image: AssetImage(iconPath),
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
),
|
||||
title: InkWell(
|
||||
onTap: selectCallback,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
displayName,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 16,
|
||||
height: description == null ? 3.2 : 1.8,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
if (description != null)
|
||||
Text(
|
||||
description!,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14,
|
||||
color: AppColors.of(context).text.withOpacity(.75),
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
trailing: selected
|
||||
? Icon(
|
||||
FeatherIcons.checkCircle,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
)
|
||||
: const SizedBox(),
|
||||
);
|
||||
}
|
||||
}
|
36
lib/ui/mobile/settings/app_icon_screen.i18n.dart
Normal file
36
lib/ui/mobile/settings/app_icon_screen.i18n.dart
Normal file
|
@ -0,0 +1,36 @@
|
|||
import 'package:i18n_extension/i18n_extension.dart';
|
||||
|
||||
extension Localization on String {
|
||||
static final _t = Translations.byLocale("hu_hu") +
|
||||
{
|
||||
"en_en": {
|
||||
"custom_app_icon": "Custom App Icon",
|
||||
"app_icons": "App Icons",
|
||||
"basic": "Basic",
|
||||
"seasonal": "Seasonal",
|
||||
"special": "Special",
|
||||
"other": "Other",
|
||||
},
|
||||
"hu_hu": {
|
||||
"custom_app_icon": "Alkalmazásikon",
|
||||
"app_icons": "Alkalmazásikonok",
|
||||
"basic": "Egyszerű",
|
||||
"seasonal": "Szezonális",
|
||||
"special": "Különleges",
|
||||
"other": "Egyéb",
|
||||
},
|
||||
"de_de": {
|
||||
"custom_app_icon": "App-Symbol",
|
||||
"app_icons": "App-Symbole",
|
||||
"basic": "Basic",
|
||||
"seasonal": "Saisonal",
|
||||
"special": "Besonders",
|
||||
"other": "Andere",
|
||||
},
|
||||
};
|
||||
|
||||
String get i18n => localize(this, _t);
|
||||
String fill(List<Object> params) => localizeFill(this, params);
|
||||
String plural(int value) => localizePlural(value, this, _t);
|
||||
String version(Object modifier) => localizeVersion(modifier, this, _t);
|
||||
}
|
452
lib/ui/mobile/settings/modify_teacher_names.dart
Normal file
452
lib/ui/mobile/settings/modify_teacher_names.dart
Normal file
|
@ -0,0 +1,452 @@
|
|||
// import 'package:dropdown_button2/dropdown_button2.dart';
|
||||
// import 'package:refilc/api/providers/database_provider.dart';
|
||||
// import 'package:refilc/api/providers/user_provider.dart';
|
||||
// import 'package:refilc/models/settings.dart';
|
||||
// import 'package:refilc/theme/colors/colors.dart';
|
||||
// import 'package:refilc/utils/format.dart';
|
||||
// import 'package:refilc_kreta_api/models/teacher.dart';
|
||||
// import 'package:refilc_kreta_api/providers/absence_provider.dart';
|
||||
// import 'package:refilc_kreta_api/providers/grade_provider.dart';
|
||||
// import 'package:refilc_kreta_api/providers/timetable_provider.dart';
|
||||
// import 'package:refilc_mobile_ui/common/panel/panel.dart';
|
||||
// import 'package:refilc_mobile_ui/common/panel/panel_button.dart';
|
||||
// // import 'package:refilc_plus/models/premium_scopes.dart';
|
||||
// // import 'package:refilc_plus/providers/plus_provider.dart';
|
||||
// // import 'package:refilc_plus/ui/mobile/plus/upsell.dart';
|
||||
// import 'package:flutter/cupertino.dart';
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
// import 'package:provider/provider.dart';
|
||||
// import 'package:refilc_mobile_ui/screens/settings/modify_names.i18n.dart';
|
||||
|
||||
// class MenuRenamedTeachers extends StatelessWidget {
|
||||
// const MenuRenamedTeachers({Key? key, required this.settings})
|
||||
// : super(key: key);
|
||||
|
||||
// final SettingsProvider settings;
|
||||
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// return PanelButton(
|
||||
// padding: const EdgeInsets.only(left: 14.0),
|
||||
// onPressed: () {
|
||||
// // if (!Provider.of<PlusProvider>(context, listen: false)
|
||||
// // .hasScope(PremiumScopes.renameTeachers)) {
|
||||
// // PlusLockedFeaturePopup.show(
|
||||
// // context: context, feature: PremiumFeature.teacherrename);
|
||||
// // return;
|
||||
// // }
|
||||
|
||||
// Navigator.of(context, rootNavigator: true).push(
|
||||
// CupertinoPageRoute(builder: (context) => const ModifyTeacherNames()),
|
||||
// );
|
||||
// },
|
||||
// title: Text(
|
||||
// "rename_teachers".i18n,
|
||||
// style: TextStyle(
|
||||
// color: AppColors.of(context)
|
||||
// .text
|
||||
// .withOpacity(settings.renamedTeachersEnabled ? 1.0 : .5)),
|
||||
// ),
|
||||
// leading: settings.renamedTeachersEnabled
|
||||
// ? const Icon(FeatherIcons.users)
|
||||
// : Icon(FeatherIcons.users,
|
||||
// color: AppColors.of(context).text.withOpacity(.25)),
|
||||
// trailingDivider: true,
|
||||
// trailing: Switch(
|
||||
// onChanged: (v) async {
|
||||
// // if (!Provider.of<PlusProvider>(context, listen: false)
|
||||
// // .hasScope(PremiumScopes.renameTeachers)) {
|
||||
// // PlusLockedFeaturePopup.show(
|
||||
// // context: context, feature: PremiumFeature.teacherrename);
|
||||
// // return;
|
||||
// // }
|
||||
|
||||
// settings.update(renamedTeachersEnabled: v);
|
||||
// await Provider.of<GradeProvider>(context, listen: false)
|
||||
// .convertBySettings();
|
||||
// await Provider.of<TimetableProvider>(context, listen: false)
|
||||
// .convertBySettings();
|
||||
// await Provider.of<AbsenceProvider>(context, listen: false)
|
||||
// .convertBySettings();
|
||||
// },
|
||||
// value: settings.renamedTeachersEnabled,
|
||||
// activeColor: Theme.of(context).colorScheme.secondary,
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
// class ModifyTeacherNames extends StatefulWidget {
|
||||
// const ModifyTeacherNames({Key? key}) : super(key: key);
|
||||
|
||||
// @override
|
||||
// State<ModifyTeacherNames> createState() => _ModifyTeacherNamesState();
|
||||
// }
|
||||
|
||||
// class _ModifyTeacherNamesState extends State<ModifyTeacherNames> {
|
||||
// final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
// final _teacherName = TextEditingController();
|
||||
// String? selectedTeacherId;
|
||||
|
||||
// late List<Teacher> teachers;
|
||||
// late UserProvider user;
|
||||
// late DatabaseProvider dbProvider;
|
||||
// late SettingsProvider settings;
|
||||
|
||||
// @override
|
||||
// void initState() {
|
||||
// super.initState();
|
||||
// teachers = (Provider.of<GradeProvider>(context, listen: false)
|
||||
// .grades
|
||||
// .map((e) => e.teacher)
|
||||
// .toSet()
|
||||
// .toList()
|
||||
// ..sort((a, b) => a.name.compareTo(b.name)));
|
||||
// user = Provider.of<UserProvider>(context, listen: false);
|
||||
// dbProvider = Provider.of<DatabaseProvider>(context, listen: false);
|
||||
// }
|
||||
|
||||
// Future<Map<String, String>> fetchRenamedTeachers() async {
|
||||
// return await dbProvider.userQuery.renamedTeachers(userId: user.id!);
|
||||
// }
|
||||
|
||||
// void showRenameDialog() {
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// builder: (context) => StatefulBuilder(builder: (context, setS) {
|
||||
// return AlertDialog(
|
||||
// shape: const RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.all(Radius.circular(14.0))),
|
||||
// title: Text("rename_teacher".i18n),
|
||||
// content: Column(
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
// children: [
|
||||
// DropdownButton2(
|
||||
// items: teachers
|
||||
// .map((item) => DropdownMenuItem<String>(
|
||||
// value: item.id,
|
||||
// child: Text(
|
||||
// item.name,
|
||||
// style: TextStyle(
|
||||
// fontSize: 14,
|
||||
// fontWeight: FontWeight.bold,
|
||||
// color: AppColors.of(context).text,
|
||||
// ),
|
||||
// overflow: TextOverflow.ellipsis,
|
||||
// ),
|
||||
// ))
|
||||
// .toList(),
|
||||
// onChanged: (String? v) async {
|
||||
// final renamedSubs = await fetchRenamedTeachers();
|
||||
|
||||
// setS(() {
|
||||
// selectedTeacherId = v;
|
||||
|
||||
// if (renamedSubs.containsKey(selectedTeacherId)) {
|
||||
// _teacherName.text = renamedSubs[selectedTeacherId]!;
|
||||
// } else {
|
||||
// _teacherName.text = "";
|
||||
// }
|
||||
// });
|
||||
// },
|
||||
// iconStyleData: IconStyleData(
|
||||
// iconSize: 14,
|
||||
// iconEnabledColor: AppColors.of(context).text,
|
||||
// iconDisabledColor: AppColors.of(context).text,
|
||||
// ),
|
||||
// underline: const SizedBox(),
|
||||
// menuItemStyleData: MenuItemStyleData(height: 40,),
|
||||
// itemHeight: 40,
|
||||
// itemPadding: const EdgeInsets.only(left: 14, right: 14),
|
||||
// buttonWidth: 50,
|
||||
// dropdownWidth: 300,
|
||||
// dropdownPadding: null,
|
||||
// buttonDecoration: BoxDecoration(
|
||||
// borderRadius: BorderRadius.circular(8),
|
||||
// ),
|
||||
// dropdownDecoration: BoxDecoration(
|
||||
// borderRadius: BorderRadius.circular(14),
|
||||
// ),
|
||||
// dropdownElevation: 8,
|
||||
// scrollbarRadius: const Radius.circular(40),
|
||||
// scrollbarThickness: 6,
|
||||
// scrollbarAlwaysShow: true,
|
||||
// offset: const Offset(-10, -10),
|
||||
// buttonSplashColor: Colors.transparent,
|
||||
// customButton: Container(
|
||||
// width: double.infinity,
|
||||
// decoration: BoxDecoration(
|
||||
// border: Border.all(color: Colors.grey, width: 2),
|
||||
// borderRadius: BorderRadius.circular(12.0),
|
||||
// ),
|
||||
// padding: const EdgeInsets.symmetric(
|
||||
// vertical: 12.0, horizontal: 8.0),
|
||||
// child: Text(
|
||||
// selectedTeacherId == null
|
||||
// ? "select_teacher".i18n
|
||||
// : teachers
|
||||
// .firstWhere(
|
||||
// (element) => element.id == selectedTeacherId,
|
||||
// orElse: () => Teacher(
|
||||
// id: 'noid', name: "select_teacher".i18n),
|
||||
// )
|
||||
// .name,
|
||||
// style: Theme.of(context).textTheme.titleSmall!.copyWith(
|
||||
// fontWeight: FontWeight.w700,
|
||||
// color: AppColors.of(context).text.withOpacity(0.75)),
|
||||
// overflow: TextOverflow.ellipsis,
|
||||
// maxLines: 2,
|
||||
// textAlign: TextAlign.center,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// const Padding(
|
||||
// padding: EdgeInsets.symmetric(vertical: 8.0),
|
||||
// child: Icon(FeatherIcons.arrowDown, size: 32),
|
||||
// ),
|
||||
// TextField(
|
||||
// controller: _teacherName,
|
||||
// decoration: InputDecoration(
|
||||
// border: OutlineInputBorder(
|
||||
// borderSide:
|
||||
// const BorderSide(color: Colors.grey, width: 1.5),
|
||||
// borderRadius: BorderRadius.circular(12.0),
|
||||
// ),
|
||||
// focusedBorder: OutlineInputBorder(
|
||||
// borderSide:
|
||||
// const BorderSide(color: Colors.grey, width: 1.5),
|
||||
// borderRadius: BorderRadius.circular(12.0),
|
||||
// ),
|
||||
// contentPadding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||
// hintText: "modified_name".i18n,
|
||||
// suffixIcon: IconButton(
|
||||
// icon: const Icon(
|
||||
// FeatherIcons.x,
|
||||
// color: Colors.grey,
|
||||
// ),
|
||||
// onPressed: () {
|
||||
// setState(() {
|
||||
// _teacherName.text = "";
|
||||
// });
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// actions: [
|
||||
// TextButton(
|
||||
// child: Text(
|
||||
// "cancel".i18n,
|
||||
// style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
// ),
|
||||
// onPressed: () {
|
||||
// Navigator.of(context).maybePop();
|
||||
// },
|
||||
// ),
|
||||
// TextButton(
|
||||
// child: Text(
|
||||
// "done".i18n,
|
||||
// style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
// ),
|
||||
// onPressed: () async {
|
||||
// if (selectedTeacherId != null) {
|
||||
// final renamedSubs = await fetchRenamedTeachers();
|
||||
|
||||
// renamedSubs[selectedTeacherId!] = _teacherName.text;
|
||||
// await dbProvider.userStore
|
||||
// .storeRenamedTeachers(renamedSubs, userId: user.id!);
|
||||
// await Provider.of<GradeProvider>(context, listen: false)
|
||||
// .convertBySettings();
|
||||
// await Provider.of<TimetableProvider>(context, listen: false)
|
||||
// .convertBySettings();
|
||||
// await Provider.of<AbsenceProvider>(context, listen: false)
|
||||
// .convertBySettings();
|
||||
// }
|
||||
// Navigator.of(context).pop(true);
|
||||
// setState(() {});
|
||||
// },
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// }),
|
||||
// ).then((val) {
|
||||
// _teacherName.text = "";
|
||||
// selectedTeacherId = null;
|
||||
// });
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// settings = Provider.of<SettingsProvider>(context);
|
||||
// return Scaffold(
|
||||
// key: _scaffoldKey,
|
||||
// appBar: AppBar(
|
||||
// surfaceTintColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
// leading: BackButton(color: AppColors.of(context).text),
|
||||
// title: Text(
|
||||
// "modify_teachers".i18n,
|
||||
// style: TextStyle(color: AppColors.of(context).text),
|
||||
// ),
|
||||
// ),
|
||||
// body: Padding(
|
||||
// padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 24.0),
|
||||
// child: SingleChildScrollView(
|
||||
// child: Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// // Panel(
|
||||
// // child: SwitchListTile(
|
||||
|
||||
// // title: Text("italics_toggle".i18n),
|
||||
// // onChanged: (value) =>
|
||||
// // settings.update(renamedTeachersItalics: value),
|
||||
// // value: settings.renamedTeachersItalics,
|
||||
// // ),
|
||||
// // ),
|
||||
// // const SizedBox(
|
||||
// // height: 20,
|
||||
// // ),
|
||||
// InkWell(
|
||||
// onTap: showRenameDialog,
|
||||
// borderRadius: BorderRadius.circular(12.0),
|
||||
// child: Container(
|
||||
// width: double.infinity,
|
||||
// decoration: BoxDecoration(
|
||||
// border: Border.all(color: Colors.grey, width: 2),
|
||||
// borderRadius: BorderRadius.circular(12.0),
|
||||
// ),
|
||||
// padding: const EdgeInsets.symmetric(
|
||||
// vertical: 18.0, horizontal: 12.0),
|
||||
// child: Center(
|
||||
// child: Text(
|
||||
// "rename_new_teacher".i18n,
|
||||
// style: TextStyle(
|
||||
// fontWeight: FontWeight.w600,
|
||||
// fontSize: 18,
|
||||
// color: AppColors.of(context).text.withOpacity(.85),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// const SizedBox(
|
||||
// height: 30,
|
||||
// ),
|
||||
// FutureBuilder<Map<String, String>>(
|
||||
// future: fetchRenamedTeachers(),
|
||||
// builder: (context, snapshot) {
|
||||
// if (!snapshot.hasData || snapshot.data!.isEmpty) {
|
||||
// return Container();
|
||||
// }
|
||||
|
||||
// return Panel(
|
||||
// title: Text("renamed_teachers".i18n),
|
||||
// child: Column(
|
||||
// children: snapshot.data!.keys.map(
|
||||
// (key) {
|
||||
// Teacher? teacher = teachers.firstWhere(
|
||||
// (element) => key == element.id,
|
||||
// orElse: () => Teacher(id: 'noid', name: 'noname'),
|
||||
// );
|
||||
|
||||
// if (teacher.id == 'noid') {
|
||||
// return const SizedBox(
|
||||
// width: 0,
|
||||
// height: 0,
|
||||
// );
|
||||
// }
|
||||
|
||||
// String renameTo = snapshot.data![key]!;
|
||||
// return RenamedTeacherItem(
|
||||
// teacher: teacher,
|
||||
// renamedTo: renameTo,
|
||||
// modifyCallback: () {
|
||||
// setState(() {
|
||||
// selectedTeacherId = teacher.id;
|
||||
// _teacherName.text = renameTo;
|
||||
// });
|
||||
// showRenameDialog();
|
||||
// },
|
||||
// removeCallback: () {
|
||||
// setState(() {
|
||||
// Map<String, String> subs =
|
||||
// Map.from(snapshot.data!);
|
||||
// subs.remove(key);
|
||||
// dbProvider.userStore.storeRenamedTeachers(
|
||||
// subs,
|
||||
// userId: user.id!);
|
||||
// });
|
||||
// },
|
||||
// );
|
||||
// },
|
||||
// ).toList(),
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ));
|
||||
// }
|
||||
// }
|
||||
|
||||
// class RenamedTeacherItem extends StatelessWidget {
|
||||
// const RenamedTeacherItem({
|
||||
// Key? key,
|
||||
// required this.teacher,
|
||||
// required this.renamedTo,
|
||||
// required this.modifyCallback,
|
||||
// required this.removeCallback,
|
||||
// }) : super(key: key);
|
||||
|
||||
// final Teacher teacher;
|
||||
// final String renamedTo;
|
||||
// final void Function() modifyCallback;
|
||||
// final void Function() removeCallback;
|
||||
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// return ListTile(
|
||||
// minLeadingWidth: 32.0,
|
||||
// dense: true,
|
||||
// contentPadding:
|
||||
// const EdgeInsets.symmetric(horizontal: 16.0, vertical: 6.0),
|
||||
// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
|
||||
// visualDensity: VisualDensity.compact,
|
||||
// onTap: () {},
|
||||
// leading: Icon(FeatherIcons.user,
|
||||
// color: AppColors.of(context).text.withOpacity(.75)),
|
||||
// title: InkWell(
|
||||
// onTap: modifyCallback,
|
||||
// child: Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// Text(
|
||||
// teacher.name.capital(),
|
||||
// style: TextStyle(
|
||||
// fontWeight: FontWeight.w500,
|
||||
// fontSize: 14,
|
||||
// color: AppColors.of(context).text.withOpacity(.75)),
|
||||
// maxLines: 1,
|
||||
// overflow: TextOverflow.ellipsis,
|
||||
// ),
|
||||
// Text(
|
||||
// renamedTo,
|
||||
// style: const TextStyle(fontWeight: FontWeight.w500, fontSize: 16),
|
||||
// maxLines: 2,
|
||||
// overflow: TextOverflow.ellipsis,
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// trailing: InkWell(
|
||||
// onTap: removeCallback,
|
||||
// child: Icon(FeatherIcons.trash,
|
||||
// color: AppColors.of(context).red.withOpacity(.75)),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
143
lib/ui/mobile/settings/settings_helper.dart
Normal file
143
lib/ui/mobile/settings/settings_helper.dart
Normal file
|
@ -0,0 +1,143 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:refilc/api/providers/database_provider.dart';
|
||||
import 'package:refilc/api/providers/user_provider.dart';
|
||||
import 'package:refilc/models/settings.dart';
|
||||
import 'package:refilc/ui/widgets/grade/grade_tile.dart';
|
||||
import 'package:refilc_kreta_api/models/grade.dart';
|
||||
|
||||
class GradeRarityTextSetting extends StatefulWidget {
|
||||
const GradeRarityTextSetting({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.cancel,
|
||||
required this.done,
|
||||
required this.defaultRarities,
|
||||
});
|
||||
|
||||
final String title;
|
||||
final String cancel;
|
||||
final String done;
|
||||
final List<String> defaultRarities;
|
||||
|
||||
@override
|
||||
GradeRarityTextSettingState createState() => GradeRarityTextSettingState();
|
||||
}
|
||||
|
||||
class GradeRarityTextSettingState extends State<GradeRarityTextSetting> {
|
||||
late SettingsProvider settings;
|
||||
late DatabaseProvider db;
|
||||
late UserProvider user;
|
||||
|
||||
final _rarityText = TextEditingController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
settings = Provider.of<SettingsProvider>(context, listen: false);
|
||||
db = Provider.of<DatabaseProvider>(context, listen: false);
|
||||
user = Provider.of<UserProvider>(context, listen: false);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: List.generate(5, (index) {
|
||||
return ClipOval(
|
||||
child: Material(
|
||||
type: MaterialType.transparency,
|
||||
child: InkWell(
|
||||
onTap: () async {
|
||||
showRenameDialog(
|
||||
title: widget.title,
|
||||
cancel: widget.cancel,
|
||||
done: widget.done,
|
||||
rarities:
|
||||
await db.userQuery.getGradeRarities(userId: user.id!),
|
||||
gradeIndex: (index + 1).toString(),
|
||||
defaultRarities: widget.defaultRarities,
|
||||
);
|
||||
},
|
||||
child: GradeValueWidget(GradeValue(index + 1, "", "", 0),
|
||||
fill: true, size: 36.0),
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
void showRenameDialog(
|
||||
{required String title,
|
||||
required String cancel,
|
||||
required String done,
|
||||
required Map<String, String> rarities,
|
||||
required String gradeIndex,
|
||||
required List<String> defaultRarities,
|
||||
required}) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => StatefulBuilder(builder: (context, setS) {
|
||||
String? rr = rarities[gradeIndex];
|
||||
rr ??= '';
|
||||
|
||||
_rarityText.text = rr;
|
||||
|
||||
return AlertDialog(
|
||||
title: Text(title),
|
||||
content: TextField(
|
||||
controller: _rarityText,
|
||||
autofocus: true,
|
||||
decoration: InputDecoration(
|
||||
border: const OutlineInputBorder(),
|
||||
label: Text(defaultRarities[int.parse(gradeIndex) - 1]),
|
||||
suffixIcon: IconButton(
|
||||
icon: const Icon(FeatherIcons.x),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_rarityText.clear();
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(
|
||||
cancel,
|
||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context).maybePop();
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: Text(
|
||||
done,
|
||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
),
|
||||
onPressed: () {
|
||||
rarities[gradeIndex] = _rarityText.text;
|
||||
|
||||
Provider.of<DatabaseProvider>(context, listen: false)
|
||||
.userStore
|
||||
.storeGradeRarities(rarities, userId: user.id!);
|
||||
|
||||
Navigator.of(context).pop(true);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
).then((val) {
|
||||
_rarityText.clear();
|
||||
});
|
||||
}
|
||||
}
|
26
lib/ui/mobile/settings/share_theme.dart
Normal file
26
lib/ui/mobile/settings/share_theme.dart
Normal file
|
@ -0,0 +1,26 @@
|
|||
import 'package:refilc/models/settings.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class PremiumShareTheme extends StatefulWidget {
|
||||
const PremiumShareTheme({super.key});
|
||||
|
||||
@override
|
||||
State<PremiumShareTheme> createState() => _PremiumShareThemeState();
|
||||
}
|
||||
|
||||
class _PremiumShareThemeState extends State<PremiumShareTheme>
|
||||
with TickerProviderStateMixin {
|
||||
late final SettingsProvider settingsProvider;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
settingsProvider = Provider.of<SettingsProvider>(context, listen: false);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Scaffold();
|
||||
}
|
||||
}
|
660
lib/ui/mobile/settings/submenu/calendar_sync.dart
Normal file
660
lib/ui/mobile/settings/submenu/calendar_sync.dart
Normal file
|
@ -0,0 +1,660 @@
|
|||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:refilc/api/providers/user_provider.dart';
|
||||
import 'package:refilc/models/linked_account.dart';
|
||||
import 'package:refilc/models/settings.dart';
|
||||
import 'package:refilc/providers/third_party_provider.dart';
|
||||
import 'package:refilc/theme/colors/colors.dart';
|
||||
import 'package:refilc_kreta_api/providers/share_provider.dart';
|
||||
import 'package:refilc_mobile_ui/common/dot.dart';
|
||||
import 'package:refilc_mobile_ui/common/panel/panel_button.dart';
|
||||
import 'package:refilc_mobile_ui/common/splitted_panel/splitted_panel.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:refilc_mobile_ui/common/widgets/custom_segmented_control.dart';
|
||||
import 'package:refilc_mobile_ui/screens/settings/settings_screen.i18n.dart';
|
||||
import 'package:refilc_plus/models/premium_scopes.dart';
|
||||
import 'package:refilc_plus/providers/plus_provider.dart';
|
||||
import 'package:refilc_plus/ui/mobile/plus/upsell.dart';
|
||||
|
||||
class MenuCalendarSync extends StatelessWidget {
|
||||
const MenuCalendarSync({
|
||||
super.key,
|
||||
this.borderRadius = const BorderRadius.vertical(
|
||||
top: Radius.circular(4.0), bottom: Radius.circular(4.0)),
|
||||
});
|
||||
|
||||
final BorderRadius borderRadius;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PanelButton(
|
||||
onPressed: () async {
|
||||
// if (!Provider.of<PlusProvider>(context, listen: false)
|
||||
// .hasScope(PremiumScopes.calendarSync)) {
|
||||
// return PlusLockedFeaturePopup.show(
|
||||
// context: context, feature: PremiumFeature.calendarSync);
|
||||
// }
|
||||
|
||||
// Navigator.of(context, rootNavigator: true).push(CupertinoPageRoute(
|
||||
// builder: (context) => const CalendarSyncScreen()));
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text("Figyelem!"),
|
||||
content: const Text(
|
||||
"A naptár szinkronizálás csak azután fog működni, hogy a Google elfogadja az OAuth kérelmünket, addig is szíves türelmeteket kérjük! Amint ez megtörténik, értesíteni fogunk titeket Discord-on, valamint alkalmazáson belüli hírekben is."),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: const Text(
|
||||
"Vissza",
|
||||
style: TextStyle(fontWeight: FontWeight.w500),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: const Text(
|
||||
"Tovább",
|
||||
style: TextStyle(fontWeight: FontWeight.w500),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
|
||||
if (!Provider.of<PlusProvider>(context, listen: false)
|
||||
.hasScope(PremiumScopes.calendarSync)) {
|
||||
return PlusLockedFeaturePopup.show(
|
||||
context: context, feature: PremiumFeature.calendarSync);
|
||||
}
|
||||
|
||||
Navigator.of(context, rootNavigator: true).push(
|
||||
CupertinoPageRoute(
|
||||
builder: (context) => const CalendarSyncScreen()));
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
title: Text(
|
||||
"calendar_sync".i18n,
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context).text.withOpacity(.95),
|
||||
),
|
||||
),
|
||||
leading: Icon(
|
||||
FeatherIcons.calendar,
|
||||
size: 22.0,
|
||||
color: AppColors.of(context).text.withOpacity(.95),
|
||||
),
|
||||
trailing: Icon(
|
||||
FeatherIcons.chevronRight,
|
||||
size: 22.0,
|
||||
color: AppColors.of(context).text.withOpacity(0.95),
|
||||
),
|
||||
borderRadius: borderRadius,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CalendarSyncScreen extends StatefulWidget {
|
||||
const CalendarSyncScreen({super.key});
|
||||
|
||||
@override
|
||||
CalendarSyncScreenState createState() => CalendarSyncScreenState();
|
||||
}
|
||||
|
||||
class CalendarSyncScreenState extends State<CalendarSyncScreen>
|
||||
with SingleTickerProviderStateMixin {
|
||||
late SettingsProvider settingsProvider;
|
||||
late UserProvider user;
|
||||
late ShareProvider shareProvider;
|
||||
late ThirdPartyProvider thirdPartyProvider;
|
||||
|
||||
late AnimationController _hideContainersController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
shareProvider = Provider.of<ShareProvider>(context, listen: false);
|
||||
|
||||
_hideContainersController = AnimationController(
|
||||
vsync: this, duration: const Duration(milliseconds: 200));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
settingsProvider = Provider.of<SettingsProvider>(context);
|
||||
user = Provider.of<UserProvider>(context);
|
||||
thirdPartyProvider = Provider.of<ThirdPartyProvider>(context);
|
||||
|
||||
return AnimatedBuilder(
|
||||
animation: _hideContainersController,
|
||||
builder: (context, child) => Opacity(
|
||||
opacity: 1 - _hideContainersController.value,
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
surfaceTintColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
leading: BackButton(color: AppColors.of(context).text),
|
||||
title: Text(
|
||||
"calendar_sync".i18n,
|
||||
style: TextStyle(color: AppColors.of(context).text),
|
||||
),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 16.0, horizontal: 24.0),
|
||||
child: Column(
|
||||
children: [
|
||||
// banner
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12.0),
|
||||
image: const DecorationImage(
|
||||
image: AssetImage(
|
||||
'assets/images/banner_texture.png',
|
||||
),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 40,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16.0),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.2),
|
||||
blurRadius: 4.0,
|
||||
spreadRadius: 0.01,
|
||||
),
|
||||
],
|
||||
),
|
||||
height: 64,
|
||||
width: 64,
|
||||
child: const Icon(
|
||||
Icons.calendar_month,
|
||||
color: Colors.black,
|
||||
size: 38.0,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Icon(
|
||||
Icons.sync_alt_outlined,
|
||||
color: Colors.black.withOpacity(
|
||||
thirdPartyProvider.linkedAccounts.isEmpty
|
||||
? 0.2
|
||||
: 0.5),
|
||||
size: 20.0,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(16.0),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.2),
|
||||
blurRadius: 4.0,
|
||||
spreadRadius: 0.01,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Image.asset(
|
||||
'assets/icons/ic_rounded.png',
|
||||
width: 64,
|
||||
height: 64,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(
|
||||
height: 18.0,
|
||||
),
|
||||
// choose account if not logged in
|
||||
if (thirdPartyProvider.linkedAccounts.isEmpty)
|
||||
Column(
|
||||
children: [
|
||||
if (Platform.isAndroid)
|
||||
SplittedPanel(
|
||||
title: Text('choose_account'.i18n),
|
||||
padding: EdgeInsets.zero,
|
||||
cardPadding: const EdgeInsets.all(4.0),
|
||||
isSeparated: true,
|
||||
children: [
|
||||
PanelButton(
|
||||
onPressed: () async {
|
||||
await Provider.of<ThirdPartyProvider>(context,
|
||||
listen: false)
|
||||
.googleSignIn();
|
||||
|
||||
setState(() {});
|
||||
},
|
||||
title: Text(
|
||||
'Google',
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context)
|
||||
.text
|
||||
.withOpacity(.95),
|
||||
),
|
||||
),
|
||||
leading: Image.asset(
|
||||
'assets/images/ext_logo/google.png',
|
||||
width: 24.0,
|
||||
height: 24.0,
|
||||
),
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(12),
|
||||
bottom: Radius.circular(12),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
// const SizedBox(
|
||||
// height: 9.0,
|
||||
// ),
|
||||
if (Platform.isIOS)
|
||||
SplittedPanel(
|
||||
padding: EdgeInsets.zero,
|
||||
cardPadding: const EdgeInsets.all(4.0),
|
||||
isSeparated: true,
|
||||
children: [
|
||||
PanelButton(
|
||||
onPressed: null,
|
||||
title: Text(
|
||||
'Apple',
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context)
|
||||
.text
|
||||
.withOpacity(.55),
|
||||
decoration: TextDecoration.lineThrough,
|
||||
),
|
||||
),
|
||||
leading: Image.asset(
|
||||
'assets/images/ext_logo/apple.png',
|
||||
width: 24.0,
|
||||
height: 24.0,
|
||||
),
|
||||
trailing: Text(
|
||||
'soon'.i18n,
|
||||
style: const TextStyle(
|
||||
fontStyle: FontStyle.italic,
|
||||
fontSize: 14.0),
|
||||
),
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(12),
|
||||
bottom: Radius.circular(12),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(
|
||||
height: 10.0,
|
||||
),
|
||||
const Text(
|
||||
"A naptár szinkronizálás csak azután fog működni, hogy a Google elfogadja az OAuth kérelmünket, addig is szíves türelmeteket kérjük! Amint ez megtörténik, értesíteni fogunk titeket Discord-on, valamint alkalmazáson belüli hírekben is."),
|
||||
],
|
||||
),
|
||||
|
||||
// show options if logged in
|
||||
if (thirdPartyProvider.linkedAccounts.isNotEmpty)
|
||||
Column(
|
||||
children: [
|
||||
SplittedPanel(
|
||||
title: Text('your_account'.i18n),
|
||||
padding: EdgeInsets.zero,
|
||||
cardPadding: const EdgeInsets.all(4.0),
|
||||
children: [
|
||||
PanelButton(
|
||||
onPressed: null,
|
||||
title: Text(
|
||||
thirdPartyProvider
|
||||
.linkedAccounts.first.username,
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context)
|
||||
.text
|
||||
.withOpacity(.95),
|
||||
),
|
||||
),
|
||||
leading: Image.asset(
|
||||
'assets/images/ext_logo/${thirdPartyProvider.linkedAccounts.first.type == AccountType.google ? "google" : "apple"}.png',
|
||||
width: 24.0,
|
||||
height: 24.0,
|
||||
),
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(12),
|
||||
bottom: Radius.circular(12),
|
||||
),
|
||||
),
|
||||
PanelButton(
|
||||
onPressed: () async {
|
||||
await thirdPartyProvider.signOutAll();
|
||||
setState(() {});
|
||||
},
|
||||
title: Text(
|
||||
'change_account'.i18n,
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context)
|
||||
.text
|
||||
.withOpacity(.95),
|
||||
),
|
||||
),
|
||||
trailing: Icon(
|
||||
FeatherIcons.chevronRight,
|
||||
size: 22.0,
|
||||
color: AppColors.of(context)
|
||||
.text
|
||||
.withOpacity(0.95),
|
||||
),
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(12),
|
||||
bottom: Radius.circular(12),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 18.0,
|
||||
),
|
||||
SplittedPanel(
|
||||
title: Text('choose_calendar'.i18n),
|
||||
padding: EdgeInsets.zero,
|
||||
cardPadding: EdgeInsets.zero,
|
||||
isTransparent: true,
|
||||
children: getCalendarList(),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 18.0,
|
||||
),
|
||||
SplittedPanel(
|
||||
title: Text('room_num_location'.i18n),
|
||||
padding: EdgeInsets.zero,
|
||||
cardPadding: EdgeInsets.zero,
|
||||
isTransparent: true,
|
||||
children: [
|
||||
CustomSegmentedControl(
|
||||
onChanged: (v) {
|
||||
settingsProvider.update(
|
||||
calSyncRoomLocation:
|
||||
v == 0 ? 'location' : 'description');
|
||||
},
|
||||
value: settingsProvider.calSyncRoomLocation ==
|
||||
'location'
|
||||
? 0
|
||||
: 1,
|
||||
height: 45,
|
||||
children: [
|
||||
Text(
|
||||
'location'.i18n,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 16.0,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'description'.i18n,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 16.0,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 18.0,
|
||||
),
|
||||
SplittedPanel(
|
||||
title: Text('options'.i18n),
|
||||
padding: EdgeInsets.zero,
|
||||
cardPadding: EdgeInsets.zero,
|
||||
isTransparent: true,
|
||||
isSeparated: true,
|
||||
children: [
|
||||
SplittedPanel(
|
||||
padding: EdgeInsets.zero,
|
||||
cardPadding: const EdgeInsets.all(4.0),
|
||||
children: [
|
||||
PanelButton(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 14.0, right: 6.0),
|
||||
onPressed: () async {
|
||||
settingsProvider.update(
|
||||
calSyncShowExams:
|
||||
!settingsProvider.calSyncShowExams);
|
||||
|
||||
setState(() {});
|
||||
},
|
||||
title: Text(
|
||||
"show_exams".i18n,
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context)
|
||||
.text
|
||||
.withOpacity(
|
||||
settingsProvider.calSyncShowExams
|
||||
? .95
|
||||
: .25),
|
||||
),
|
||||
),
|
||||
trailing: Switch(
|
||||
onChanged: (v) async {
|
||||
settingsProvider.update(
|
||||
calSyncShowExams: v);
|
||||
|
||||
setState(() {});
|
||||
},
|
||||
value: settingsProvider.calSyncShowExams,
|
||||
activeColor:
|
||||
Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(12.0),
|
||||
bottom: Radius.circular(12.0),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SplittedPanel(
|
||||
padding: EdgeInsets.zero,
|
||||
cardPadding: const EdgeInsets.all(4.0),
|
||||
children: [
|
||||
PanelButton(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 14.0, right: 6.0),
|
||||
onPressed: () async {
|
||||
settingsProvider.update(
|
||||
calSyncShowTeacher: !settingsProvider
|
||||
.calSyncShowTeacher);
|
||||
|
||||
setState(() {});
|
||||
},
|
||||
title: Text(
|
||||
"show_teacher".i18n,
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context)
|
||||
.text
|
||||
.withOpacity(settingsProvider
|
||||
.calSyncShowTeacher
|
||||
? .95
|
||||
: .25),
|
||||
),
|
||||
),
|
||||
trailing: Switch(
|
||||
onChanged: (v) async {
|
||||
settingsProvider.update(
|
||||
calSyncShowTeacher: v);
|
||||
|
||||
setState(() {});
|
||||
},
|
||||
value: settingsProvider.calSyncShowTeacher,
|
||||
activeColor:
|
||||
Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(12.0),
|
||||
bottom: Radius.circular(12.0),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SplittedPanel(
|
||||
padding: EdgeInsets.zero,
|
||||
cardPadding: const EdgeInsets.all(4.0),
|
||||
children: [
|
||||
PanelButton(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 14.0, right: 6.0),
|
||||
onPressed: () async {
|
||||
settingsProvider.update(
|
||||
calSyncRenamed:
|
||||
!settingsProvider.calSyncRenamed);
|
||||
|
||||
setState(() {});
|
||||
},
|
||||
title: Text(
|
||||
"show_renamed".i18n,
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context)
|
||||
.text
|
||||
.withOpacity(
|
||||
settingsProvider.calSyncRenamed
|
||||
? .95
|
||||
: .25),
|
||||
),
|
||||
),
|
||||
trailing: Switch(
|
||||
onChanged: (v) async {
|
||||
settingsProvider.update(
|
||||
calSyncRenamed: v);
|
||||
|
||||
setState(() {});
|
||||
},
|
||||
value: settingsProvider.calSyncRenamed,
|
||||
activeColor:
|
||||
Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(12.0),
|
||||
bottom: Radius.circular(12.0),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> getCalendarList() {
|
||||
// List<Widget> widgets = thirdPartyProvider.googleCalendars
|
||||
// .map(
|
||||
// (e) => Container(
|
||||
// margin: const EdgeInsets.only(bottom: 3.0),
|
||||
// decoration: BoxDecoration(
|
||||
// border: Border.all(
|
||||
// color: Theme.of(context).colorScheme.primary.withOpacity(.25),
|
||||
// width: 1.0,
|
||||
// ),
|
||||
// borderRadius: BorderRadius.circular(12.0),
|
||||
// ),
|
||||
// child: PanelButton(
|
||||
// onPressed: () async {
|
||||
// print((e.backgroundColor ?? '#000000').replaceAll('#', '0x'));
|
||||
// setState(() {});
|
||||
// },
|
||||
// title: Text(
|
||||
// e.summary ?? 'no_title'.i18n,
|
||||
// style: TextStyle(
|
||||
// color: AppColors.of(context).text.withOpacity(.95),
|
||||
// ),
|
||||
// ),
|
||||
// leading: Dot(
|
||||
// color: colorFromHex(
|
||||
// e.backgroundColor ?? '#000',
|
||||
// ) ??
|
||||
// Colors.black,
|
||||
// ),
|
||||
// borderRadius: const BorderRadius.vertical(
|
||||
// top: Radius.circular(12),
|
||||
// bottom: Radius.circular(12),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// )
|
||||
// .toList();
|
||||
|
||||
List<Widget> widgets = [];
|
||||
|
||||
widgets.add(
|
||||
Container(
|
||||
margin: const EdgeInsets.only(bottom: 3.0),
|
||||
decoration: BoxDecoration(
|
||||
// border: Border.all(
|
||||
// color: Theme.of(context).colorScheme.primary.withOpacity(.25),
|
||||
// width: 1.0,
|
||||
// ),
|
||||
color: AppColors.of(context).highlight,
|
||||
borderRadius: BorderRadius.circular(16.0),
|
||||
),
|
||||
child: PanelButton(
|
||||
onPressed: null,
|
||||
// onPressed: () async {
|
||||
// // thirdPartyProvider.pushTimetable(context, timetable);
|
||||
// setState(() {});
|
||||
// },
|
||||
title: Text(
|
||||
'reFilc - Órarend',
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context).text.withOpacity(.95),
|
||||
),
|
||||
),
|
||||
// leading: Icon(
|
||||
// FeatherIcons.plus,
|
||||
// size: 20.0,
|
||||
// color: AppColors.of(context).text.withOpacity(0.75),
|
||||
// ),
|
||||
leading: Dot(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(12),
|
||||
bottom: Radius.circular(12),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return widgets;
|
||||
}
|
||||
}
|
363
lib/ui/mobile/settings/submenu/grade_exporting.dart
Normal file
363
lib/ui/mobile/settings/submenu/grade_exporting.dart
Normal file
|
@ -0,0 +1,363 @@
|
|||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:refilc/api/providers/user_provider.dart';
|
||||
import 'package:refilc/models/settings.dart';
|
||||
import 'package:refilc/providers/third_party_provider.dart';
|
||||
import 'package:refilc/theme/colors/colors.dart';
|
||||
import 'package:refilc_kreta_api/models/grade.dart';
|
||||
import 'package:refilc_kreta_api/providers/grade_provider.dart';
|
||||
import 'package:refilc_kreta_api/providers/share_provider.dart';
|
||||
import 'package:refilc_mobile_ui/common/dot.dart';
|
||||
import 'package:refilc_mobile_ui/common/panel/panel_button.dart';
|
||||
import 'package:refilc_mobile_ui/common/splitted_panel/splitted_panel.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:refilc_mobile_ui/screens/settings/settings_screen.i18n.dart';
|
||||
import 'package:refilc_plus/models/premium_scopes.dart';
|
||||
import 'package:refilc_plus/providers/plus_provider.dart';
|
||||
import 'package:refilc_plus/ui/mobile/plus/upsell.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:refilc_mobile_ui/common/chips/new_chip.dart';
|
||||
|
||||
class MenuGradeExporting extends StatelessWidget {
|
||||
const MenuGradeExporting({
|
||||
super.key,
|
||||
this.borderRadius = const BorderRadius.vertical(
|
||||
top: Radius.circular(4.0), bottom: Radius.circular(4.0)),
|
||||
});
|
||||
|
||||
final BorderRadius borderRadius;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PanelButton(
|
||||
onPressed: () async {
|
||||
// if (!Provider.of<PlusProvider>(context, listen: false)
|
||||
// .hasScope(PremiumScopes.calendarSync)) {
|
||||
// return PlusLockedFeaturePopup.show(
|
||||
// context: context, feature: PremiumFeature.calendarSync);
|
||||
// }
|
||||
|
||||
// Navigator.of(context, rootNavigator: true).push(CupertinoPageRoute(
|
||||
// builder: (context) => const CalendarSyncScreen()));
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// builder: (context) => AlertDialog(
|
||||
// title: const Text("Figyelem!"),
|
||||
// content: const Text(
|
||||
// "Az exportált jegyek jelenleg még nem megtekinthetők a reFilc-ben, csak te magad tudod átnézni őket JSON formátumban. A jövőben ez a funkció bővülni fog, és a jegyeket meg is tekintheted majd a reFilc felületén."),
|
||||
// actions: [
|
||||
// // TextButton(
|
||||
// // child: const Text(
|
||||
// // "Vissza",
|
||||
// // style: TextStyle(fontWeight: FontWeight.w500),
|
||||
// // ),
|
||||
// // onPressed: () {
|
||||
// // Navigator.of(context).pop();
|
||||
// // },
|
||||
// // ),
|
||||
// TextButton(
|
||||
// child: const Text(
|
||||
// "Tovább",
|
||||
// style: TextStyle(fontWeight: FontWeight.w500),
|
||||
// ),
|
||||
// onPressed: () {
|
||||
// Navigator.of(context).pop();
|
||||
|
||||
Provider.of<SettingsProvider>(context, listen: false).update(
|
||||
unseenNewFeatures: List.from(
|
||||
Provider.of<SettingsProvider>(context, listen: false)
|
||||
.unseenNewFeatures
|
||||
..remove('grade_exporting'),
|
||||
),
|
||||
);
|
||||
// Provider.of<SettingsProvider>(context, listen: false).update(
|
||||
// unseenNewFeatures: ['grade_exporting'],
|
||||
// );
|
||||
|
||||
if (!Provider.of<PlusProvider>(context, listen: false)
|
||||
.hasScope(PremiumScopes.gradeExporting)) {
|
||||
return PlusLockedFeaturePopup.show(
|
||||
context: context, feature: PremiumFeature.gradeExporting);
|
||||
}
|
||||
|
||||
Navigator.of(context, rootNavigator: true).push(CupertinoPageRoute(
|
||||
builder: (context) => const GradeExportingScreen()));
|
||||
// },
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
},
|
||||
title: Text(
|
||||
"grade_exporting".i18n,
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context).text.withOpacity(.95),
|
||||
),
|
||||
),
|
||||
leading: Icon(
|
||||
Icons.toll_rounded,
|
||||
size: 22.0,
|
||||
color: AppColors.of(context).text.withOpacity(.95),
|
||||
),
|
||||
trailing: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (Provider.of<SettingsProvider>(context)
|
||||
.unseenNewFeatures
|
||||
.contains('grade_exporting'))
|
||||
const NewChip(),
|
||||
Icon(
|
||||
FeatherIcons.chevronRight,
|
||||
size: 22.0,
|
||||
color: AppColors.of(context).text.withOpacity(0.95),
|
||||
)
|
||||
],
|
||||
),
|
||||
borderRadius: borderRadius,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class GradeExportingScreen extends StatefulWidget {
|
||||
const GradeExportingScreen({super.key});
|
||||
|
||||
@override
|
||||
CalendarSyncScreenState createState() => CalendarSyncScreenState();
|
||||
}
|
||||
|
||||
class CalendarSyncScreenState extends State<GradeExportingScreen>
|
||||
with SingleTickerProviderStateMixin {
|
||||
late SettingsProvider settingsProvider;
|
||||
late UserProvider user;
|
||||
late ShareProvider shareProvider;
|
||||
late ThirdPartyProvider thirdPartyProvider;
|
||||
|
||||
late AnimationController _hideContainersController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
shareProvider = Provider.of<ShareProvider>(context, listen: false);
|
||||
|
||||
_hideContainersController = AnimationController(
|
||||
vsync: this, duration: const Duration(milliseconds: 200));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
settingsProvider = Provider.of<SettingsProvider>(context);
|
||||
user = Provider.of<UserProvider>(context);
|
||||
thirdPartyProvider = Provider.of<ThirdPartyProvider>(context);
|
||||
|
||||
return AnimatedBuilder(
|
||||
animation: _hideContainersController,
|
||||
builder: (context, child) => Opacity(
|
||||
opacity: 1 - _hideContainersController.value,
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
surfaceTintColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
leading: BackButton(color: AppColors.of(context).text),
|
||||
title: Text(
|
||||
"grade_exporting".i18n,
|
||||
style: TextStyle(color: AppColors.of(context).text),
|
||||
),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 16.0, horizontal: 24.0),
|
||||
child: Column(
|
||||
children: [
|
||||
// choose export method
|
||||
Column(
|
||||
children: [
|
||||
SplittedPanel(
|
||||
title: Text('export_method'.i18n),
|
||||
padding: EdgeInsets.zero,
|
||||
cardPadding: const EdgeInsets.all(4.0),
|
||||
isSeparated: true,
|
||||
children: [
|
||||
PanelButton(
|
||||
onPressed: () async {
|
||||
// get all grades
|
||||
List<Grade> grades = Provider.of<GradeProvider>(
|
||||
context,
|
||||
listen: false)
|
||||
.grades;
|
||||
|
||||
// gmake a list of grades in json format
|
||||
List<Map<dynamic, dynamic>> gradesList = [
|
||||
for (Grade grade in grades)
|
||||
// {
|
||||
// '"subject"': '"${grade.subject.name}"',
|
||||
// '"value"': grade.value.value,
|
||||
// '"value_name"':
|
||||
// '"${grade.value.valueName}"',
|
||||
// '"date"':
|
||||
// '"${grade.date.toIso8601String()}"',
|
||||
// '"weight"': grade.value.weight,
|
||||
// '"type"': '"${grade.type.name}"',
|
||||
// '"description"': '"${grade.description}"',
|
||||
// '"teacher"': '"${grade.teacher.name}"',
|
||||
// }
|
||||
grade.json ?? {},
|
||||
];
|
||||
|
||||
// convert list to json file
|
||||
final directory = await getTemporaryDirectory();
|
||||
|
||||
File file = File('${directory.path}/grades.json');
|
||||
file.writeAsStringSync(
|
||||
jsonEncode(gradesList),
|
||||
);
|
||||
|
||||
// convert json to bytes
|
||||
final jsonBytes = file.readAsBytesSync();
|
||||
|
||||
// get current study year
|
||||
final now = DateTime.now();
|
||||
String studyYearStr = '';
|
||||
if (now.month <= 8) {
|
||||
studyYearStr = '${now.year - 1}_${now.year}';
|
||||
} else {
|
||||
studyYearStr = '${now.year}_${now.year + 1}';
|
||||
}
|
||||
|
||||
// open the share popup with the json file
|
||||
Share.shareXFiles(
|
||||
[
|
||||
XFile.fromData(
|
||||
jsonBytes,
|
||||
name: 'refilc_grades_$studyYearStr',
|
||||
mimeType: 'application/json',
|
||||
),
|
||||
],
|
||||
subject:
|
||||
'reFilc Jegyek - ${studyYearStr.replaceAll('_', '/')}',
|
||||
);
|
||||
},
|
||||
title: Text(
|
||||
'JSON',
|
||||
style: TextStyle(
|
||||
color:
|
||||
AppColors.of(context).text.withOpacity(.95),
|
||||
),
|
||||
),
|
||||
// leading: Image.asset(
|
||||
// 'assets/images/ext_logo/google.png',
|
||||
// width: 24.0,
|
||||
// height: 24.0,
|
||||
// ),
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(12),
|
||||
bottom: Radius.circular(12),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
// const SizedBox(
|
||||
// height: 10.0,
|
||||
// ),
|
||||
// const Text(
|
||||
// "Az exportált jegyek jelenleg még nem megtekinthetők a reFilc-ben, csak te magad tudod átnézni őket JSON formátumban. A jövőben ez a funkció bővülni fog, és a jegyeket meg is tekintheted majd a reFilc felületén."),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> getCalendarList() {
|
||||
// List<Widget> widgets = thirdPartyProvider.googleCalendars
|
||||
// .map(
|
||||
// (e) => Container(
|
||||
// margin: const EdgeInsets.only(bottom: 3.0),
|
||||
// decoration: BoxDecoration(
|
||||
// border: Border.all(
|
||||
// color: Theme.of(context).colorScheme.primary.withOpacity(.25),
|
||||
// width: 1.0,
|
||||
// ),
|
||||
// borderRadius: BorderRadius.circular(12.0),
|
||||
// ),
|
||||
// child: PanelButton(
|
||||
// onPressed: () async {
|
||||
// print((e.backgroundColor ?? '#000000').replaceAll('#', '0x'));
|
||||
// setState(() {});
|
||||
// },
|
||||
// title: Text(
|
||||
// e.summary ?? 'no_title'.i18n,
|
||||
// style: TextStyle(
|
||||
// color: AppColors.of(context).text.withOpacity(.95),
|
||||
// ),
|
||||
// ),
|
||||
// leading: Dot(
|
||||
// color: colorFromHex(
|
||||
// e.backgroundColor ?? '#000',
|
||||
// ) ??
|
||||
// Colors.black,
|
||||
// ),
|
||||
// borderRadius: const BorderRadius.vertical(
|
||||
// top: Radius.circular(12),
|
||||
// bottom: Radius.circular(12),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// )
|
||||
// .toList();
|
||||
|
||||
List<Widget> widgets = [];
|
||||
|
||||
widgets.add(
|
||||
Container(
|
||||
margin: const EdgeInsets.only(bottom: 3.0),
|
||||
decoration: BoxDecoration(
|
||||
// border: Border.all(
|
||||
// color: Theme.of(context).colorScheme.primary.withOpacity(.25),
|
||||
// width: 1.0,
|
||||
// ),
|
||||
color: AppColors.of(context).highlight,
|
||||
borderRadius: BorderRadius.circular(16.0),
|
||||
),
|
||||
child: PanelButton(
|
||||
onPressed: null,
|
||||
// onPressed: () async {
|
||||
// // thirdPartyProvider.pushTimetable(context, timetable);
|
||||
// setState(() {});
|
||||
// },
|
||||
title: Text(
|
||||
'reFilc - Órarend',
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context).text.withOpacity(.95),
|
||||
),
|
||||
),
|
||||
// leading: Icon(
|
||||
// FeatherIcons.plus,
|
||||
// size: 20.0,
|
||||
// color: AppColors.of(context).text.withOpacity(0.75),
|
||||
// ),
|
||||
leading: Dot(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(12),
|
||||
bottom: Radius.circular(12),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return widgets;
|
||||
}
|
||||
}
|
157
lib/ui/mobile/settings/welcome_message.dart
Normal file
157
lib/ui/mobile/settings/welcome_message.dart
Normal file
|
@ -0,0 +1,157 @@
|
|||
import 'package:refilc/api/providers/user_provider.dart';
|
||||
import 'package:refilc/models/settings.dart';
|
||||
import 'package:refilc/theme/colors/colors.dart';
|
||||
import 'package:refilc_mobile_ui/common/panel/panel_button.dart';
|
||||
import 'package:refilc_plus/models/premium_scopes.dart';
|
||||
import 'package:refilc_plus/providers/plus_provider.dart';
|
||||
import 'package:refilc_plus/ui/mobile/plus/upsell.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
import 'package:refilc_mobile_ui/screens/settings/settings_screen.i18n.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:i18n_extension/i18n_extension.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class WelcomeMessagePanelButton extends StatelessWidget {
|
||||
late SettingsProvider settingsProvider;
|
||||
late UserProvider user;
|
||||
|
||||
WelcomeMessagePanelButton(this.settingsProvider, this.user, {super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String finalName = ((user.nickname ?? '') != ''
|
||||
? user.nickname
|
||||
: (user.displayName ?? '') != ''
|
||||
? user.displayName
|
||||
: 'János') ??
|
||||
'János';
|
||||
|
||||
return PanelButton(
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => WelcomeMessageEditor(settingsProvider));
|
||||
},
|
||||
title: Text(
|
||||
"welcome_msg".i18n,
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context).text.withOpacity(.95),
|
||||
),
|
||||
),
|
||||
leading: Icon(
|
||||
FeatherIcons.smile,
|
||||
size: 22.0,
|
||||
color: AppColors.of(context).text.withOpacity(.95),
|
||||
),
|
||||
trailing: Container(
|
||||
constraints: const BoxConstraints(maxWidth: 100),
|
||||
child: Text(
|
||||
settingsProvider.welcomeMessage.replaceAll(' ', '') != ''
|
||||
? localizeFill(
|
||||
settingsProvider.welcomeMessage,
|
||||
[finalName],
|
||||
)
|
||||
: 'default'.i18n,
|
||||
style: const TextStyle(fontSize: 14.0),
|
||||
textAlign: TextAlign.end,
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class WelcomeMessageEditor extends StatefulWidget {
|
||||
late SettingsProvider settingsProvider;
|
||||
|
||||
WelcomeMessageEditor(this.settingsProvider, {super.key});
|
||||
|
||||
@override
|
||||
State<WelcomeMessageEditor> createState() => _WelcomeMessageEditorState();
|
||||
}
|
||||
|
||||
class _WelcomeMessageEditorState extends State<WelcomeMessageEditor> {
|
||||
final _welcomeMsg = TextEditingController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_welcomeMsg.text =
|
||||
widget.settingsProvider.welcomeMessage.replaceAll('%s', '%name%');
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text("edit_welcome_msg".i18n),
|
||||
content: TextField(
|
||||
controller: _welcomeMsg,
|
||||
autofocus: true,
|
||||
decoration: InputDecoration(
|
||||
border: const OutlineInputBorder(),
|
||||
label: Text('welcome_msg'.i18n),
|
||||
suffixIcon: IconButton(
|
||||
icon: const Icon(FeatherIcons.x),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_welcomeMsg.text = "";
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(
|
||||
"cancel".i18n,
|
||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context).maybePop();
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: Text(
|
||||
"done".i18n,
|
||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
),
|
||||
onPressed: () {
|
||||
// var trimmed = _welcomeMsg.text.trim();
|
||||
|
||||
// var defLen = trimmed.length;
|
||||
// var replacedLen = trimmed.replaceAll('%s', '').length;
|
||||
|
||||
// if (defLen - 2 > replacedLen) {
|
||||
// print('fuck yourself rn');
|
||||
// }
|
||||
var finalText = _welcomeMsg.text
|
||||
.trim()
|
||||
.replaceFirst('%name%', '\$s')
|
||||
.replaceFirst('%user%', '\$s')
|
||||
.replaceFirst('%username%', '\$s')
|
||||
.replaceFirst('%me%', '\$s')
|
||||
.replaceFirst('%profile%', '\$s')
|
||||
.replaceAll('%', '')
|
||||
.replaceFirst('\$s', '%s');
|
||||
// .replaceAll('\$s', 's');
|
||||
|
||||
if (!Provider.of<PlusProvider>(context, listen: false)
|
||||
.hasScope(PremiumScopes.welcomeMessage) &&
|
||||
finalText.replaceAll(' ', '') != '') {
|
||||
PlusLockedFeaturePopup.show(
|
||||
context: context, feature: PremiumFeature.welcomeMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
widget.settingsProvider
|
||||
.update(welcomeMessage: finalText, store: true);
|
||||
Navigator.of(context).pop(true);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue