Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 91 additions & 43 deletions lib/core/common/app_buttons.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:lantern/core/common/app_asset.dart';
import 'package:lantern/core/common/app_colors.dart';
import 'package:lantern/core/common/app_dimens.dart';
import 'package:lantern/core/common/app_text_styles.dart';
import 'package:lantern/core/common/cap_scaling.dart';

typedef OnPressed = VoidCallback;

Expand Down Expand Up @@ -40,25 +40,40 @@ class PrimaryButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
final button = Theme.of(context).elevatedButtonTheme.style;

final iconHeight = hCap(context, 22);
final iconSz = spCap(context, 24);

return icon == null
? ElevatedButton(
onPressed: enabled ? onPressed : null,
style: _buildButtonStyle(button!),
style: _buildButtonStyle(context, button!, iconSz),
child: Text(label),
)
: ElevatedButton.icon(
onPressed: enabled ? onPressed : null,
icon: AppImage(
path: icon!,
height: 22,
height: iconHeight,
color: iconColor,
),
label: Text(label),
style: _buildButtonStyle(button!),
style: _buildButtonStyle(context, button!, iconSz),
);
}

ButtonStyle _buildButtonStyle(ButtonStyle style) {
ButtonStyle _buildButtonStyle(
BuildContext context,
ButtonStyle style,
double iconSz,
) {
final verticalPad = hCap(context, 12);
final fontSz = spCap(context, 16);

// Heights
final minHeight = isTaller == true ? hCap(context, 56) : hCap(context, 48);
final nonExpandedHeight = hCap(context, 52);

return style.copyWith(
backgroundColor: WidgetStateProperty.resolveWith<Color>(
(Set<WidgetState> states) {
Expand Down Expand Up @@ -87,20 +102,27 @@ class PrimaryButton extends StatelessWidget {
},
),
// backgroundColor: WidgetStatePropertyAll<Color>(bgColor ?? AppColors.blue7),
iconSize: WidgetStatePropertyAll<double>(24.0),
iconSize: WidgetStatePropertyAll<double>(iconSz),
padding: WidgetStatePropertyAll<EdgeInsetsGeometry>(
EdgeInsets.symmetric(vertical: 12.0.h, horizontal: 40.0)),
EdgeInsets.symmetric(
vertical: verticalPad,
horizontal: 40.0,
),
),
textStyle: WidgetStatePropertyAll<TextStyle>(
AppTextStyles.primaryButtonTextStyle.copyWith(
fontSize: expanded ? 16.0.sp : 16.0, fontWeight: FontWeight.w500),
fontSize: expanded ? fontSz : 16.0,
fontWeight: FontWeight.w500,
),
),

foregroundColor: WidgetStatePropertyAll<Color>(
enabled == false ? AppColors.gray5 : textColor ?? AppColors.gray1,
),
minimumSize: WidgetStatePropertyAll<Size>(expanded
? Size(double.infinity, isTaller == true ? 56.0 : 48.0)
: const Size(0, 52.0)),
minimumSize: WidgetStatePropertyAll<Size>(
expanded
? Size(double.infinity, minHeight)
: Size(0, nonExpandedHeight),
),
);
}
}
Expand All @@ -117,37 +139,52 @@ class SecondaryButton extends StatelessWidget {
final Color? bgColor;
final bool? isTaller;

const SecondaryButton(
{super.key,
required this.label,
this.enabled = true,
this.expanded = true,
this.isTaller = false,
required this.onPressed,
this.icon,
this.bgColor});
const SecondaryButton({
super.key,
required this.label,
this.enabled = true,
this.expanded = true,
this.isTaller = false,
required this.onPressed,
this.icon,
this.bgColor,
});

@override
Widget build(BuildContext context) {
final button = Theme.of(context).elevatedButtonTheme.style;

final iconHeight = hCap(context, 22);
final iconSz = spCap(context, 24);

return icon == null
? ElevatedButton(
onPressed: enabled ? onPressed : null,
style: _buildButtonStyle(button!),
style: _buildButtonStyle(context, button!, iconSz),
child: Text(label),
)
: ElevatedButton.icon(
onPressed: enabled ? onPressed : null,
icon: AppImage(
path: icon!,
height: 22,
height: iconHeight,
),
label: Text(label),
style: _buildButtonStyle(button!),
style: _buildButtonStyle(context, button!, iconSz),
);
}

ButtonStyle _buildButtonStyle(ButtonStyle style) {
ButtonStyle _buildButtonStyle(
BuildContext context,
ButtonStyle style,
double iconSz,
) {
final verticalPad = hCap(context, 12);
final fontSz = spCap(context, 16);

// Heights
final height = isTaller == true ? hCap(context, 56) : hCap(context, 50);

return style.copyWith(
backgroundColor: WidgetStateProperty.resolveWith<Color>(
(Set<WidgetState> states) {
Expand All @@ -167,18 +204,22 @@ class SecondaryButton extends StatelessWidget {
),
overlayColor: WidgetStatePropertyAll<Color>(AppColors.gray2),
foregroundColor: WidgetStatePropertyAll<Color>(AppColors.gray9),
iconSize: WidgetStatePropertyAll<double>(24.0),
iconSize: WidgetStatePropertyAll<double>(iconSz),
padding: WidgetStatePropertyAll<EdgeInsetsGeometry>(
EdgeInsets.symmetric(vertical: 12.0.h, horizontal: 40.0)),
EdgeInsets.symmetric(
vertical: verticalPad,
horizontal: 40.0,
),
),
textStyle: WidgetStatePropertyAll<TextStyle>(
AppTextStyles.primaryButtonTextStyle.copyWith(
fontSize: expanded ? 16.0.sp : 16.0,
color: AppColors.gray9,
fontWeight: FontWeight.w600)),
maximumSize: WidgetStatePropertyAll<Size>(
Size(double.infinity, isTaller == true ? 56.0 : 50.0)),
minimumSize: WidgetStatePropertyAll<Size>(
Size(double.infinity, isTaller == true ? 56.0 : 50.0)),
AppTextStyles.primaryButtonTextStyle.copyWith(
fontSize: expanded ? fontSz : 16.0,
color: AppColors.gray9,
fontWeight: FontWeight.w600,
),
),
maximumSize: WidgetStatePropertyAll<Size>(Size(double.infinity, height)),
minimumSize: WidgetStatePropertyAll<Size>(Size(double.infinity, height)),
);
}
}
Expand All @@ -205,16 +246,19 @@ class AppTextButton extends StatelessWidget {

@override
Widget build(BuildContext context) {
final cappedFontSize = fontSize == null ? null : spCap(context, fontSize!);

return TextButton(
onPressed: onPressed,
style: TextButton.styleFrom(
padding: padding ?? EdgeInsets.symmetric(horizontal: defaultSize),
visualDensity: VisualDensity.compact,
textStyle: AppTextStyles.titleMedium.copyWith(
overflow: TextOverflow.ellipsis,
decoration:
underLine ? TextDecoration.underline : TextDecoration.none,
fontSize: fontSize),
overflow: TextOverflow.ellipsis,
decoration:
underLine ? TextDecoration.underline : TextDecoration.none,
fontSize: cappedFontSize,
),
foregroundColor: textColor ?? AppColors.blue7,
),
child: Text(label),
Expand All @@ -234,12 +278,14 @@ class AppIconButton extends StatelessWidget {

@override
Widget build(BuildContext context) {
final iconHeight = hCap(context, 24);

return IconButton(
onPressed: onPressed,
padding: EdgeInsets.symmetric(horizontal: 16.0),
padding: const EdgeInsets.symmetric(horizontal: 16.0),
icon: AppImage(
path: path,
height: 24,
height: iconHeight,
),
);
}
Expand All @@ -259,9 +305,11 @@ class AppRadioButton<T> extends StatelessWidget {

@override
Widget build(BuildContext context) {
final sz = hCap(context, 24);

return SizedBox(
width: 24,
height: 24,
width: sz,
height: sz,
child: Radio<T>(
value: value,
groupValue: groupValue,
Expand Down
13 changes: 13 additions & 0 deletions lib/core/common/app_dimens.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:lantern/core/common/cap_scaling.dart';
import 'package:lantern/core/utils/platform_utils.dart';

const double iconSize = 24;
double font16 = 16.sp;
Expand All @@ -15,3 +17,14 @@ const gap16 = SizedBox(height: 16);
const desktopWindowMinSize = Size(390, 750);
const desktopWindowSize = Size(390, 800);
const mobileSize = Size(360, 690);

Size designSizeFor(BuildContext context) {
final s = MediaQuery.sizeOf(context);

if (PlatformUtils.isDesktop) return desktopWindowSize;

// tablets: don't scale up (use 1:1)
if (isTabletSize(s)) return s;

return mobileSize;
}
11 changes: 6 additions & 5 deletions lib/core/common/app_text_field.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:lantern/core/common/app_asset.dart';
import 'package:lantern/core/common/app_colors.dart';
import 'package:lantern/core/common/app_dimens.dart';
import 'package:lantern/core/common/cap_scaling.dart';

class AppTextField extends StatelessWidget {
final FormFieldValidator<String>? validator;
Expand Down Expand Up @@ -56,16 +57,16 @@ class AppTextField extends StatelessWidget {
this.onEditingComplete,
this.counter,
this.autofillHints,
this. autofocus,
this.autofocus,
});

@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
Widget inputField = TextFormField(
autofocus: autofocus ??false,
autofocus: autofocus ?? false,
textAlign: TextAlign.start,
textAlignVertical: TextAlignVertical.top,
textAlignVertical: TextAlignVertical.center,
keyboardType: keyboardType,
autocorrect: autocorrect ?? !obscureText,
autofillHints: autofillHints,
Expand All @@ -89,7 +90,7 @@ class AppTextField extends StatelessWidget {
cursorOpacityAnimates: true,
style: textTheme.bodyMedium!.copyWith(
color: AppColors.gray9,
fontSize: 14.sp,
fontSize: spCap(context, 14),
),
textInputAction: textInputAction,
maxLines: maxLines,
Expand Down Expand Up @@ -157,7 +158,7 @@ class AppTextField extends StatelessWidget {
label!,
style: textTheme.labelLarge?.copyWith(
color: AppColors.gray8,
fontSize: 14.sp,
fontSize: spCap(context, 14),
),
),
),
Expand Down
22 changes: 22 additions & 0 deletions lib/core/common/cap_scaling.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';

const double kTabletShortestSide = 600;

/// Tablet heuristic used across the app
bool isTablet(BuildContext context) =>
MediaQuery.sizeOf(context).shortestSide >= kTabletShortestSide;

bool isTabletSize(Size size) => size.shortestSide >= kTabletShortestSide;

double spCap(BuildContext context, double base) {
// phone: use sp, tablet: cap to base
final scaled = base.sp;
return isTablet(context) ? math.min(scaled, base) : scaled;
}

double hCap(BuildContext context, double base) {
final scaled = base.h;
return isTablet(context) ? math.min(scaled, base) : scaled;
}
14 changes: 9 additions & 5 deletions lib/core/widgets/lantern_logo.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'dart:math' as math;

import '../common/common.dart';
import 'package:flutter/material.dart';
import 'package:lantern/core/common/common.dart';

class LanternLogo extends StatelessWidget {
final bool isPro;
Expand All @@ -20,8 +20,12 @@ class LanternLogo extends StatelessWidget {
@override
Widget build(BuildContext context) {
final aspectRatio = 105.64 / 20;
final screenWidth = 1.sw;
final width = (widthFraction ?? (105.64 / 390)) * screenWidth;
// Cap usable width to avoid tablets blowing up the logo
final usableWidth = math.min(MediaQuery.sizeOf(context).width, 430.0);

final rawWidth = (widthFraction ?? 0.27) * usableWidth;

final width = math.min(rawWidth, 140.0);
final height = width / aspectRatio;

return AppImage(
Expand Down
4 changes: 1 addition & 3 deletions lib/lantern_app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:i18n_extension/i18n_extension.dart';
import 'package:lantern/core/localization/localization_constants.dart';
import 'package:lantern/core/router/router.dart';
import 'package:lantern/core/updater/updater.dart';
import 'package:lantern/core/widgets/loading_indicator.dart';
import 'package:lantern/features/home/provider/app_setting_notifier.dart';
import 'package:lantern/features/window/window_wrapper.dart';
Expand Down Expand Up @@ -137,8 +136,7 @@ class _LanternAppState extends ConsumerState<LanternApp> {
child: SystemTrayWrapper(
child: ScreenUtilInit(
ensureScreenSize: true,
designSize:
PlatformUtils.isDesktop ? desktopWindowSize : mobileSize,
designSize: designSizeFor(context),
minTextAdapt: true,
child: I18n(
initialLocale: locale.toLocale,
Expand Down
Loading