mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-12 23:45:18 +00:00
chore: fix window resizing
This commit is contained in:
parent
3649b67869
commit
5930c342b5
@ -20,17 +20,6 @@ class $AssetsBackgroundsGen {
|
||||
List<AssetGenImage> get values => [xmasEffect];
|
||||
}
|
||||
|
||||
class $AssetsIllustrationsGen {
|
||||
const $AssetsIllustrationsGen();
|
||||
|
||||
/// File path: assets/illustrations/fixing_bugs.png
|
||||
AssetGenImage get fixingBugs =>
|
||||
const AssetGenImage('assets/illustrations/fixing_bugs.png');
|
||||
|
||||
/// List of all assets
|
||||
List<AssetGenImage> get values => [fixingBugs];
|
||||
}
|
||||
|
||||
class $AssetsLogosGen {
|
||||
const $AssetsLogosGen();
|
||||
|
||||
@ -151,8 +140,6 @@ class Assets {
|
||||
AssetGenImage('assets/bengali-patterns-bg.jpg');
|
||||
static const AssetGenImage branding = AssetGenImage('assets/branding.png');
|
||||
static const AssetGenImage emptyBox = AssetGenImage('assets/empty_box.png');
|
||||
static const $AssetsIllustrationsGen illustrations =
|
||||
$AssetsIllustrationsGen();
|
||||
static const AssetGenImage invidious = AssetGenImage('assets/invidious.jpg');
|
||||
static const AssetGenImage jiosaavn = AssetGenImage('assets/jiosaavn.png');
|
||||
static const AssetGenImage likedTracks =
|
||||
|
@ -1,73 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
typedef MouseStateBuilderCB = Widget Function(
|
||||
BuildContext context, MouseState mouseState);
|
||||
|
||||
class MouseState {
|
||||
bool isMouseOver = false;
|
||||
bool isMouseDown = false;
|
||||
MouseState();
|
||||
@override
|
||||
String toString() {
|
||||
return "isMouseDown: $isMouseDown - isMouseOver: $isMouseOver";
|
||||
}
|
||||
}
|
||||
|
||||
T? _ambiguate<T>(T? value) => value;
|
||||
|
||||
class MouseStateBuilder extends StatefulWidget {
|
||||
final MouseStateBuilderCB builder;
|
||||
final VoidCallback? onPressed;
|
||||
const MouseStateBuilder({super.key, required this.builder, this.onPressed});
|
||||
@override
|
||||
// ignore: library_private_types_in_public_api
|
||||
_MouseStateBuilderState createState() => _MouseStateBuilderState();
|
||||
}
|
||||
|
||||
class _MouseStateBuilderState extends State<MouseStateBuilder> {
|
||||
late MouseState _mouseState;
|
||||
_MouseStateBuilderState() {
|
||||
_mouseState = MouseState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MouseRegion(
|
||||
onEnter: (event) {
|
||||
setState(() {
|
||||
_mouseState.isMouseOver = true;
|
||||
});
|
||||
},
|
||||
onExit: (event) {
|
||||
setState(() {
|
||||
_mouseState.isMouseOver = false;
|
||||
});
|
||||
},
|
||||
child: GestureDetector(
|
||||
onTapDown: (_) {
|
||||
setState(() {
|
||||
_mouseState.isMouseDown = true;
|
||||
});
|
||||
},
|
||||
onTapCancel: () {
|
||||
setState(() {
|
||||
_mouseState.isMouseDown = false;
|
||||
});
|
||||
},
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_mouseState.isMouseDown = false;
|
||||
_mouseState.isMouseOver = false;
|
||||
});
|
||||
_ambiguate(WidgetsBinding.instance)!.addPostFrameCallback((_) {
|
||||
if (widget.onPressed != null) {
|
||||
widget.onPressed!();
|
||||
}
|
||||
});
|
||||
},
|
||||
onTapUp: (_) {},
|
||||
child: widget.builder(context, _mouseState),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:shadcn_flutter/shadcn_flutter.dart';
|
||||
import 'package:shadcn_flutter/shadcn_flutter_extension.dart';
|
||||
import 'package:spotube/components/button/back_button.dart';
|
||||
import 'package:spotube/components/titlebar/titlebar_buttons.dart';
|
||||
import 'package:spotube/provider/user_preferences/user_preferences_provider.dart';
|
||||
@ -49,7 +50,7 @@ class TitleBar extends HookConsumerWidget implements PreferredSizeWidget {
|
||||
this.height,
|
||||
this.surfaceBlur,
|
||||
this.surfaceOpacity,
|
||||
this.useSafeArea = true,
|
||||
this.useSafeArea = false,
|
||||
});
|
||||
|
||||
void onDrag(WidgetRef ref) {
|
||||
@ -66,7 +67,7 @@ class TitleBar extends HookConsumerWidget implements PreferredSizeWidget {
|
||||
final lastClicked = useRef<int>(DateTime.now().millisecondsSinceEpoch);
|
||||
|
||||
return SizedBox(
|
||||
height: height ?? 56,
|
||||
height: height ?? (48 * context.theme.scaling),
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
final hasFullscreen =
|
||||
@ -102,18 +103,22 @@ class TitleBar extends HookConsumerWidget implements PreferredSizeWidget {
|
||||
: leading,
|
||||
trailing: [
|
||||
...trailing,
|
||||
Align(
|
||||
alignment: Alignment.topRight,
|
||||
child:
|
||||
WindowTitleBarButtons(foregroundColor: foregroundColor),
|
||||
),
|
||||
],
|
||||
title: title,
|
||||
header: header,
|
||||
subtitle: subtitle,
|
||||
trailingExpanded: trailingExpanded,
|
||||
alignment: alignment,
|
||||
padding: padding,
|
||||
padding: padding ?? EdgeInsets.zero,
|
||||
backgroundColor: backgroundColor,
|
||||
leadingGap: leadingGap,
|
||||
trailingGap: trailingGap,
|
||||
height: height,
|
||||
height: height ?? (48 * context.theme.scaling),
|
||||
surfaceBlur: surfaceBlur,
|
||||
surfaceOpacity: surfaceOpacity,
|
||||
useSafeArea: useSafeArea,
|
||||
@ -127,5 +132,5 @@ class TitleBar extends HookConsumerWidget implements PreferredSizeWidget {
|
||||
}
|
||||
|
||||
@override
|
||||
Size get preferredSize => Size.fromHeight(height ?? 56.0);
|
||||
Size get preferredSize => Size.fromHeight(height ?? 48);
|
||||
}
|
||||
|
@ -2,9 +2,11 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:shadcn_flutter/shadcn_flutter_extension.dart';
|
||||
import 'package:spotube/components/hover_builder.dart';
|
||||
import 'package:spotube/components/titlebar/titlebar.dart';
|
||||
import 'package:spotube/components/titlebar/titlebar_icon_buttons.dart';
|
||||
import 'package:spotube/components/titlebar/window_button.dart';
|
||||
|
||||
import 'package:spotube/hooks/configurators/use_window_listener.dart';
|
||||
import 'package:spotube/provider/user_preferences/user_preferences_provider.dart';
|
||||
import 'package:spotube/utils/platform.dart';
|
||||
import 'package:titlebar_buttons/titlebar_buttons.dart';
|
||||
@ -22,12 +24,20 @@ class WindowTitleBarButtons extends HookConsumerWidget {
|
||||
final preferences = ref.watch(userPreferencesProvider);
|
||||
final isMaximized = useState<bool?>(null);
|
||||
const type = ThemeType.auto;
|
||||
final scale = context.theme.scaling;
|
||||
|
||||
Future<void> onClose() async {
|
||||
await windowManager.close();
|
||||
}
|
||||
|
||||
useWindowListener(
|
||||
onWindowMaximize: () {
|
||||
isMaximized.value = true;
|
||||
},
|
||||
onWindowUnmaximize: () {
|
||||
isMaximized.value = false;
|
||||
},
|
||||
);
|
||||
|
||||
useEffect(() {
|
||||
if (kIsDesktop) {
|
||||
windowManager.isMaximized().then((value) {
|
||||
@ -42,62 +52,45 @@ class WindowTitleBarButtons extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
if (kIsWindows) {
|
||||
final theme = Theme.of(context);
|
||||
final colors = WindowButtonColors(
|
||||
normal: Colors.transparent,
|
||||
iconNormal: foregroundColor ?? theme.colorScheme.onSurface,
|
||||
mouseOver: theme.colorScheme.onSurface.withAlpha(25),
|
||||
mouseDown: theme.colorScheme.onSurface.withAlpha(51),
|
||||
iconMouseOver: theme.colorScheme.onSurface,
|
||||
iconMouseDown: theme.colorScheme.onSurface,
|
||||
);
|
||||
|
||||
final closeColors = WindowButtonColors(
|
||||
normal: Colors.transparent,
|
||||
iconNormal: foregroundColor ?? theme.colorScheme.onSurface,
|
||||
mouseOver: Colors.red,
|
||||
mouseDown: Colors.red[800]!,
|
||||
iconMouseOver: Colors.white,
|
||||
iconMouseDown: Colors.black,
|
||||
);
|
||||
|
||||
return Transform(
|
||||
transform: Matrix4.translationValues(18, -12, 0) * scale,
|
||||
child: Row(
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
MinimizeWindowButton(
|
||||
ShadcnWindowButton(
|
||||
icon: MinimizeIcon(color: context.theme.colorScheme.foreground),
|
||||
onPressed: windowManager.minimize,
|
||||
colors: colors,
|
||||
),
|
||||
if (isMaximized.value != true)
|
||||
MaximizeWindowButton(
|
||||
colors: colors,
|
||||
ShadcnWindowButton(
|
||||
icon: MaximizeIcon(color: context.theme.colorScheme.foreground),
|
||||
onPressed: () {
|
||||
windowManager.maximize();
|
||||
isMaximized.value = true;
|
||||
},
|
||||
)
|
||||
else
|
||||
RestoreWindowButton(
|
||||
colors: colors,
|
||||
ShadcnWindowButton(
|
||||
icon: RestoreIcon(color: context.theme.colorScheme.foreground),
|
||||
onPressed: () {
|
||||
windowManager.unmaximize();
|
||||
isMaximized.value = false;
|
||||
},
|
||||
),
|
||||
CloseWindowButton(
|
||||
colors: closeColors,
|
||||
HoverBuilder(builder: (context, isHovered) {
|
||||
return ShadcnWindowButton(
|
||||
icon: CloseIcon(
|
||||
color: isHovered
|
||||
? Colors.white
|
||||
: context.theme.colorScheme.foreground,
|
||||
),
|
||||
onPressed: onClose,
|
||||
),
|
||||
hoverBackgroundColor: const Color(0xFFD32F2F),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Transform(
|
||||
transform: Matrix4.translationValues(18, -12, 0) * scale,
|
||||
child: Row(
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
DecoratedMinimizeButton(
|
||||
@ -121,7 +114,6 @@ class WindowTitleBarButtons extends HookConsumerWidget {
|
||||
onPressed: onClose,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,56 +1,50 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:spotube/components/titlebar/window_button.dart';
|
||||
import 'package:shadcn_flutter/shadcn_flutter.dart';
|
||||
import 'package:spotube/extensions/button_variance.dart';
|
||||
|
||||
class MinimizeWindowButton extends WindowButton {
|
||||
MinimizeWindowButton(
|
||||
{super.key, super.colors, super.onPressed, bool? animate})
|
||||
: super(
|
||||
animate: animate ?? false,
|
||||
iconBuilder: (buttonContext) =>
|
||||
MinimizeIcon(color: buttonContext.iconColor),
|
||||
class ShadcnWindowButton extends StatelessWidget {
|
||||
final Widget icon;
|
||||
final VoidCallback onPressed;
|
||||
final Color? hoverBackgroundColor;
|
||||
|
||||
const ShadcnWindowButton({
|
||||
super.key,
|
||||
required this.icon,
|
||||
required this.onPressed,
|
||||
this.hoverBackgroundColor,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
width: 45,
|
||||
height: 32,
|
||||
child: IconButton(
|
||||
variance: ButtonVariance.ghost.copyWith(
|
||||
decoration: (context, states) {
|
||||
final decoration = ButtonVariance.ghost.decoration(context, states)
|
||||
as BoxDecoration;
|
||||
if (hoverBackgroundColor != null &&
|
||||
states.contains(WidgetState.hovered)) {
|
||||
return decoration.copyWith(
|
||||
borderRadius: BorderRadius.zero,
|
||||
color: hoverBackgroundColor,
|
||||
);
|
||||
}
|
||||
|
||||
class MaximizeWindowButton extends WindowButton {
|
||||
MaximizeWindowButton(
|
||||
{super.key, super.colors, super.onPressed, bool? animate})
|
||||
: super(
|
||||
animate: animate ?? false,
|
||||
iconBuilder: (buttonContext) =>
|
||||
MaximizeIcon(color: buttonContext.iconColor),
|
||||
return decoration.copyWith(
|
||||
borderRadius: BorderRadius.zero,
|
||||
);
|
||||
},
|
||||
),
|
||||
icon: icon,
|
||||
onPressed: onPressed,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
class RestoreWindowButton extends WindowButton {
|
||||
RestoreWindowButton({super.key, super.colors, super.onPressed, bool? animate})
|
||||
: super(
|
||||
animate: animate ?? false,
|
||||
iconBuilder: (buttonContext) =>
|
||||
RestoreIcon(color: buttonContext.iconColor),
|
||||
);
|
||||
}
|
||||
|
||||
final _defaultCloseButtonColors = WindowButtonColors(
|
||||
mouseOver: const Color(0xFFD32F2F),
|
||||
mouseDown: const Color(0xFFB71C1C),
|
||||
iconNormal: const Color(0xFF805306),
|
||||
iconMouseOver: const Color(0xFFFFFFFF));
|
||||
|
||||
class CloseWindowButton extends WindowButton {
|
||||
CloseWindowButton(
|
||||
{super.key, WindowButtonColors? colors, super.onPressed, bool? animate})
|
||||
: super(
|
||||
colors: colors ?? _defaultCloseButtonColors,
|
||||
animate: animate ?? false,
|
||||
iconBuilder: (buttonContext) =>
|
||||
CloseIcon(color: buttonContext.iconColor),
|
||||
);
|
||||
}
|
||||
|
||||
// Switched to CustomPaint icons by https://github.com/esDotDev
|
||||
|
||||
/// Close
|
||||
class CloseIcon extends StatelessWidget {
|
||||
final Color color;
|
||||
@ -150,7 +144,8 @@ class _AlignedPaint extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return Align(
|
||||
alignment: Alignment.center,
|
||||
child: CustomPaint(size: const Size(10, 10), painter: painter));
|
||||
child: CustomPaint(size: const Size(10, 10), painter: painter),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,125 +0,0 @@
|
||||
import 'package:shadcn_flutter/shadcn_flutter.dart';
|
||||
import 'package:spotube/components/titlebar/mouse_state.dart';
|
||||
import 'package:spotube/components/titlebar/titlebar.dart';
|
||||
|
||||
typedef WindowButtonIconBuilder = Widget Function(
|
||||
WindowButtonContext buttonContext);
|
||||
typedef WindowButtonBuilder = Widget Function(
|
||||
WindowButtonContext buttonContext, Widget icon);
|
||||
|
||||
class WindowButtonContext {
|
||||
BuildContext context;
|
||||
MouseState mouseState;
|
||||
Color? backgroundColor;
|
||||
Color iconColor;
|
||||
WindowButtonContext(
|
||||
{required this.context,
|
||||
required this.mouseState,
|
||||
this.backgroundColor,
|
||||
required this.iconColor});
|
||||
}
|
||||
|
||||
class WindowButtonColors {
|
||||
late Color normal;
|
||||
late Color mouseOver;
|
||||
late Color mouseDown;
|
||||
late Color iconNormal;
|
||||
late Color iconMouseOver;
|
||||
late Color iconMouseDown;
|
||||
WindowButtonColors(
|
||||
{Color? normal,
|
||||
Color? mouseOver,
|
||||
Color? mouseDown,
|
||||
Color? iconNormal,
|
||||
Color? iconMouseOver,
|
||||
Color? iconMouseDown}) {
|
||||
this.normal = normal ?? _defaultButtonColors.normal;
|
||||
this.mouseOver = mouseOver ?? _defaultButtonColors.mouseOver;
|
||||
this.mouseDown = mouseDown ?? _defaultButtonColors.mouseDown;
|
||||
this.iconNormal = iconNormal ?? _defaultButtonColors.iconNormal;
|
||||
this.iconMouseOver = iconMouseOver ?? _defaultButtonColors.iconMouseOver;
|
||||
this.iconMouseDown = iconMouseDown ?? _defaultButtonColors.iconMouseDown;
|
||||
}
|
||||
}
|
||||
|
||||
final _defaultButtonColors = WindowButtonColors(
|
||||
normal: Colors.transparent,
|
||||
iconNormal: const Color(0xFF805306),
|
||||
mouseOver: const Color(0xFF404040),
|
||||
mouseDown: const Color(0xFF202020),
|
||||
iconMouseOver: const Color(0xFFFFFFFF),
|
||||
iconMouseDown: const Color(0xFFF0F0F0),
|
||||
);
|
||||
|
||||
class WindowButton extends StatelessWidget {
|
||||
final WindowButtonBuilder? builder;
|
||||
final WindowButtonIconBuilder? iconBuilder;
|
||||
late final WindowButtonColors colors;
|
||||
final bool animate;
|
||||
final EdgeInsets? padding;
|
||||
final VoidCallback? onPressed;
|
||||
|
||||
WindowButton(
|
||||
{super.key,
|
||||
WindowButtonColors? colors,
|
||||
this.builder,
|
||||
@required this.iconBuilder,
|
||||
this.padding,
|
||||
this.onPressed,
|
||||
this.animate = false}) {
|
||||
this.colors = colors ?? _defaultButtonColors;
|
||||
}
|
||||
|
||||
Color getBackgroundColor(MouseState mouseState) {
|
||||
if (mouseState.isMouseDown) return colors.mouseDown;
|
||||
if (mouseState.isMouseOver) return colors.mouseOver;
|
||||
return colors.normal;
|
||||
}
|
||||
|
||||
Color getIconColor(MouseState mouseState) {
|
||||
if (mouseState.isMouseDown) return colors.iconMouseDown;
|
||||
if (mouseState.isMouseOver) return colors.iconMouseOver;
|
||||
return colors.iconNormal;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (!kTitlebarVisible) return const SizedBox.shrink();
|
||||
|
||||
return MouseStateBuilder(
|
||||
builder: (context, mouseState) {
|
||||
WindowButtonContext buttonContext = WindowButtonContext(
|
||||
mouseState: mouseState,
|
||||
context: context,
|
||||
backgroundColor: getBackgroundColor(mouseState),
|
||||
iconColor: getIconColor(mouseState));
|
||||
|
||||
var icon = (iconBuilder != null)
|
||||
? iconBuilder!(buttonContext)
|
||||
: const SizedBox();
|
||||
|
||||
var fadeOutColor =
|
||||
getBackgroundColor(MouseState()..isMouseOver = true).withAlpha(0);
|
||||
var padding = this.padding ?? const EdgeInsets.all(10);
|
||||
var animationMs =
|
||||
mouseState.isMouseOver ? (animate ? 100 : 0) : (animate ? 200 : 0);
|
||||
Widget iconWithPadding = Padding(padding: padding, child: icon);
|
||||
iconWithPadding = AnimatedContainer(
|
||||
curve: Curves.easeOut,
|
||||
duration: Duration(milliseconds: animationMs),
|
||||
color: buttonContext.backgroundColor ?? fadeOutColor,
|
||||
child: iconWithPadding);
|
||||
var button =
|
||||
(builder != null) ? builder!(buttonContext, icon) : iconWithPadding;
|
||||
return SizedBox(
|
||||
width: 45,
|
||||
height: 32,
|
||||
child: button,
|
||||
);
|
||||
},
|
||||
onPressed: () {
|
||||
if (onPressed != null) onPressed!();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
@ -207,7 +207,9 @@ class Spotube extends HookConsumerWidget {
|
||||
child: child!,
|
||||
);
|
||||
|
||||
if (kIsDesktop && !kIsMacOS) child = DragToResizeArea(child: child);
|
||||
if (kIsLinux) {
|
||||
child = DragToResizeArea(child: child);
|
||||
}
|
||||
|
||||
return child;
|
||||
},
|
||||
|
@ -36,7 +36,7 @@ class HomePage extends HookConsumerWidget {
|
||||
bottom: false,
|
||||
child: Scaffold(
|
||||
headers: [
|
||||
if (kTitlebarVisible) const TitleBar(),
|
||||
if (kTitlebarVisible) const TitleBar(height: 30),
|
||||
],
|
||||
child: CustomScrollView(
|
||||
controller: controller,
|
||||
|
@ -2,8 +2,6 @@ import 'package:flutter/material.dart' show Badge;
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:shadcn_flutter/shadcn_flutter.dart';
|
||||
import 'package:shadcn_flutter/shadcn_flutter_extension.dart';
|
||||
|
||||
import 'package:spotube/modules/library/user_local_tracks.dart';
|
||||
import 'package:spotube/components/titlebar/titlebar.dart';
|
||||
import 'package:spotube/modules/library/user_albums.dart';
|
||||
@ -19,7 +17,6 @@ class LibraryPage extends HookConsumerWidget {
|
||||
const LibraryPage({super.key});
|
||||
@override
|
||||
Widget build(BuildContext context, ref) {
|
||||
final scale = context.theme.scaling;
|
||||
final downloadingCount = ref.watch(downloadManagerProvider).$downloadCount;
|
||||
final index = useState(0);
|
||||
|
||||
@ -40,11 +37,6 @@ class LibraryPage extends HookConsumerWidget {
|
||||
child: Scaffold(
|
||||
headers: [
|
||||
TitleBar(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 18,
|
||||
vertical: 12,
|
||||
).copyWith(left: 0) *
|
||||
scale,
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: TabList(
|
||||
|
@ -151,6 +151,8 @@ class LyricsPage extends HookConsumerWidget {
|
||||
? TitleBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
title: tabbar,
|
||||
height: 58 * context.theme.scaling,
|
||||
surfaceBlur: 0,
|
||||
)
|
||||
: tabbar
|
||||
],
|
||||
|
@ -70,7 +70,8 @@ class SearchPage extends HookConsumerWidget {
|
||||
bottom: false,
|
||||
child: Scaffold(
|
||||
headers: [
|
||||
if (kTitlebarVisible) const TitleBar(automaticallyImplyLeading: true)
|
||||
if (kTitlebarVisible)
|
||||
const TitleBar(automaticallyImplyLeading: true, height: 30)
|
||||
],
|
||||
child: auth.asData?.value == null
|
||||
? const AnonymousFallback()
|
||||
|
Loading…
Reference in New Issue
Block a user