Merge branch 'master' of github.com:refilc/naplo

This commit is contained in:
zypherift
2024-06-14 14:09:28 +02:00
72 changed files with 2854 additions and 609 deletions

View File

@@ -10,6 +10,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
import 'package:provider/provider.dart';
import 'package:refilc_plus/ui/mobile/settings/submenu/calendar_sync.dart';
import 'package:refilc_plus/ui/mobile/settings/submenu/grade_exporting.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';
@@ -158,6 +159,16 @@ class ExtrasSettingsScreenState extends State<ExtrasSettingsScreen> {
),
],
),
SplittedPanel(
padding: const EdgeInsets.only(top: 9.0),
cardPadding: const EdgeInsets.all(4.0),
isSeparated: true,
children: [
MenuGradeExporting(
borderRadius: BorderRadius.circular(12.0),
),
],
),
SplittedPanel(
padding: const EdgeInsets.only(top: 9.0),
cardPadding: const EdgeInsets.all(4.0),

View File

@@ -0,0 +1,381 @@
import 'package:refilc/models/settings.dart';
import 'package:refilc/theme/colors/colors.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:refilc/ui/flutter_colorpicker/colorpicker.dart';
import 'package:refilc/ui/widgets/grade/grade_tile.dart';
import 'package:refilc_kreta_api/models/grade.dart';
import 'package:refilc_mobile_ui/screens/settings/theme_screen.dart';
import 'submenu_screen.i18n.dart';
enum SelectedGrade { one, two, three, four, five }
class GradeColorsSettingsScreen extends StatefulWidget {
const GradeColorsSettingsScreen({super.key});
@override
GradeColorsSettingsScreenState createState() =>
GradeColorsSettingsScreenState();
}
class GradeColorsSettingsScreenState extends State<GradeColorsSettingsScreen> {
late SettingsProvider settingsProvider;
SelectedGrade currentEditGrade = SelectedGrade.one;
@override
Widget build(BuildContext context) {
SettingsProvider settingsProvider = Provider.of<SettingsProvider>(context);
return Scaffold(
appBar: AppBar(
surfaceTintColor: Theme.of(context).scaffoldBackgroundColor,
leading: BackButton(
color: AppColors.of(context).text,
onPressed: () {
setState(() {
// made this cuz else it will be ugly
currentEditGrade = SelectedGrade.one;
});
Navigator.of(context).pop();
},
),
title: Text(
"grade_colors".i18n,
style: TextStyle(color: AppColors.of(context).text),
),
actions: [
IconButton(
onPressed: () {
List<Color> colors = List.castFrom(settingsProvider.gradeColors);
var defaultColors =
SettingsProvider.defaultSettings().gradeColors;
colors[currentEditGrade.index] =
defaultColors[currentEditGrade.index];
settingsProvider.update(gradeColors: colors);
},
icon: const Icon(
Icons.restore,
size: 26.0,
),
),
const SizedBox(
width: 10.0,
),
],
),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
children: [
SizedBox(
height: MediaQuery.of(context).size.height * 0.14,
),
Stack(
children: [
Container(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.background,
borderRadius: BorderRadius.circular(75.0),
boxShadow: [
BoxShadow(
color: Theme.of(context)
.colorScheme
.shadow
.withOpacity(.1),
blurRadius: 10.0,
offset: const Offset(0, 5),
),
],
),
padding: const EdgeInsets.all(6.0),
child: GradeValueWidget(
GradeValue(currentEditGrade.index + 1, '', '', 100),
fill: true,
size: 75.0,
// color:
// settingsProvider.gradeColors[currentEditGrade.index],
),
),
// before grades
if (currentEditGrade.index > 0)
Transform.translate(
offset: const Offset(-110, 16.5),
child: GradeValueWidget(
GradeValue(currentEditGrade.index, '', '', 100),
fill: true,
size: 60.0,
// color:
// settingsProvider.gradeColors[currentEditGrade.index],
),
),
if (currentEditGrade.index > 1)
Transform.translate(
offset: const Offset(-200, 23),
child: GradeValueWidget(
GradeValue(currentEditGrade.index - 1, '', '', 100),
fill: true,
size: 50.0,
// color:
// settingsProvider.gradeColors[currentEditGrade.index],
),
),
// after grades
if (currentEditGrade.index < 4)
Transform.translate(
offset: const Offset(142, 16.5),
child: GradeValueWidget(
GradeValue(currentEditGrade.index + 2, '', '', 100),
fill: true,
size: 60.0,
// color:
// settingsProvider.gradeColors[currentEditGrade.index],
),
),
if (currentEditGrade.index < 3)
Transform.translate(
offset: const Offset(245, 23),
child: GradeValueWidget(
GradeValue(currentEditGrade.index + 3, '', '', 100),
fill: true,
size: 50.0,
// color:
// settingsProvider.gradeColors[currentEditGrade.index],
),
),
],
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.14,
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: SafeArea(
child: FilcColorPicker(
colorMode: CustomColorMode.grade,
pickerColor:
settingsProvider.gradeColors[currentEditGrade.index],
onColorChanged: (c) {
setState(() {
// update grade color
settingsProvider.update(
gradeColors: settingsProvider.gradeColors
..[currentEditGrade.index] = c);
});
},
onColorChangeEnd: (c, {adaptive}) {
// update grade color
},
onThemeIdProvided: (t) {},
),
),
),
Padding(
padding: const EdgeInsets.only(bottom: 20.0, top: 16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
onTap: () => setState(() {
currentEditGrade = SelectedGrade.one;
}),
child: Container(
width: 45.0,
height: 45.0,
decoration: BoxDecoration(
border: Border.all(
color: currentEditGrade == SelectedGrade.one
? Theme.of(context).colorScheme.secondary
: Theme.of(context)
.colorScheme
.secondary
.withOpacity(.2),
width: 1.0,
),
borderRadius: BorderRadius.circular(50.0),
color: currentEditGrade == SelectedGrade.one
? Theme.of(context).colorScheme.secondary
: null,
),
child: Center(
child: Text(
'1',
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w600,
color: currentEditGrade == SelectedGrade.one
? Colors.white
: null,
),
),
),
),
),
const SizedBox(width: 10.0),
GestureDetector(
onTap: () => setState(() {
currentEditGrade = SelectedGrade.two;
}),
child: Container(
width: 45.0,
height: 45.0,
decoration: BoxDecoration(
border: Border.all(
color: currentEditGrade == SelectedGrade.two
? Theme.of(context).colorScheme.secondary
: Theme.of(context)
.colorScheme
.secondary
.withOpacity(.2),
width: 1.0,
),
borderRadius: BorderRadius.circular(50.0),
color: currentEditGrade == SelectedGrade.two
? Theme.of(context).colorScheme.secondary
: null,
),
child: Center(
child: Text(
'2',
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w600,
color: currentEditGrade == SelectedGrade.two
? Colors.white
: null,
),
),
),
),
),
const SizedBox(width: 10.0),
GestureDetector(
onTap: () => setState(() {
currentEditGrade = SelectedGrade.three;
}),
child: Container(
width: 45.0,
height: 45.0,
decoration: BoxDecoration(
border: Border.all(
color: currentEditGrade == SelectedGrade.three
? Theme.of(context).colorScheme.secondary
: Theme.of(context)
.colorScheme
.secondary
.withOpacity(.2),
width: 1.0,
),
borderRadius: BorderRadius.circular(50.0),
color: currentEditGrade == SelectedGrade.three
? Theme.of(context).colorScheme.secondary
: null,
),
child: Center(
child: Text(
'3',
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w600,
color: currentEditGrade == SelectedGrade.three
? Colors.white
: null,
),
),
),
),
),
const SizedBox(width: 10.0),
GestureDetector(
onTap: () => setState(() {
currentEditGrade = SelectedGrade.four;
}),
child: Container(
width: 45.0,
height: 45.0,
decoration: BoxDecoration(
border: Border.all(
color: currentEditGrade == SelectedGrade.four
? Theme.of(context).colorScheme.secondary
: Theme.of(context)
.colorScheme
.secondary
.withOpacity(.2),
width: 1.0,
),
borderRadius: BorderRadius.circular(50.0),
color: currentEditGrade == SelectedGrade.four
? Theme.of(context).colorScheme.secondary
: null,
),
child: Center(
child: Text(
'4',
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w600,
color: currentEditGrade == SelectedGrade.four
? Colors.white
: null,
),
),
),
),
),
const SizedBox(width: 10.0),
GestureDetector(
onTap: () => setState(() {
currentEditGrade = SelectedGrade.five;
}),
child: Container(
width: 45.0,
height: 45.0,
decoration: BoxDecoration(
border: Border.all(
color: currentEditGrade == SelectedGrade.five
? Theme.of(context).colorScheme.secondary
: Theme.of(context)
.colorScheme
.secondary
.withOpacity(.2),
width: 1.0,
),
borderRadius: BorderRadius.circular(50.0),
color: currentEditGrade == SelectedGrade.five
? Theme.of(context).colorScheme.secondary
: null,
),
child: Center(
child: Text(
'5',
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w600,
color: currentEditGrade == SelectedGrade.five
? Colors.white
: null,
),
),
),
),
),
],
),
),
],
),
],
),
),
);
}
}

