Co-authored-by: Felipe M. <me@fmartingr.com> Co-committed-by: Felipe M. <me@fmartingr.com>
81 lines
2 KiB
Dart
81 lines
2 KiB
Dart
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
import 'package:worldhopper/models/opds_entry.dart';
|
|
import 'package:worldhopper/models/opds_link.dart';
|
|
|
|
part 'opds_feed.freezed.dart';
|
|
part 'opds_feed.g.dart';
|
|
|
|
/// Represents an OPDS feed (navigation or acquisition)
|
|
@freezed
|
|
class OPDSFeed with _$OPDSFeed {
|
|
const factory OPDSFeed({
|
|
/// Feed ID
|
|
required String id,
|
|
|
|
/// Feed title
|
|
required String title,
|
|
|
|
/// Feed subtitle
|
|
String? subtitle,
|
|
|
|
/// Feed icon URL
|
|
String? icon,
|
|
|
|
/// Last update timestamp
|
|
DateTime? updated,
|
|
|
|
/// Feed author
|
|
String? author,
|
|
|
|
/// All links in the feed
|
|
@Default([]) List<OPDSLink> links,
|
|
|
|
/// All entries in the feed
|
|
@Default([]) List<OPDSEntry> entries,
|
|
|
|
/// Total results (for paginated feeds)
|
|
int? totalResults,
|
|
|
|
/// Items per page (for paginated feeds)
|
|
int? itemsPerPage,
|
|
|
|
/// Start index (for paginated feeds)
|
|
int? startIndex,
|
|
}) = _OPDSFeed;
|
|
|
|
const OPDSFeed._();
|
|
|
|
/// Create OPDSFeed from JSON
|
|
factory OPDSFeed.fromJson(Map<String, dynamic> json) =>
|
|
_$OPDSFeedFromJson(json);
|
|
|
|
/// Check if this is a navigation feed
|
|
bool get isNavigationFeed => entries.any((entry) => entry.isNavigation);
|
|
|
|
/// Check if this is an acquisition feed (contains publications)
|
|
bool get isAcquisitionFeed => !isNavigationFeed;
|
|
|
|
/// Get the start (root) link
|
|
OPDSLink? get startLink => links.cast<OPDSLink?>().firstWhere(
|
|
(link) => link?.rel == 'start',
|
|
orElse: () => null,
|
|
);
|
|
|
|
/// Get the self link
|
|
OPDSLink? get selfLink => links.cast<OPDSLink?>().firstWhere(
|
|
(link) => link?.rel == 'self',
|
|
orElse: () => null,
|
|
);
|
|
|
|
/// Get the next page link
|
|
OPDSLink? get nextLink => links.cast<OPDSLink?>().firstWhere(
|
|
(link) => link?.rel == 'next',
|
|
orElse: () => null,
|
|
);
|
|
|
|
/// Get the previous page link
|
|
OPDSLink? get previousLink => links.cast<OPDSLink?>().firstWhere(
|
|
(link) => link?.rel == 'previous' || link?.rel == 'prev',
|
|
orElse: () => null,
|
|
);
|
|
}
|