feat: 逻辑与页面布局分离
This commit is contained in:
1 parent
b1f6ce4bf9
commit
1e61ae7a0b
11 files changed
+1233
-907
No files matched your search
@@ -2,8 +2,11 @@ import 'package:flutter/material.dart';
|
||||
|
||||
import '../../core/data/models/drama.dart';
|
||||
import '../../core/data/repositories/watch_history_repository.dart';
|
||||
import '../../l10n/app_localizations.dart';
|
||||
|
||||
class DiscoverLogic {
|
||||
enum DiscoverPageAction { home, my, watchlist, detail, resume }
|
||||
|
||||
class DiscoverLogic extends ChangeNotifier {
|
||||
DiscoverLogic({required this.history, required this.drama}) {
|
||||
refreshPosition();
|
||||
}
|
||||
@@ -15,6 +18,11 @@ class DiscoverLogic {
|
||||
final FocusNode searchFocus = FocusNode();
|
||||
final ScrollController scroll = ScrollController();
|
||||
int category = 0;
|
||||
bool _disposed = false;
|
||||
|
||||
void notify() {
|
||||
if (!_disposed) notifyListeners();
|
||||
}
|
||||
|
||||
void refreshPosition() {
|
||||
position = history.positionFor(
|
||||
@@ -24,9 +32,125 @@ class DiscoverLogic {
|
||||
);
|
||||
}
|
||||
|
||||
void selectCategory(int index) {
|
||||
category = index;
|
||||
notify();
|
||||
}
|
||||
|
||||
void onSearchChanged() => notify();
|
||||
|
||||
void syncDrama({
|
||||
required bool active,
|
||||
required bool wasActive,
|
||||
required Drama nextDrama,
|
||||
required bool dramaChanged,
|
||||
required int searchRequest,
|
||||
required int previousSearchRequest,
|
||||
required bool Function() isActive,
|
||||
}) {
|
||||
if (active && (!wasActive || dramaChanged)) {
|
||||
drama = nextDrama;
|
||||
refreshPosition();
|
||||
notify();
|
||||
}
|
||||
if (active && searchRequest != previousSearchRequest) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (isActive()) searchFocus.requestFocus();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void act(
|
||||
BuildContext context,
|
||||
DiscoverPageAction action, {
|
||||
required bool embedded,
|
||||
ValueChanged<DiscoverPageAction>? onAction,
|
||||
}) {
|
||||
if (embedded) {
|
||||
onAction?.call(action);
|
||||
} else {
|
||||
Navigator.pop(context, action);
|
||||
}
|
||||
}
|
||||
|
||||
Drama? dramaFor(String? dramaId, List<Drama> dramas) {
|
||||
for (final item in dramas) {
|
||||
if (item.id == dramaId) return item;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void openCard(
|
||||
BuildContext context,
|
||||
Drama? selected, {
|
||||
required bool embedded,
|
||||
ValueChanged<Drama>? onDramaSelected,
|
||||
ValueChanged<DiscoverPageAction>? onAction,
|
||||
}) {
|
||||
if (selected == null) {
|
||||
unavailable(context);
|
||||
} else if (embedded && onDramaSelected != null) {
|
||||
onDramaSelected(selected);
|
||||
} else {
|
||||
act(context, DiscoverPageAction.detail, embedded: embedded, onAction: onAction);
|
||||
}
|
||||
}
|
||||
|
||||
void unavailable(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text(l10n.artworkOnlyNotice)));
|
||||
}
|
||||
|
||||
void catalogInfo(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text(l10n.demoCatalogNotice)));
|
||||
}
|
||||
|
||||
void showFilters(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
final labels = [
|
||||
l10n.featured,
|
||||
l10n.suspense,
|
||||
l10n.romance,
|
||||
l10n.actionGenre,
|
||||
];
|
||||
showModalBottomSheet<void>(
|
||||
context: context,
|
||||
backgroundColor: const Color(0xFF202126),
|
||||
showDragHandle: true,
|
||||
builder: (sheetContext) => SafeArea(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ListTile(title: Text(l10n.filter)),
|
||||
for (var index = 0; index < labels.length; index++)
|
||||
ListTile(
|
||||
title: Text(labels[index]),
|
||||
trailing: index == category
|
||||
? const Icon(Icons.check_rounded, color: Color(0xFFFF5B3D))
|
||||
: null,
|
||||
onTap: () {
|
||||
selectCategory(index);
|
||||
Navigator.pop(sheetContext);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_disposed = true;
|
||||
search.dispose();
|
||||
searchFocus.dispose();
|
||||
scroll.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user