mirror of
https://github.com/koloideal/Casha.git
synced 2026-08-08 17:51:14 +03:00
step
This commit is contained in:
@@ -87,15 +87,15 @@ class _AccountEditorOverlayState extends State<AccountEditorOverlay> {
|
|||||||
final mq = MediaQuery.of(widget.context);
|
final mq = MediaQuery.of(widget.context);
|
||||||
final layout = CardOverlayLayout.fromMediaQuery(mq);
|
final layout = CardOverlayLayout.fromMediaQuery(mq);
|
||||||
final cardTop = layout.cardTop;
|
final cardTop = layout.cardTop;
|
||||||
final cardHeight = layout.cardHeight;
|
|
||||||
final editorPanelHeight = layout.editorPanelHeight;
|
final editorPanelHeight = layout.editorPanelHeight;
|
||||||
final editorPanelTop = cardTop + cardHeight + layout.sectionGap;
|
|
||||||
final colorPanelTop = editorPanelTop + editorPanelHeight + layout.sectionGap;
|
|
||||||
final colorPanelHeight = layout.colorPanelHeight(mq, colorPanelTop);
|
|
||||||
|
|
||||||
return Consumer(
|
return Consumer(
|
||||||
builder: (context, ref, _) {
|
builder: (context, ref, _) {
|
||||||
final exchangeService = ref.watch(exchangeRateServiceProvider);
|
final exchangeService = ref.watch(exchangeRateServiceProvider);
|
||||||
|
final cardHeight = ref.watch(cardHeightProvider);
|
||||||
|
final editorPanelTop = cardTop + cardHeight + layout.sectionGap;
|
||||||
|
final colorPanelTop = editorPanelTop + editorPanelHeight + layout.sectionGap;
|
||||||
|
final colorPanelHeight = layout.colorPanelHeight(mq, colorPanelTop);
|
||||||
|
|
||||||
double previewBalance = 0.0;
|
double previewBalance = 0.0;
|
||||||
if (!dash.isAddingAccount) {
|
if (!dash.isAddingAccount) {
|
||||||
@@ -220,11 +220,38 @@ class _AccountEditorOverlayState extends State<AccountEditorOverlay> {
|
|||||||
Brightness.dark
|
Brightness.dark
|
||||||
? dash.tempDarkGradientType
|
? dash.tempDarkGradientType
|
||||||
: dash.tempLightGradientType,
|
: dash.tempLightGradientType,
|
||||||
|
cardHeight: cardHeight,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Positioned(
|
||||||
|
top: cardTop - 28,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
child: Center(
|
||||||
|
child: _HeightHandle(
|
||||||
|
onDrag: (delta) {
|
||||||
|
final newHeight = cardHeight - delta * 2;
|
||||||
|
ref.read(cardHeightProvider.notifier).set(newHeight);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
top: cardTop + cardHeight + 6,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
child: Center(
|
||||||
|
child: _HeightHandle(
|
||||||
|
onDrag: (delta) {
|
||||||
|
final newHeight = cardHeight + delta * 2;
|
||||||
|
ref.read(cardHeightProvider.notifier).set(newHeight);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
top: editorPanelTop,
|
top: editorPanelTop,
|
||||||
left: 20,
|
left: 20,
|
||||||
@@ -468,3 +495,36 @@ class _AccountEditorOverlayState extends State<AccountEditorOverlay> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _HeightHandle extends StatefulWidget {
|
||||||
|
final ValueChanged<double> onDrag;
|
||||||
|
|
||||||
|
const _HeightHandle({required this.onDrag});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<_HeightHandle> createState() => _HeightHandleState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _HeightHandleState extends State<_HeightHandle> {
|
||||||
|
bool _active = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
return GestureDetector(
|
||||||
|
onVerticalDragStart: (_) => setState(() => _active = true),
|
||||||
|
onVerticalDragUpdate: (details) => widget.onDrag(details.delta.dy),
|
||||||
|
onVerticalDragEnd: (_) => setState(() => _active = false),
|
||||||
|
behavior: HitTestBehavior.opaque,
|
||||||
|
child: AnimatedContainer(
|
||||||
|
duration: const Duration(milliseconds: 150),
|
||||||
|
width: _active ? 56 : 44,
|
||||||
|
height: _active ? 6 : 4,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: theme.colorScheme.onSurface.withOpacity(_active ? 0.5 : 0.25),
|
||||||
|
borderRadius: BorderRadius.circular(3),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ class BalanceCard extends ConsumerStatefulWidget {
|
|||||||
final GradientType? previewGradientType;
|
final GradientType? previewGradientType;
|
||||||
final String? accountName;
|
final String? accountName;
|
||||||
final CardColors? accountColors;
|
final CardColors? accountColors;
|
||||||
|
final double? cardHeight;
|
||||||
|
|
||||||
const BalanceCard({
|
const BalanceCard({
|
||||||
super.key,
|
super.key,
|
||||||
@@ -48,6 +49,7 @@ class BalanceCard extends ConsumerStatefulWidget {
|
|||||||
this.previewGradientType,
|
this.previewGradientType,
|
||||||
this.accountName,
|
this.accountName,
|
||||||
this.accountColors,
|
this.accountColors,
|
||||||
|
this.cardHeight,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -132,7 +134,7 @@ class BalanceCardState extends ConsumerState<BalanceCard>
|
|||||||
..rotateY(_tiltY * 0.42),
|
..rotateY(_tiltY * 0.42),
|
||||||
child: Container(
|
child: Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: kBalanceCardHeight,
|
height: widget.cardHeight ?? kBalanceCardHeight,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(20),
|
borderRadius: BorderRadius.circular(20),
|
||||||
gradient: buildCardGradient(primary, secondary, gradientType),
|
gradient: buildCardGradient(primary, secondary, gradientType),
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ class _BalanceCardCarouselState extends ConsumerState<BalanceCardCarousel> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final accountsAsync = ref.watch(accountsProvider);
|
final accountsAsync = ref.watch(accountsProvider);
|
||||||
final activeIndex = ref.watch(activeAccountIndexProvider);
|
final activeIndex = ref.watch(activeAccountIndexProvider);
|
||||||
|
final cardHeight = ref.watch(cardHeightProvider);
|
||||||
|
|
||||||
return accountsAsync.when(
|
return accountsAsync.when(
|
||||||
data: (accounts) {
|
data: (accounts) {
|
||||||
@@ -67,7 +68,7 @@ class _BalanceCardCarouselState extends ConsumerState<BalanceCardCarousel> {
|
|||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: kBalanceCardCarouselHeight,
|
height: cardHeight + 10,
|
||||||
child: OverflowBox(
|
child: OverflowBox(
|
||||||
maxWidth: MediaQuery.of(context).size.width,
|
maxWidth: MediaQuery.of(context).size.width,
|
||||||
child: PageView.builder(
|
child: PageView.builder(
|
||||||
@@ -96,6 +97,7 @@ class _BalanceCardCarouselState extends ConsumerState<BalanceCardCarousel> {
|
|||||||
previewPrimary: widget.previewPrimary,
|
previewPrimary: widget.previewPrimary,
|
||||||
previewSecondary: widget.previewSecondary,
|
previewSecondary: widget.previewSecondary,
|
||||||
previewGradientType: widget.previewGradientType,
|
previewGradientType: widget.previewGradientType,
|
||||||
|
cardHeight: cardHeight,
|
||||||
);
|
);
|
||||||
} else if (index <= accounts.length) {
|
} else if (index <= accounts.length) {
|
||||||
final account = accounts[index - 1];
|
final account = accounts[index - 1];
|
||||||
@@ -134,10 +136,12 @@ class _BalanceCardCarouselState extends ConsumerState<BalanceCardCarousel> {
|
|||||||
widget.onAccountLongPress?.call(account),
|
widget.onAccountLongPress?.call(account),
|
||||||
accountName: account.name,
|
accountName: account.name,
|
||||||
accountColors: accountColors,
|
accountColors: accountColors,
|
||||||
|
cardHeight: cardHeight,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
cardWidget = AddAccountCard(
|
cardWidget = AddAccountCard(
|
||||||
onTap: widget.onAddAccountTap,
|
onTap: widget.onAddAccountTap,
|
||||||
|
cardHeight: cardHeight,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,15 +158,15 @@ class _BalanceCardCarouselState extends ConsumerState<BalanceCardCarousel> {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const SizedBox(
|
loading: () => SizedBox(
|
||||||
height: kBalanceCardCarouselHeight,
|
height: cardHeight + 10,
|
||||||
child: Center(child: CircularProgressIndicator()),
|
child: const Center(child: CircularProgressIndicator()),
|
||||||
),
|
),
|
||||||
error: (error, stack) {
|
error: (error, stack) {
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: kBalanceCardCarouselHeight,
|
height: cardHeight + 10,
|
||||||
child: BalanceCard(
|
child: BalanceCard(
|
||||||
balance: widget.balance,
|
balance: widget.balance,
|
||||||
currencyInfo: widget.currencyInfo,
|
currencyInfo: widget.currencyInfo,
|
||||||
@@ -170,6 +174,7 @@ class _BalanceCardCarouselState extends ConsumerState<BalanceCardCarousel> {
|
|||||||
previewPrimary: widget.previewPrimary,
|
previewPrimary: widget.previewPrimary,
|
||||||
previewSecondary: widget.previewSecondary,
|
previewSecondary: widget.previewSecondary,
|
||||||
previewGradientType: widget.previewGradientType,
|
previewGradientType: widget.previewGradientType,
|
||||||
|
cardHeight: cardHeight,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
@@ -183,8 +188,9 @@ class _BalanceCardCarouselState extends ConsumerState<BalanceCardCarousel> {
|
|||||||
|
|
||||||
class AddAccountCard extends StatelessWidget {
|
class AddAccountCard extends StatelessWidget {
|
||||||
final VoidCallback? onTap;
|
final VoidCallback? onTap;
|
||||||
|
final double? cardHeight;
|
||||||
|
|
||||||
const AddAccountCard({super.key, this.onTap});
|
const AddAccountCard({super.key, this.onTap, this.cardHeight});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -199,7 +205,7 @@ class AddAccountCard extends StatelessWidget {
|
|||||||
painter: _DashedBorderPainter(),
|
painter: _DashedBorderPainter(),
|
||||||
child: Container(
|
child: Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: kAddAccountCardHeight,
|
height: cardHeight ?? kAddAccountCardHeight,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).colorScheme.surface.withOpacity(0.4),
|
color: Theme.of(context).colorScheme.surface.withOpacity(0.4),
|
||||||
borderRadius: BorderRadius.circular(20),
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
|||||||
@@ -37,9 +37,12 @@ class _FullScreenBlurOverlayState extends State<FullScreenBlurOverlay> {
|
|||||||
final mq = MediaQuery.of(widget.context);
|
final mq = MediaQuery.of(widget.context);
|
||||||
final layout = CardOverlayLayout.fromMediaQuery(mq);
|
final layout = CardOverlayLayout.fromMediaQuery(mq);
|
||||||
final cardTop = layout.cardTop;
|
final cardTop = layout.cardTop;
|
||||||
final cardHeight = layout.cardHeight;
|
|
||||||
final panelTop = cardTop + cardHeight + layout.cardPreviewGap;
|
return Consumer(
|
||||||
final panelHeight = layout.colorPanelHeight(mq, panelTop);
|
builder: (context, ref, _) {
|
||||||
|
final cardHeight = ref.watch(cardHeightProvider);
|
||||||
|
final panelTop = cardTop + cardHeight + layout.cardPreviewGap;
|
||||||
|
final panelHeight = layout.colorPanelHeight(mq, panelTop);
|
||||||
|
|
||||||
return Material(
|
return Material(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
@@ -80,6 +83,7 @@ class _FullScreenBlurOverlayState extends State<FullScreenBlurOverlay> {
|
|||||||
Theme.of(widget.context).brightness == Brightness.dark
|
Theme.of(widget.context).brightness == Brightness.dark
|
||||||
? dash.tempDarkGradientType
|
? dash.tempDarkGradientType
|
||||||
: dash.tempLightGradientType,
|
: dash.tempLightGradientType,
|
||||||
|
cardHeight: cardHeight,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -132,6 +136,8 @@ class _FullScreenBlurOverlayState extends State<FullScreenBlurOverlay> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildPanel(double panelHeight, CardOverlayLayout layout) {
|
Widget _buildPanel(double panelHeight, CardOverlayLayout layout) {
|
||||||
|
|||||||
@@ -103,6 +103,31 @@ final exchangeRateServiceProvider = Provider<ExchangeRateService>((ref) {
|
|||||||
return ExchangeRateService(prefs);
|
return ExchangeRateService(prefs);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
final cardHeightProvider = NotifierProvider<CardHeightNotifier, double>(
|
||||||
|
CardHeightNotifier.new,
|
||||||
|
);
|
||||||
|
|
||||||
|
class CardHeightNotifier extends Notifier<double> {
|
||||||
|
static const _key = 'card_height';
|
||||||
|
static const _minHeight = 160.0;
|
||||||
|
static const _maxHeight = 280.0;
|
||||||
|
static const _defaultHeight = 200.0;
|
||||||
|
|
||||||
|
@override
|
||||||
|
double build() {
|
||||||
|
final prefs = ref.watch(sharedPreferencesProvider);
|
||||||
|
final saved = prefs.getDouble(_key);
|
||||||
|
if (saved == null) return _defaultHeight;
|
||||||
|
return saved.clamp(_minHeight, _maxHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(double height) {
|
||||||
|
final clamped = height.clamp(_minHeight, _maxHeight);
|
||||||
|
state = clamped;
|
||||||
|
ref.read(sharedPreferencesProvider).setDouble(_key, clamped);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final ratesInitProvider = FutureProvider<void>((ref) async {
|
final ratesInitProvider = FutureProvider<void>((ref) async {
|
||||||
await ref.read(exchangeRateServiceProvider).fetchRates();
|
await ref.read(exchangeRateServiceProvider).fetchRates();
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user