mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-22 07:20:39 +00:00
cleanup
This commit is contained in:
parent
8fdbc102b6
commit
1d149425ab
6 changed files with 122 additions and 152 deletions
|
@ -1,21 +1,12 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:lightmeter/generated/l10n.dart';
|
||||
import 'package:lightmeter/res/dimens.dart';
|
||||
import 'package:lightmeter/screens/metering/components/shared/readings_container/components/shared/animated_dialog_picker/components/animated_dialog/widget_dialog_animated.dart';
|
||||
import 'package:lightmeter/screens/metering/components/shared/readings_container/components/shared/reading_value_container/widget_container_reading_value.dart';
|
||||
import 'package:lightmeter/screens/settings/utils/show_buy_pro_dialog.dart';
|
||||
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
||||
import 'package:lightmeter/screens/shared/pro_features_dialog/widget_dialog_pro_features.dart';
|
||||
|
||||
class LightmeterProAnimatedDialog extends StatefulWidget {
|
||||
class LightmeterProAnimatedDialog extends StatelessWidget {
|
||||
const LightmeterProAnimatedDialog({super.key});
|
||||
|
||||
@override
|
||||
State<LightmeterProAnimatedDialog> createState() => _LightmeterProAnimatedDialogState();
|
||||
}
|
||||
|
||||
class _LightmeterProAnimatedDialogState extends State<LightmeterProAnimatedDialog> {
|
||||
final _key = GlobalKey<AnimatedDialogState>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AnimatedDialog(
|
||||
|
@ -28,44 +19,8 @@ class _LightmeterProAnimatedDialogState extends State<LightmeterProAnimatedDialo
|
|||
),
|
||||
],
|
||||
),
|
||||
openedChild: ProFeaturesDialog(),
|
||||
openedSize: Size.fromHeight(height(context)),
|
||||
openedChild: const ProFeaturesDialog(),
|
||||
openedSize: Size.fromHeight(const ProFeaturesDialog().height(context)),
|
||||
);
|
||||
}
|
||||
|
||||
double height(BuildContext context) {
|
||||
double textHeight(
|
||||
BuildContext context,
|
||||
String text,
|
||||
TextStyle? style,
|
||||
double horizontalPadding,
|
||||
) {
|
||||
final TextPainter titlePainter = TextPainter(
|
||||
text: TextSpan(
|
||||
text: text,
|
||||
style: style,
|
||||
),
|
||||
textDirection: TextDirection.ltr,
|
||||
)..layout(maxWidth: MediaQuery.of(context).size.width - Dimens.dialogMargin.horizontal - horizontalPadding);
|
||||
return titlePainter.size.height;
|
||||
}
|
||||
|
||||
final titleHeight = textHeight(
|
||||
context,
|
||||
S.of(context).unlockProFeatures,
|
||||
Theme.of(context).textTheme.headlineSmall,
|
||||
Dimens.dialogIconTitlePadding.horizontal,
|
||||
);
|
||||
final contentHeight = textHeight(
|
||||
context,
|
||||
S.of(context).unlockProFeaturesDescription,
|
||||
Theme.of(context).textTheme.bodyMedium,
|
||||
Dimens.paddingL * 2,
|
||||
);
|
||||
|
||||
return (IconTheme.of(context).size! + Dimens.dialogTitlePadding.vertical) + // icon + icon padding
|
||||
(titleHeight + Dimens.dialogIconTitlePadding.vertical) + // title + title padding
|
||||
contentHeight +
|
||||
(48 + Dimens.dialogActionsPadding.vertical); // actions + actions padding
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:lightmeter/generated/l10n.dart';
|
||||
import 'package:lightmeter/res/dimens.dart';
|
||||
import 'package:lightmeter/screens/shared/transparent_dialog/widget_dialog_transparent.dart';
|
||||
|
||||
typedef DialogPickerItemTitleBuilder<T> = Widget Function(BuildContext context, T value);
|
||||
typedef DialogPickerItemTrailingBuilder<T> = Widget? Function(T selected, T value);
|
||||
|
@ -29,29 +30,13 @@ class DialogPicker<T> extends StatefulWidget {
|
|||
super.key,
|
||||
});
|
||||
|
||||
double height(BuildContext context) {
|
||||
double textHeight(BuildContext context, String text, TextStyle? style) {
|
||||
final TextPainter titlePainter = TextPainter(
|
||||
text: TextSpan(
|
||||
text: text,
|
||||
style: style,
|
||||
),
|
||||
textDirection: TextDirection.ltr,
|
||||
)..layout(maxWidth: MediaQuery.of(context).size.width - Dimens.dialogIconTitlePadding.horizontal);
|
||||
return titlePainter.size.height + Dimens.dialogIconTitlePadding.vertical;
|
||||
}
|
||||
|
||||
final titleHeight = textHeight(context, title, Theme.of(context).textTheme.headlineSmall);
|
||||
final subtitleHeight =
|
||||
subtitle != null ? textHeight(context, subtitle!, Theme.of(context).textTheme.bodyMedium) : 0;
|
||||
|
||||
return (IconTheme.of(context).size! + Dimens.dialogTitlePadding.vertical) + // icon + icon padding
|
||||
titleHeight + // title + title padding
|
||||
subtitleHeight + // subtitle + subtitle padding
|
||||
Dimens.grid56 * values.length + // values summary height
|
||||
1 + // dividers
|
||||
(48 + Dimens.dialogActionsPadding.vertical); // actions + actions padding
|
||||
}
|
||||
double height(BuildContext context) => TransparentDialog.height(
|
||||
context,
|
||||
title: title,
|
||||
subtitle: subtitle,
|
||||
scrollableContent: true,
|
||||
contextHeight: Dimens.grid56 * values.length,
|
||||
);
|
||||
|
||||
@override
|
||||
State<DialogPicker<T>> createState() => _DialogPickerState<T>();
|
||||
|
@ -70,78 +55,43 @@ class _DialogPickerState<T> extends State<DialogPicker<T>> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Padding(
|
||||
padding: Dimens.dialogTitlePadding,
|
||||
child: Icon(widget.icon),
|
||||
),
|
||||
Padding(
|
||||
padding: Dimens.dialogIconTitlePadding,
|
||||
child: Text(
|
||||
widget.title,
|
||||
style: Theme.of(context).textTheme.headlineSmall,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
if (widget.subtitle != null)
|
||||
Padding(
|
||||
padding: Dimens.dialogIconTitlePadding,
|
||||
child: Text(
|
||||
widget.subtitle!,
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const Divider(),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
controller: _scrollController,
|
||||
padding: EdgeInsets.zero,
|
||||
itemCount: widget.values.length,
|
||||
itemExtent: Dimens.grid56,
|
||||
itemBuilder: (context, index) => RadioListTile(
|
||||
value: widget.values[index],
|
||||
groupValue: _selectedValue,
|
||||
title: DefaultTextStyle(
|
||||
style: Theme.of(context).textTheme.bodyLarge!,
|
||||
child: widget.itemTitleBuilder(context, widget.values[index]),
|
||||
),
|
||||
secondary: widget.itemTrailingBuilder?.call(_selectedValue, widget.values[index]),
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
setState(() {
|
||||
_selectedValue = value;
|
||||
});
|
||||
}
|
||||
},
|
||||
return TransparentDialog(
|
||||
icon: widget.icon,
|
||||
title: widget.title,
|
||||
subtitle: widget.subtitle,
|
||||
content: Expanded(
|
||||
child: ListView.builder(
|
||||
controller: _scrollController,
|
||||
padding: EdgeInsets.zero,
|
||||
itemCount: widget.values.length,
|
||||
itemExtent: Dimens.grid56,
|
||||
itemBuilder: (context, index) => RadioListTile(
|
||||
value: widget.values[index],
|
||||
groupValue: _selectedValue,
|
||||
title: DefaultTextStyle(
|
||||
style: Theme.of(context).textTheme.bodyLarge!,
|
||||
child: widget.itemTitleBuilder(context, widget.values[index]),
|
||||
),
|
||||
secondary: widget.itemTrailingBuilder?.call(_selectedValue, widget.values[index]),
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
setState(() {
|
||||
_selectedValue = value;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
Padding(
|
||||
padding: Dimens.dialogActionsPadding,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
const Spacer(),
|
||||
TextButton(
|
||||
onPressed: widget.onCancel,
|
||||
child: Text(S.of(context).cancel),
|
||||
),
|
||||
const SizedBox(width: Dimens.grid16),
|
||||
TextButton(
|
||||
onPressed: () => widget.onSelect(_selectedValue),
|
||||
child: Text(S.of(context).select),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
scrollableContent: true,
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: widget.onCancel,
|
||||
child: Text(S.of(context).cancel),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => widget.onSelect(_selectedValue),
|
||||
child: Text(S.of(context).select),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
|
|
@ -4,7 +4,7 @@ import 'package:lightmeter/generated/l10n.dart';
|
|||
import 'package:lightmeter/providers/remote_config_provider.dart';
|
||||
import 'package:lightmeter/providers/services_provider.dart';
|
||||
import 'package:lightmeter/res/dimens.dart';
|
||||
import 'package:lightmeter/screens/settings/utils/show_buy_pro_dialog.dart';
|
||||
import 'package:lightmeter/screens/shared/pro_features_dialog/widget_dialog_pro_features.dart';
|
||||
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
||||
|
||||
class BuyProListTile extends StatelessWidget {
|
||||
|
@ -20,7 +20,10 @@ class BuyProListTile extends StatelessWidget {
|
|||
title: Text(unlockFeaturesEnabled ? S.of(context).unlockProFeatures : S.of(context).buyLightmeterPro),
|
||||
onTap: !isPending
|
||||
? () {
|
||||
showBuyProDialog(context);
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) => const Dialog(child: ProFeaturesDialog()),
|
||||
);
|
||||
ServicesProvider.of(context)
|
||||
.analytics
|
||||
.logUnlockProFeatures(unlockFeaturesEnabled ? 'Unlock Pro features' : 'Buy Lightmeter Pro');
|
||||
|
|
|
@ -3,20 +3,23 @@ import 'package:lightmeter/generated/l10n.dart';
|
|||
import 'package:lightmeter/res/dimens.dart';
|
||||
import 'package:lightmeter/screens/metering/components/shared/readings_container/components/shared/animated_dialog_picker/components/animated_dialog/widget_dialog_animated.dart';
|
||||
import 'package:lightmeter/screens/shared/transparent_dialog/widget_dialog_transparent.dart';
|
||||
import 'package:lightmeter/utils/text_height.dart';
|
||||
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
||||
|
||||
Future<void> showBuyProDialog(BuildContext context) {
|
||||
return showDialog(
|
||||
context: context,
|
||||
builder: (_) => Dialog(
|
||||
child: const ProFeaturesDialog(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
class ProFeaturesDialog extends StatelessWidget {
|
||||
const ProFeaturesDialog({super.key});
|
||||
|
||||
double height(BuildContext context) => TransparentDialog.height(
|
||||
context,
|
||||
title: S.of(context).proFeatures,
|
||||
contextHeight: dialogTextHeight(
|
||||
context,
|
||||
S.of(context).unlockProFeaturesDescription,
|
||||
Theme.of(context).textTheme.bodyMedium,
|
||||
Dimens.paddingL * 2,
|
||||
),
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TransparentDialog(
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:lightmeter/res/dimens.dart';
|
||||
import 'package:lightmeter/utils/text_height.dart';
|
||||
|
||||
class TransparentDialog extends StatelessWidget {
|
||||
final IconData icon;
|
||||
|
@ -19,6 +20,35 @@ class TransparentDialog extends StatelessWidget {
|
|||
super.key,
|
||||
});
|
||||
|
||||
static double height(
|
||||
BuildContext context, {
|
||||
required String title,
|
||||
String? subtitle,
|
||||
required double contextHeight,
|
||||
bool scrollableContent = false,
|
||||
}) {
|
||||
double height = IconTheme.of(context).size! + Dimens.dialogTitlePadding.vertical;
|
||||
height += dialogTextHeight(
|
||||
context,
|
||||
title,
|
||||
Theme.of(context).textTheme.headlineSmall,
|
||||
Dimens.dialogIconTitlePadding.horizontal,
|
||||
) +
|
||||
Dimens.dialogIconTitlePadding.vertical;
|
||||
if (subtitle != null) {
|
||||
height += dialogTextHeight(
|
||||
context,
|
||||
subtitle,
|
||||
Theme.of(context).textTheme.bodyMedium,
|
||||
Dimens.dialogIconTitlePadding.horizontal,
|
||||
) +
|
||||
Dimens.dialogIconTitlePadding.vertical;
|
||||
}
|
||||
height += contextHeight;
|
||||
if (scrollableContent) height += 1;
|
||||
return height += 48 + Dimens.dialogActionsPadding.vertical;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
|
|
29
lib/utils/text_height.dart
Normal file
29
lib/utils/text_height.dart
Normal file
|
@ -0,0 +1,29 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:lightmeter/res/dimens.dart';
|
||||
|
||||
double dialogTextHeight(
|
||||
BuildContext context,
|
||||
String text,
|
||||
TextStyle? style,
|
||||
double textPadding,
|
||||
) =>
|
||||
textHeight(
|
||||
text,
|
||||
style,
|
||||
MediaQuery.sizeOf(context).width - Dimens.dialogMargin.horizontal - textPadding,
|
||||
);
|
||||
|
||||
double textHeight(
|
||||
String text,
|
||||
TextStyle? style,
|
||||
double maxWidth,
|
||||
) {
|
||||
final TextPainter titlePainter = TextPainter(
|
||||
text: TextSpan(
|
||||
text: text,
|
||||
style: style,
|
||||
),
|
||||
textDirection: TextDirection.ltr,
|
||||
)..layout(maxWidth: maxWidth);
|
||||
return titlePainter.height;
|
||||
}
|
Loading…
Reference in a new issue