View File

@@ -16,6 +16,7 @@ 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_mobile_ui/screens/settings/submenu/share_theme_popup.dart';
import 'package:share_plus/share_plus.dart';
class MenuPaintList extends StatelessWidget {
@@ -251,18 +252,7 @@ class PaintListScreenState extends State<PaintListScreen>
subject: 'share_subj_theme'.i18n,
);
} else {
SharedGradeColors gradeColors = await shareProvider
.shareCurrentGradeColors(context);
SharedTheme theme =
await shareProvider.shareCurrentTheme(
context,
gradeColors: gradeColors,
);
Share.share(
theme.id,
subject: 'share_subj_theme'.i18n,
);
ShareThemeDialog.show(context);
}
},
longPressInstead: true,

View File

@@ -30,6 +30,8 @@ import 'package:refilc_plus/providers/plus_provider.dart';
import 'package:refilc_plus/ui/mobile/plus/upsell.dart';
import 'package:google_fonts/google_fonts.dart';
import 'grade_colors.dart';
class MenuPersonalizeSettings extends StatelessWidget {
const MenuPersonalizeSettings({
super.key,
@@ -459,6 +461,49 @@ class PersonalizeSettingsScreenState extends State<PersonalizeSettingsScreen>
),
],
),
// new popup toggle
SplittedPanel(
padding: const EdgeInsets.only(top: 9.0),
cardPadding: const EdgeInsets.all(4.0),
isSeparated: true,
children: [
PanelButton(
padding: const EdgeInsets.only(left: 14.0, right: 6.0),
onPressed: () async {
settingsProvider.update(
newPopups: !settingsProvider.newPopups);
setState(() {});
},
title: Text(
"new_popups".i18n,
style: TextStyle(
color: AppColors.of(context).text.withOpacity(
settingsProvider.newPopups ? .95 : .25),
),
),
leading: Icon(
FeatherIcons.alertOctagon,
size: 22.0,
color: AppColors.of(context).text.withOpacity(
settingsProvider.newPopups ? .95 : .25),
),
trailing: Switch(
onChanged: (v) async {
settingsProvider.update(newPopups: v);
setState(() {});
},
value: settingsProvider.newPopups,
activeColor: Theme.of(context).colorScheme.secondary,
),
borderRadius: const BorderRadius.vertical(
top: Radius.circular(12.0),
bottom: Radius.circular(12.0),
),
),
],
),
// change subject icons
// SplittedPanel(
// padding: const EdgeInsets.only(top: 9.0),
@@ -499,8 +544,14 @@ class PersonalizeSettingsScreenState extends State<PersonalizeSettingsScreen>
children: [
PanelButton(
onPressed: () {
SettingsHelper.gradeColors(context);
setState(() {});
// SettingsHelper.gradeColors(context);
// setState(() {});
Navigator.of(context, rootNavigator: true).push(
CupertinoPageRoute(
builder: (context) =>
const GradeColorsSettingsScreen(),
),
);
},
title: Text(
"grade_colors".i18n,
@@ -670,16 +721,6 @@ class PersonalizeSettingsScreenState extends State<PersonalizeSettingsScreen>
children: [
PanelButton(
onPressed: () {
if (!Provider.of<PlusProvider>(context,
listen: false)
.hasScope(PremiumScopes.liveActivityColor)) {
PlusLockedFeaturePopup.show(
context: context,
feature: PremiumFeature.liveActivity,
);
return;
}
SettingsHelper.liveActivityColor(context);
setState(() {});
},
@@ -882,7 +923,7 @@ class PersonalizeSettingsScreenState extends State<PersonalizeSettingsScreen>
title: Text('fonts'.i18n),
padding: EdgeInsets.zero,
cardPadding: const EdgeInsets.all(4.0),
isSeparated: true,
isSeparated: false,
children: [
PanelButton(
onPressed: () {
@@ -920,11 +961,72 @@ class PersonalizeSettingsScreenState extends State<PersonalizeSettingsScreen>
),
borderRadius: const BorderRadius.vertical(
top: Radius.circular(12.0),
bottom: Radius.circular(6.0),
),
),
PanelButton(
padding: const EdgeInsets.only(left: 14.0, right: 6.0),
onPressed: () async {
if (!Provider.of<PlusProvider>(context, listen: false)
.hasScope(PremiumScopes.customFont)) {
PlusLockedFeaturePopup.show(
context: context,
feature: PremiumFeature.fontChange);
return;
}
settingsProvider.update(
titleOnlyFont: !settingsProvider.titleOnlyFont);
Provider.of<ThemeModeObserver>(context, listen: false)
.changeTheme(settingsProvider.theme,
updateNavbarColor: false);
setState(() {});
},
title: Text(
"only_ch_title_font".i18n,
style: TextStyle(
color: AppColors.of(context).text.withOpacity(
settingsProvider.titleOnlyFont ? .95 : .25),
),
),
leading: Icon(
Icons.text_increase_rounded,
size: 22.0,
color: AppColors.of(context).text.withOpacity(
settingsProvider.titleOnlyFont ? .95 : .25),
),
trailing: Switch(
onChanged: (v) async {
if (!Provider.of<PlusProvider>(context,
listen: false)
.hasScope(PremiumScopes.customFont)) {
PlusLockedFeaturePopup.show(
context: context,
feature: PremiumFeature.fontChange);
return;
}
settingsProvider.update(titleOnlyFont: v);
Provider.of<ThemeModeObserver>(context,
listen: false)
.changeTheme(settingsProvider.theme,
updateNavbarColor: false);
setState(() {});
},
value: settingsProvider.titleOnlyFont,
activeColor: Theme.of(context).colorScheme.secondary,
),
borderRadius: const BorderRadius.vertical(
top: Radius.circular(4.0),
bottom: Radius.circular(12.0),
),
),
],
),
// bottom padding
const SizedBox(
height: 20.0,
),
],
),
),

View File

@@ -0,0 +1,160 @@
// ignore_for_file: use_build_context_synchronously, deprecated_member_use
import 'package:flutter/material.dart';
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
import 'package:provider/provider.dart';
// import 'package:refilc/models/settings.dart';
import 'package:refilc/models/shared_theme.dart';
import 'package:refilc_kreta_api/providers/share_provider.dart';
import 'package:refilc_mobile_ui/common/action_button.dart';
import 'package:refilc_mobile_ui/common/splitted_panel/splitted_panel.dart';
import 'package:share_plus/share_plus.dart';
import 'submenu_screen.i18n.dart';
class ShareThemeDialog extends StatefulWidget {
const ShareThemeDialog({super.key});
static void show(BuildContext context) {
showDialog(
context: context,
builder: (context) => AlertDialog(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)),
title: Text("attention".i18n),
content: Text("share_disclaimer".i18n),
actions: [
ActionButton(
label: "understand".i18n,
onTap: () async {
Navigator.of(context).pop();
showDialog(
context: context,
builder: (context) => const ShareThemeDialog());
},
),
],
),
);
}
@override
ShareThemeDialogState createState() => ShareThemeDialogState();
}
class ShareThemeDialogState extends State<ShareThemeDialog> {
final _title = TextEditingController();
bool isPublic = false;
late ShareProvider shareProvider;
@override
void initState() {
super.initState();
shareProvider = Provider.of<ShareProvider>(context, listen: false);
}
@override
Widget build(BuildContext context) {
return AlertDialog(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(14.0))),
contentPadding: const EdgeInsets.only(top: 10.0),
title: Text("share_theme".i18n),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding:
const EdgeInsets.symmetric(vertical: 12.0, horizontal: 24.0),
child: TextField(
controller: _title,
onEditingComplete: () async {},
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: 'paint_title'.i18n,
suffixIcon: IconButton(
icon: const Icon(
FeatherIcons.x,
color: Colors.grey,
),
onPressed: () {
setState(() {
_title.text = '';
});
},
),
),
),
),
SplittedPanel(
children: [
SwitchListTile(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.0),
),
value: isPublic,
onChanged: (value) {
setState(() {
isPublic = value;
});
},
title: Text("is_public".i18n),
contentPadding: const EdgeInsets.only(left: 15.0, right: 10.0),
),
],
),
],
),
actions: [
TextButton(
child: Text(
"cancel".i18n,
style: const TextStyle(fontWeight: FontWeight.w500),
),
onPressed: () {
Navigator.of(context).maybePop();
},
),
TextButton(
child: Text(
"share_it".i18n,
style: const TextStyle(fontWeight: FontWeight.w500),
),
onPressed: () async {
// share the fucking theme
SharedGradeColors gradeColors =
await shareProvider.shareCurrentGradeColors(context);
SharedTheme theme = await shareProvider.shareCurrentTheme(
context,
gradeColors: gradeColors,
isPublic: isPublic,
displayName: _title.text,
);
// save theme id in settings
// Provider.of<SettingsProvider>(context, listen: false)
// .update(currentThemeId: theme.id);
// close this popup shit
Navigator.of(context).pop(true);
// show the share popup
Share.share(
theme.id,
subject: 'share_subj_theme'.i18n,
);
},
),
],
);
}
}

