import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:worldhopper/services/url_helper.dart'; part 'opds_server.freezed.dart'; part 'opds_server.g.dart'; /// Represents an OPDS server configuration @freezed class OPDSServer with _$OPDSServer { const factory OPDSServer({ /// Unique identifier for the server required String id, /// Display name for the server required String name, /// Root URL of the OPDS server required String url, /// Optional username for HTTP Basic Auth String? username, /// Optional password for HTTP Basic Auth (stored encrypted in database) String? password, /// Timestamp when the server was added required DateTime createdAt, /// Timestamp of the last successful sync DateTime? lastSyncedAt, /// Whether KOReader sync is enabled for this server @Default(false) bool koreaderSyncEnabled, /// KOReader sync server URL (e.g., https://sync.example.com) String? koreaderSyncUrl, /// KOReader sync username String? koreaderSyncUsername, /// KOReader sync password String? koreaderSyncPassword, }) = _OPDSServer; /// Create OPDSServer from JSON factory OPDSServer.fromJson(Map json) => _$OPDSServerFromJson(json); /// Create OPDSServer from database row factory OPDSServer.fromDatabase(Map row) { return OPDSServer( id: row['id'] as String, name: row['name'] as String, url: row['url'] as String, username: row['username'] as String?, password: row['password'] as String?, createdAt: DateTime.fromMillisecondsSinceEpoch(row['created_at'] as int), lastSyncedAt: row['last_synced_at'] != null ? DateTime.fromMillisecondsSinceEpoch(row['last_synced_at'] as int) : null, koreaderSyncEnabled: (row['koreader_sync_enabled'] as int?) == 1, koreaderSyncUrl: row['koreader_sync_url'] as String?, koreaderSyncUsername: row['koreader_sync_username'] as String?, koreaderSyncPassword: row['koreader_sync_password'] as String?, ); } } extension OPDSServerX on OPDSServer { /// Convert OPDSServer to database row Map toDatabase() { return { 'id': id, 'name': name, 'url': url, 'username': username, 'password': password, 'created_at': createdAt.millisecondsSinceEpoch, 'last_synced_at': lastSyncedAt?.millisecondsSinceEpoch, 'koreader_sync_enabled': koreaderSyncEnabled ? 1 : 0, 'koreader_sync_url': koreaderSyncUrl, 'koreader_sync_username': koreaderSyncUsername, 'koreader_sync_password': koreaderSyncPassword, }; } /// Check if server requires authentication bool get requiresAuth => username != null && password != null; /// Resolve a relative URL against this server's base URL String resolveUrl(String relativeUrl) { return UrlHelper.resolveUrl(url, relativeUrl); } /// Make a request URL by resolving it against the server base String makeRequest(String path) { return UrlHelper.resolveUrl(url, path); } }