QinGang_interested/lib/customWidget/read_file_page.dart

203 lines
5.3 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import 'dart:async';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:docx_viewer/docx_viewer.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pdfx/pdfx.dart';
import 'package:qhd_prevention/pages/my_appbar.dart';
class ReadFilePage extends StatefulWidget {
final String fileUrl;
final int countdownSeconds;
const ReadFilePage({
Key? key,
required this.fileUrl,
this.countdownSeconds = 3,
}) : super(key: key);
@override
State<ReadFilePage> createState() => _ReadFilePageState();
}
class _ReadFilePageState extends State<ReadFilePage> {
String? _localPath;
bool _isLoading = true;
bool _hasScrolledToBottom = false;
bool _timerFinished = false;
late int _secondsRemaining;
Timer? _countdownTimer;
PdfControllerPinch? _pdfController;
int _totalPages = 0;
bool _isDocxFile = false;
@override
void initState() {
super.initState();
_secondsRemaining = widget.countdownSeconds;
_startCountdown();
_prepareFile();
}
bool _isDocxUrl(String url) {
final path = Uri.parse(url).path.toLowerCase();
return path.endsWith('.docx') || path.endsWith('.doc');
}
bool _isPdfUrl(String url) {
final path = Uri.parse(url).path.toLowerCase();
return path.endsWith('.pdf');
}
Future<void> _prepareFile() async {
final url = widget.fileUrl;
if (_isDocxUrl(url)) {
if (!mounted) return;
setState(() {
_isDocxFile = true;
_isLoading = false;
});
return;
}
if (!_isPdfUrl(url)) {
if (!mounted) return;
setState(() {
_isLoading = false;
});
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('目前仅支持 PDF、DOCX、DOC 文件预览')),
);
return;
}
await _downloadAndLoadPdf();
}
Future<void> _downloadAndLoadPdf() async {
try {
final url = widget.fileUrl;
final uri = Uri.parse(url);
final filename = uri.pathSegments.isNotEmpty ? uri.pathSegments.last : 'temp.pdf';
final dir = await getTemporaryDirectory();
final filePath = '${dir.path}/$filename';
final dio = Dio();
await dio.download(url, filePath);
if (!mounted) return;
_pdfController = PdfControllerPinch(
document: PdfDocument.openFile(filePath),
);
setState(() {
_localPath = filePath;
_isLoading = false;
});
} catch (e) {
if (!mounted) return;
setState(() {
_isLoading = false;
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('文件加载失败:$e')),
);
}
}
void _startCountdown() {
_countdownTimer?.cancel();
_countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
if (!mounted) return;
setState(() {
if (_secondsRemaining > 1) {
_secondsRemaining--;
} else {
_secondsRemaining = 0;
_timerFinished = true;
_countdownTimer?.cancel();
}
});
});
}
@override
void dispose() {
_countdownTimer?.cancel();
_pdfController?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final isButtonEnabled = _timerFinished && _hasScrolledToBottom;
return Scaffold(
appBar: MyAppbar(title: '文件详情'),
backgroundColor: Colors.white,
body: SafeArea(
child: Column(
children: [
Expanded(
child: _isLoading
? const Center(child: CircularProgressIndicator())
: _isDocxFile
? DocxView(
filePath: widget.fileUrl,
fontSize: 16,
onError: (error) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('DOCX 加载失败:$error')),
);
},
)
: _pdfController == null
? const Center(
child: Text('文件无法预览,请确认链接有效且为 PDF 文件'),
)
: PdfViewPinch(
controller: _pdfController!,
scrollDirection: Axis.vertical,
onDocumentLoaded: (document) {
setState(() {
_totalPages = document.pagesCount;
});
},
onPageChanged: (page) {
if (_totalPages > 0 && page == _totalPages - 1) {
setState(() => _hasScrolledToBottom = true);
}
},
),
),
// Padding(
// padding: const EdgeInsets.all(16),
// child: ElevatedButton(
// onPressed: isButtonEnabled
// ? () {
// Navigator.pop(context);
// }
// : null,
// child: Text(
// isButtonEnabled
// ? '我已学习完毕'
// : _secondsRemaining == 0
// ? '请阅读完成'
// : '$_secondsRemaining s我已学习完毕',
// ),
// ),
// ),
],
),
),
);
}
}