mirror of
https://github.com/jagandeepbrar/lunasea.git
synced 2026-08-31 12:42:34 +00:00
feat(ui): support skeleton-state loading on LunaBlock
This commit is contained in:
@@ -30,6 +30,7 @@ export 'ui/popup_menu_button.dart';
|
||||
export 'ui/refresh_indicator.dart';
|
||||
export 'ui/scaffold.dart';
|
||||
export 'ui/shape.dart';
|
||||
export 'ui/shimmer.dart';
|
||||
export 'ui/snackbar.dart';
|
||||
export 'ui/switch.dart';
|
||||
export 'ui/table.dart';
|
||||
@@ -70,8 +71,9 @@ class LunaUI {
|
||||
|
||||
// <--> Animations
|
||||
static const int ANIMATION_SPEED = 250;
|
||||
static const int ANIMATION_SPEED_IMAGES = 125;
|
||||
static const int ANIMATION_SPEED_IMAGES = ANIMATION_SPEED ~/ 2;
|
||||
static const int ANIMATION_SPEED_SCROLLING = ANIMATION_SPEED * 2;
|
||||
static const int ANIMATION_SPEED_SHIMMER = ANIMATION_SPEED * 4;
|
||||
|
||||
// <--> Other
|
||||
static const double BORDER_RADIUS = 10.0;
|
||||
|
||||
@@ -5,6 +5,11 @@ class LunaBlock extends StatelessWidget {
|
||||
static const TITLE_HEIGHT = LunaUI.FONT_SIZE_H2 + 4.0;
|
||||
static const SUBTITLE_HEIGHT = LunaUI.FONT_SIZE_H3 + 4.0;
|
||||
|
||||
// If true, will load a skeleton-form version of the block.
|
||||
final bool skeletonEnabled;
|
||||
final bool skeletonPoster;
|
||||
final int skeletonSubtitles;
|
||||
|
||||
final bool? disabled;
|
||||
final String? title;
|
||||
final Color titleColor;
|
||||
@@ -37,8 +42,11 @@ class LunaBlock extends StatelessWidget {
|
||||
|
||||
const LunaBlock({
|
||||
Key? key,
|
||||
this.skeletonEnabled = false,
|
||||
this.skeletonPoster = true,
|
||||
this.skeletonSubtitles = 2,
|
||||
this.disabled = false,
|
||||
required this.title,
|
||||
this.title,
|
||||
this.titleColor = Colors.white,
|
||||
this.body,
|
||||
this.bodyLeadingIcons,
|
||||
@@ -92,11 +100,36 @@ class LunaBlock extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
double _calculateSkeletonHeight() {
|
||||
return calculateItemHeight(
|
||||
skeletonSubtitles,
|
||||
hasBottom: bottom != null,
|
||||
bottomHeight: bottomHeight,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (skeletonEnabled) return _buildSkeletonBlock(context);
|
||||
return _buildBlock(context);
|
||||
}
|
||||
|
||||
Widget _buildSkeletonBlock(BuildContext context) {
|
||||
double _height = _calculateSkeletonHeight();
|
||||
return LunaCard(
|
||||
context: context,
|
||||
child: LunaShimmer(
|
||||
child: Row(
|
||||
children: [
|
||||
if (skeletonPoster) _poster(context, _height),
|
||||
_tile(context, _height),
|
||||
],
|
||||
),
|
||||
),
|
||||
height: _height,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBlock(BuildContext context) {
|
||||
double _height = _calculateHeight();
|
||||
return LunaCard(
|
||||
@@ -160,11 +193,29 @@ class LunaBlock extends StatelessWidget {
|
||||
}
|
||||
|
||||
Widget _poster(BuildContext context, double height) {
|
||||
double _dimension = height - LunaUI.DEFAULT_MARGIN_SIZE;
|
||||
|
||||
if (skeletonEnabled) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: LunaUI.MARGIN_SIZE_HALF),
|
||||
child: Container(
|
||||
height: _dimension,
|
||||
width: _dimension / (posterIsSquare ? 1.0 : 1.5),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).canvasColor,
|
||||
borderRadius: BorderRadius.circular(LunaUI.BORDER_RADIUS),
|
||||
border: LunaUI.shouldUseBorder
|
||||
? Border.all(color: LunaColours.white10)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (posterUrl == null && posterPlaceholderIcon == null) {
|
||||
return const SizedBox(width: 0.0, height: 0.0);
|
||||
}
|
||||
|
||||
double _dimension = height - LunaUI.DEFAULT_MARGIN_SIZE;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: LunaUI.MARGIN_SIZE_HALF),
|
||||
child: LunaNetworkImage(
|
||||
@@ -179,6 +230,44 @@ class LunaBlock extends StatelessWidget {
|
||||
}
|
||||
|
||||
Widget _tile(BuildContext context, double height) {
|
||||
if (skeletonEnabled) {
|
||||
return Expanded(
|
||||
child: Padding(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
height: LunaBlock.TITLE_HEIGHT - 4.0,
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).canvasColor,
|
||||
borderRadius: BorderRadius.circular(LunaUI.BORDER_RADIUS),
|
||||
border: LunaUI.shouldUseBorder
|
||||
? Border.all(color: LunaColours.white10)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
...List.generate(skeletonSubtitles, (_) {
|
||||
return Container(
|
||||
height: LunaBlock.SUBTITLE_HEIGHT - 6.0,
|
||||
width: MediaQuery.of(context).size.width / 2.5,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).canvasColor,
|
||||
borderRadius: BorderRadius.circular(LunaUI.BORDER_RADIUS),
|
||||
border: LunaUI.shouldUseBorder
|
||||
? Border.all(color: LunaColours.white10)
|
||||
: null,
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
padding: LunaUI.MARGIN_DEFAULT,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Expanded(
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
child: LunaListTile(
|
||||
|
||||
21
lib/core/ui/shimmer.dart
Normal file
21
lib/core/ui/shimmer.dart
Normal file
@@ -0,0 +1,21 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lunasea/core.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
|
||||
class LunaShimmer extends StatelessWidget {
|
||||
final Widget child;
|
||||
|
||||
const LunaShimmer({
|
||||
Key? key,
|
||||
required this.child,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Shimmer.fromColors(
|
||||
child: child,
|
||||
baseColor: Theme.of(context).primaryColor,
|
||||
highlightColor: LunaColours.accent,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1143,6 +1143,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
shimmer:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: shimmer
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
simple_gesture_detector:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -49,6 +49,7 @@ dependencies:
|
||||
quick_actions: ^0.6.0+9
|
||||
retrofit: ^3.0.1
|
||||
share_plus: ^3.0.4
|
||||
shimmer: ^2.0.0
|
||||
stack_trace: ^1.10.0
|
||||
stash_memory: ^4.0.1
|
||||
supercharged: ^2.1.1
|
||||
|
||||
Reference in New Issue
Block a user