View File

@@ -17,6 +17,17 @@ extension SettingsLocalization on String {
"rare": "Rare",
"epic": "Epic",
"legendary": "Legendary",
// grade colors
"grade_colors": "Grade Colors",
// theme share popup
"share_theme": "Share Paint",
"paint_title": "Paint title...",
"share_it": "Share it!",
"is_public": "Public Paint",
"attention": "Attention!",
"share_disclaimer":
"By sharing the theme, you agree that the nickname you set and all settings of the theme will be shared publicly.",
"understand": "I understand",
},
"hu_hu": {
"general": "Általános",
@@ -32,6 +43,17 @@ extension SettingsLocalization on String {
"rare": "Ritka",
"epic": "Epikus",
"legendary": "Legendás",
// grade colors
"grade_colors": "Jegyek színei",
// theme share popup
"share_theme": "Téma megosztása",
"paint_title": "Téma neve...",
"share_it": "Megosztás!",
"is_public": "Nyilvános téma",
"attention": "Figyelem!",
"share_disclaimer":
"A téma megosztásával elfogadod, hogy az általad beállított becenév és a téma minden beállítása nyilvánosan megosztásra kerüljön.",
"understand": "Értem",
},
"de_de": {
"general": "Allgemeine",
@@ -47,6 +69,17 @@ extension SettingsLocalization on String {
"rare": "Selten",
"epic": "Episch",
"legendary": "Legendär",
// grade colors
"grade_colors": "Notenfarben",
// theme share popup
"share_theme": "Thema teilen",
"paint_title": "Thema Titel...",
"share_it": "Teilen!",
"is_public": "Öffentliches Thema",
"attention": "Achtung!",
"share_disclaimer":
"Durch das Teilen des Themes erklären Sie sich damit einverstanden, dass der von Ihnen festgelegte Spitzname und alle Einstellungen des Themes öffentlich geteilt werden.",
"understand": "Ich verstehe",
},
};