import 'package:freezed_annotation/freezed_annotation.dart'; part 'opds_stream_link.freezed.dart'; part 'opds_stream_link.g.dart'; /// Represents an OPDS-PSE stream link for page-by-page reading @freezed class OPDSStreamLink with _$OPDSStreamLink { const factory OPDSStreamLink({ /// URL template with {pageNumber} and optionally {maxWidth} placeholders /// This should be an absolute URL (resolved against server base URL during parsing) required String href, /// Image MIME type (image/jpeg, image/png, image/gif) required String type, /// Total number of pages required int pageCount, /// Last read page (0-indexed), null if never read int? lastRead, /// Last read timestamp DateTime? lastReadDate, }) = _OPDSStreamLink; const OPDSStreamLink._(); /// Create OPDSStreamLink from JSON factory OPDSStreamLink.fromJson(Map json) => _$OPDSStreamLinkFromJson(json); /// Check if the URL template supports maxWidth parameter bool get supportsMaxWidth => href.contains('{maxWidth}'); /// Generate the URL for a specific page String getPageUrl(int pageNumber, {int? maxWidth}) { var url = href.replaceAll('{pageNumber}', pageNumber.toString()); if (supportsMaxWidth && maxWidth != null) { url = url.replaceAll('{maxWidth}', maxWidth.toString()); } else if (supportsMaxWidth) { // Remove maxWidth parameter if not provided url = url.replaceAll(RegExp(r'[?&]maxWidth=\{maxWidth\}'), ''); url = url.replaceAll(RegExp(r'[?&]size=\{maxWidth\}'), ''); } return url; } }