mirror of
https://github.com/gabehf/Fladder.git
synced 2026-03-07 21:48:14 -08:00
chore: Clean-up for status cards
This commit is contained in:
parent
c9ce5b9b90
commit
ed5598fc66
12 changed files with 69 additions and 81 deletions
|
|
@ -1,11 +1,13 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart';
|
import 'package:fladder/jellyfin/jellyfin_open_api.swagger.dart';
|
||||||
import 'package:fladder/models/item_base_model.dart';
|
import 'package:fladder/models/item_base_model.dart';
|
||||||
import 'package:fladder/models/items/images_models.dart';
|
import 'package:fladder/models/items/images_models.dart';
|
||||||
import 'package:fladder/models/items/item_shared_models.dart';
|
import 'package:fladder/models/items/item_shared_models.dart';
|
||||||
import 'package:fladder/models/items/overview_model.dart';
|
import 'package:fladder/models/items/overview_model.dart';
|
||||||
import 'package:fladder/util/localization_helper.dart';
|
import 'package:fladder/util/localization_helper.dart';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
||||||
|
|
||||||
class BookModel extends ItemBaseModel {
|
class BookModel extends ItemBaseModel {
|
||||||
final String? parentName;
|
final String? parentName;
|
||||||
|
|
@ -46,6 +48,9 @@ class BookModel extends ItemBaseModel {
|
||||||
@override
|
@override
|
||||||
double get progress => userData.progress != 0 ? 100 : 0;
|
double get progress => userData.progress != 0 ? 100 : 0;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? unplayedLabel(BuildContext context) => userData.progress != 0 ? context.localized.page(currentPage) : null;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String playButtonLabel(BuildContext context) => progress != 0
|
String playButtonLabel(BuildContext context) => progress != 0
|
||||||
? context.localized.continuePage(currentPage)
|
? context.localized.continuePage(currentPage)
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,8 @@ class ItemBaseModel with ItemBaseModelMappable {
|
||||||
|
|
||||||
bool get watched => userData.played;
|
bool get watched => userData.played;
|
||||||
|
|
||||||
|
String? unplayedLabel(BuildContext context) => null;
|
||||||
|
|
||||||
String? detailedName(BuildContext context) => "$name${overview.yearAired != null ? " (${overview.yearAired})" : ""}";
|
String? detailedName(BuildContext context) => "$name${overview.yearAired != null ? " (${overview.yearAired})" : ""}";
|
||||||
|
|
||||||
String? get subText => null;
|
String? get subText => null;
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,9 @@ class SeasonModel extends ItemBaseModel with SeasonModelMappable {
|
||||||
|
|
||||||
String localizedName(BuildContext context) => name.replaceFirst("Season", context.localized.season(1));
|
String localizedName(BuildContext context) => name.replaceFirst("Season", context.localized.season(1));
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? unplayedLabel(BuildContext context) => userData.played ? null : userData.unPlayedItemCount?.toString();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
SeriesModel get parentBaseModel => SeriesModel(
|
SeriesModel get parentBaseModel => SeriesModel(
|
||||||
originalTitle: '',
|
originalTitle: '',
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,9 @@ class SeriesModel extends ItemBaseModel with SeriesModelMappable {
|
||||||
return availableEpisodes?.map((e) => e).toList() ?? [];
|
return availableEpisodes?.map((e) => e).toList() ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? unplayedLabel(BuildContext context) => userData.played ? null : userData.unPlayedItemCount?.toString();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get syncAble => true;
|
bool get syncAble => true;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,10 +65,7 @@ class ChapterRow extends ConsumerWidget {
|
||||||
borderRadius: FladderTheme.smallShape.borderRadius,
|
borderRadius: FladderTheme.smallShape.borderRadius,
|
||||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||||
),
|
),
|
||||||
foregroundDecoration: BoxDecoration(
|
foregroundDecoration: FladderTheme.defaultPosterDecoration,
|
||||||
borderRadius: FladderTheme.smallShape.borderRadius,
|
|
||||||
border: Border.all(width: 2, color: Colors.white.withAlpha(25)),
|
|
||||||
),
|
|
||||||
child: AspectRatio(
|
child: AspectRatio(
|
||||||
aspectRatio: 1.75,
|
aspectRatio: 1.75,
|
||||||
child: CachedNetworkImage(
|
child: CachedNetworkImage(
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,9 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:iconsax_plus/iconsax_plus.dart';
|
import 'package:iconsax_plus/iconsax_plus.dart';
|
||||||
|
|
||||||
import 'package:fladder/models/book_model.dart';
|
|
||||||
import 'package:fladder/models/item_base_model.dart';
|
import 'package:fladder/models/item_base_model.dart';
|
||||||
import 'package:fladder/models/items/item_shared_models.dart';
|
import 'package:fladder/models/items/item_shared_models.dart';
|
||||||
import 'package:fladder/models/items/photos_model.dart';
|
import 'package:fladder/models/items/photos_model.dart';
|
||||||
import 'package:fladder/models/items/series_model.dart';
|
|
||||||
import 'package:fladder/screens/shared/media/components/poster_placeholder.dart';
|
import 'package:fladder/screens/shared/media/components/poster_placeholder.dart';
|
||||||
import 'package:fladder/theme.dart';
|
import 'package:fladder/theme.dart';
|
||||||
import 'package:fladder/util/adaptive_layout/adaptive_layout.dart';
|
import 'package:fladder/util/adaptive_layout/adaptive_layout.dart';
|
||||||
|
|
@ -84,7 +82,7 @@ class PosterImage extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
foregroundDecoration: BoxDecoration(
|
foregroundDecoration: BoxDecoration(
|
||||||
borderRadius: radius,
|
borderRadius: radius,
|
||||||
border: Border.all(width: 2, color: Colors.white.withAlpha(25)),
|
border: Border.all(width: 1, color: Colors.white.withAlpha(45)),
|
||||||
),
|
),
|
||||||
child: FladderImage(
|
child: FladderImage(
|
||||||
image: primaryPosters
|
image: primaryPosters
|
||||||
|
|
@ -94,26 +92,6 @@ class PosterImage extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
overlays: [
|
overlays: [
|
||||||
if (poster.userData.progress > 0 && poster.type == FladderItemType.book)
|
|
||||||
Align(
|
|
||||||
alignment: Alignment.topLeft,
|
|
||||||
child: Padding(
|
|
||||||
padding: padding,
|
|
||||||
child: Card(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(5.5),
|
|
||||||
child: Text(
|
|
||||||
context.localized.page((poster as BookModel).currentPage),
|
|
||||||
style: Theme.of(context).textTheme.labelLarge?.copyWith(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: Theme.of(context).colorScheme.primary,
|
|
||||||
fontSize: 12,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (selected == true)
|
if (selected == true)
|
||||||
Container(
|
Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
|
|
@ -196,20 +174,17 @@ class PosterImage extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if ((poster.unPlayedItemCount != null && poster is SeriesModel) || poster.watched)
|
if (poster.unplayedLabel(context) != null || poster.watched)
|
||||||
IgnorePointer(
|
IgnorePointer(
|
||||||
child: Align(
|
child: Align(
|
||||||
alignment: Alignment.topRight,
|
alignment: Alignment.topRight,
|
||||||
child: StatusCard(
|
child: StatusCard(
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).colorScheme.primaryContainer,
|
||||||
useFittedBox: poster.unPlayedItemCount != 0,
|
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(6),
|
padding: const EdgeInsets.all(6),
|
||||||
child: poster.unPlayedItemCount != 0
|
child: poster.unplayedLabel(context) != null
|
||||||
? Container(
|
? Text(
|
||||||
constraints: const BoxConstraints(minWidth: 16),
|
poster.unplayedLabel(context) ?? "",
|
||||||
child: Text(
|
|
||||||
poster.userData.unPlayedItemCount.toString(),
|
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
|
@ -217,7 +192,6 @@ class PosterImage extends ConsumerWidget {
|
||||||
overflow: TextOverflow.visible,
|
overflow: TextOverflow.visible,
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
),
|
),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
: Icon(
|
: Icon(
|
||||||
Icons.check_rounded,
|
Icons.check_rounded,
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ class PosterPlaceholder extends StatelessWidget {
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
children: [
|
children: [
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.topRight,
|
alignment: Alignment.topLeft,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(12.0),
|
padding: const EdgeInsets.all(12.0),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
|
|
|
||||||
|
|
@ -183,10 +183,7 @@ class EpisodePoster extends ConsumerWidget {
|
||||||
borderRadius: FladderTheme.smallShape.borderRadius,
|
borderRadius: FladderTheme.smallShape.borderRadius,
|
||||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||||
),
|
),
|
||||||
foregroundDecoration: BoxDecoration(
|
foregroundDecoration: FladderTheme.defaultPosterDecoration,
|
||||||
borderRadius: FladderTheme.smallShape.borderRadius,
|
|
||||||
border: Border.all(width: 2, color: Colors.white.withAlpha(25)),
|
|
||||||
),
|
|
||||||
child: FladderImage(
|
child: FladderImage(
|
||||||
image: !episodeAvailable ? episode.parentImages?.primary : episode.images?.primary,
|
image: !episodeAvailable ? episode.parentImages?.primary : episode.images?.primary,
|
||||||
placeHolder: placeHolder,
|
placeHolder: placeHolder,
|
||||||
|
|
|
||||||
|
|
@ -61,10 +61,7 @@ class PeopleRow extends ConsumerWidget {
|
||||||
borderRadius: FladderTheme.smallShape.borderRadius,
|
borderRadius: FladderTheme.smallShape.borderRadius,
|
||||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||||
),
|
),
|
||||||
foregroundDecoration: BoxDecoration(
|
foregroundDecoration: FladderTheme.defaultPosterDecoration,
|
||||||
borderRadius: FladderTheme.smallShape.borderRadius,
|
|
||||||
border: Border.all(width: 2, color: Colors.white.withAlpha(25)),
|
|
||||||
),
|
|
||||||
child: FocusButton(
|
child: FocusButton(
|
||||||
onTap: () => Navigator.of(context).push(
|
onTap: () => Navigator.of(context).push(
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
|
|
|
||||||
|
|
@ -89,10 +89,7 @@ class SeasonPoster extends ConsumerWidget {
|
||||||
borderRadius: FladderTheme.smallShape.borderRadius,
|
borderRadius: FladderTheme.smallShape.borderRadius,
|
||||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||||
),
|
),
|
||||||
foregroundDecoration: BoxDecoration(
|
foregroundDecoration: FladderTheme.defaultPosterDecoration,
|
||||||
borderRadius: FladderTheme.smallShape.borderRadius,
|
|
||||||
border: Border.all(width: 2, color: Colors.white.withAlpha(25)),
|
|
||||||
),
|
|
||||||
child: FladderImage(
|
child: FladderImage(
|
||||||
image: season.getPosters?.primary ??
|
image: season.getPosters?.primary ??
|
||||||
season.parentImages?.backDrop?.firstOrNull ??
|
season.parentImages?.backDrop?.firstOrNull ??
|
||||||
|
|
@ -153,11 +150,17 @@ class SeasonPoster extends ConsumerWidget {
|
||||||
if (season.userData.unPlayedItemCount != 0)
|
if (season.userData.unPlayedItemCount != 0)
|
||||||
StatusCard(
|
StatusCard(
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).colorScheme.primary,
|
||||||
useFittedBox: true,
|
child: Padding(
|
||||||
child: Center(
|
padding: const EdgeInsets.all(6),
|
||||||
child: Text(
|
child: Text(
|
||||||
season.userData.unPlayedItemCount.toString(),
|
season.userData.unPlayedItemCount.toString(),
|
||||||
style: const TextStyle(fontWeight: FontWeight.w700, fontSize: 14),
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
overflow: TextOverflow.visible,
|
||||||
|
fontSize: 14,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,11 @@ class FladderTheme {
|
||||||
static RoundedRectangleBorder get defaultShape => RoundedRectangleBorder(borderRadius: BorderRadius.circular(16));
|
static RoundedRectangleBorder get defaultShape => RoundedRectangleBorder(borderRadius: BorderRadius.circular(16));
|
||||||
static RoundedRectangleBorder get largeShape => RoundedRectangleBorder(borderRadius: BorderRadius.circular(32));
|
static RoundedRectangleBorder get largeShape => RoundedRectangleBorder(borderRadius: BorderRadius.circular(32));
|
||||||
|
|
||||||
|
static BoxDecoration get defaultPosterDecoration => BoxDecoration(
|
||||||
|
borderRadius: FladderTheme.smallShape.borderRadius,
|
||||||
|
border: Border.all(width: 1, color: Colors.white.withAlpha(45)),
|
||||||
|
);
|
||||||
|
|
||||||
static ThemeData theme(ColorScheme? colorScheme, DynamicSchemeVariant dynamicSchemeVariant) {
|
static ThemeData theme(ColorScheme? colorScheme, DynamicSchemeVariant dynamicSchemeVariant) {
|
||||||
final ColorScheme? scheme = generateDynamicColourSchemes(colorScheme, dynamicSchemeVariant);
|
final ColorScheme? scheme = generateDynamicColourSchemes(colorScheme, dynamicSchemeVariant);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,38 +2,40 @@ import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
|
import 'package:fladder/theme.dart';
|
||||||
|
|
||||||
class StatusCard extends ConsumerWidget {
|
class StatusCard extends ConsumerWidget {
|
||||||
final Color? color;
|
final Color? color;
|
||||||
final bool useFittedBox;
|
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
|
||||||
const StatusCard({this.color, this.useFittedBox = false, required this.child, super.key});
|
const StatusCard({this.color, required this.child, super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.all(2),
|
padding: const EdgeInsets.all(2.5),
|
||||||
child: SizedBox.square(
|
child: Container(
|
||||||
dimension: 33,
|
constraints: const BoxConstraints(minWidth: 32, minHeight: 32),
|
||||||
child: Card(
|
decoration: BoxDecoration(
|
||||||
elevation: 10,
|
color: blendColors(
|
||||||
surfaceTintColor: color,
|
Theme.of(context).colorScheme.surfaceContainer,
|
||||||
shadowColor: color != null ? Colors.transparent : null,
|
blend: color,
|
||||||
|
),
|
||||||
|
borderRadius: FladderTheme.smallShape.borderRadius,
|
||||||
|
),
|
||||||
child: IconTheme(
|
child: IconTheme(
|
||||||
data: IconThemeData(
|
data: IconThemeData(
|
||||||
color: color,
|
color: color,
|
||||||
),
|
),
|
||||||
child: Center(
|
|
||||||
child: useFittedBox
|
|
||||||
? FittedBox(
|
|
||||||
fit: BoxFit.scaleDown,
|
|
||||||
child: child,
|
child: child,
|
||||||
)
|
|
||||||
: child,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Color blendColors(Color base, {Color? blend, double amount = 0.25}) {
|
||||||
|
if (blend == null) return base;
|
||||||
|
|
||||||
|
return Color.lerp(base, blend, amount) ?? base;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue