import 'package:flutter/material.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:onsolgo/core/constants.dart'; import 'package:onsolgo/core/share_helper.dart'; import 'package:onsolgo/widgets/energy_user_chip.dart'; import 'package:onsolgo/widgets/comments_sheet.dart'; class ReaderView extends StatefulWidget { final DocumentSnapshot manga; final DocumentSnapshot chapter; const ReaderView({super.key, required this.manga, required this.chapter}); @override State createState() => _ReaderViewState(); } class _ReaderViewState extends State { final GlobalKey _readerKey = GlobalKey(); bool _showUI = true; int _curIdx = 0; DocumentReference _pageInteractionRef() { return widget.manga.reference .collection('chapters') .doc(widget.chapter.id) .collection('page_interactions') .doc('${_curIdx + 1}'); } Future _togglePageLike() async { final uid = FirebaseAuth.instance.currentUser?.uid; if (uid == null) { ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Sign in to react to pages'))); return; } final pageRef = _pageInteractionRef(); try { await FirebaseFirestore.instance.runTransaction((txn) async { final snap = await txn.get(pageRef); List liked = []; final raw = snap.data() as Map?; if (snap.exists && raw != null) { liked = List.from((raw['likedBy'] as List?)?.map((e) => e.toString()) ?? []); } final set = liked.toSet(); if (set.contains(uid)) { set.remove(uid); } else { set.add(uid); } final next = set.toList(); final payload = {'likedBy': next, 'likes': next.length}; if (snap.exists) { txn.update(pageRef, payload); } else { txn.set(pageRef, payload); } }); } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Could not update: $e'))); } } } void _openPageComments() { CommentsSheet.show( context, parent: _pageInteractionRef(), title: 'Page ${_curIdx + 1} · Comments', ); } @override Widget build(BuildContext context) { final cD = widget.chapter.data() as Map; final mD = widget.manga.data() as Map; final total = safeInt(cD['pageCount']); final uid = FirebaseAuth.instance.currentUser?.uid ?? ''; return Scaffold( backgroundColor: Colors.black, body: GestureDetector( onTap: () => setState(() => _showUI = !_showUI), child: Stack(children: [ RepaintBoundary( key: _readerKey, child: Container( color: Colors.black, child: PageView.builder( reverse: mD['readingMode'] == "RL", itemCount: total, onPageChanged: (idx) => setState(() => _curIdx = idx), itemBuilder: (context, index) { final url = "${cD['baseUrl']}PG-${(index + 1).toString().padLeft(3, '0')}.webp"; return InteractiveViewer( child: CachedNetworkImage(imageUrl: url, fit: BoxFit.contain), ); }, ), ), ), if (_showUI) Positioned( top: 0, left: 0, right: 0, child: AppBar( backgroundColor: Colors.black.withValues(alpha: 0.7), title: Text("PG ${_curIdx + 1}"), actions: [ Padding( padding: const EdgeInsets.only(right: 4, top: 4, bottom: 4), child: EnergyUserChip(uid: FirebaseAuth.instance.currentUser?.uid ?? ''), ), IconButton( icon: const Icon(Icons.share, color: kOnsolGold), onPressed: () => OnsolShare.share( _readerKey, "Check out ${mD['title']} Ch ${cD['chapterNumber']} on ONSOL-GO!", link: kOnsolShareChapterUrl(widget.manga.id, cD['chapterNumber']), ), ), ], ), ), if (_showUI) Positioned( left: 0, right: 0, bottom: 0, child: Material( color: Colors.black.withValues(alpha: 0.82), child: SafeArea( top: false, child: StreamBuilder( stream: _pageInteractionRef().snapshots(), builder: (context, snap) { final data = snap.data?.data() as Map?; final likedBy = List.from( (data?['likedBy'] as List?)?.map((e) => e.toString()) ?? [], ); final liked = uid.isNotEmpty && likedBy.contains(uid); final count = likedBy.length; return Padding( padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 4), child: Row( children: [ IconButton( icon: Icon( liked ? Icons.favorite : Icons.favorite_border, color: liked ? Colors.redAccent : Colors.white70, ), tooltip: 'Like this page', onPressed: _togglePageLike, ), Text('$count', style: const TextStyle(color: Colors.white70, fontWeight: FontWeight.w600)), const SizedBox(width: 4), IconButton( icon: const Icon(Icons.chat_bubble_outline, color: Colors.white70), tooltip: 'Comments on this page', onPressed: _openPageComments, ), const Text('Comment', style: TextStyle(color: Colors.white54, fontSize: 13)), const Spacer(), Text( '${mD['title'] ?? ''} · Ch ${cD['chapterNumber']}', style: TextStyle(color: Colors.grey[500], fontSize: 11), overflow: TextOverflow.ellipsis, ), ], ), ); }, ), ), ), ), ]), ), ); } }