Files
b0esche_cloud/b0esche_cloud/lib/pages/document_viewer.dart
2025-12-17 14:53:29 +01:00

156 lines
5.3 KiB
Dart

import 'package:flutter/material.dart';
import '../theme/app_theme.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../blocs/document_viewer/document_viewer_bloc.dart';
import '../blocs/document_viewer/document_viewer_event.dart';
import '../blocs/document_viewer/document_viewer_state.dart';
import '../services/file_service.dart';
import '../injection.dart';
import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart';
import 'package:go_router/go_router.dart';
class DocumentViewer extends StatefulWidget {
final String orgId;
final String fileId;
const DocumentViewer({super.key, required this.orgId, required this.fileId});
@override
State<DocumentViewer> createState() => _DocumentViewerState();
}
class _DocumentViewerState extends State<DocumentViewer> {
late DocumentViewerBloc _viewerBloc;
@override
void initState() {
super.initState();
_viewerBloc = DocumentViewerBloc(getIt<FileService>());
_viewerBloc.add(DocumentOpened(orgId: widget.orgId, fileId: widget.fileId));
}
@override
Widget build(BuildContext context) {
return BlocProvider.value(
value: _viewerBloc,
child: Scaffold(
appBar: AppBar(
title: const Text('Document Viewer'),
bottom: PreferredSize(
preferredSize: const Size.fromHeight(30),
child: BlocBuilder<DocumentViewerBloc, DocumentViewerState>(
builder: (context, state) {
if (state is DocumentViewerReady) {
// Placeholder for meta
return Container(
height: 30,
alignment: Alignment.centerLeft,
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text(
'Last modified: Unknown by Unknown (v1)',
style: const TextStyle(fontSize: 12),
),
);
}
return const SizedBox.shrink();
},
),
),
actions: [
BlocBuilder<DocumentViewerBloc, DocumentViewerState>(
builder: (context, state) {
if (state is DocumentViewerReady && state.caps.canEdit) {
return IconButton(
icon: const Icon(Icons.edit),
onPressed: () {
GoRouter.of(
context,
).go('/editor/${widget.orgId}/${widget.fileId}');
},
);
}
return const SizedBox.shrink();
},
),
IconButton(
icon: const Icon(Icons.refresh),
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
onPressed: () {
_viewerBloc.add(DocumentReloaded());
},
),
IconButton(
icon: const Icon(Icons.close),
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
onPressed: () {
_viewerBloc.add(DocumentClosed());
Navigator.of(context).pop();
},
),
],
),
body: BlocBuilder<DocumentViewerBloc, DocumentViewerState>(
builder: (context, state) {
if (state is DocumentViewerLoading) {
return const Center(child: CircularProgressIndicator());
}
if (state is DocumentViewerError) {
return Center(child: Text('Error: ${state.message}'));
}
if (state is DocumentViewerSessionExpired) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'Your viewing session expired. Click to reopen.',
),
ElevatedButton(
onPressed: () {
_viewerBloc.add(
DocumentOpened(
orgId: widget.orgId,
fileId: widget.fileId,
),
);
},
child: const Text('Reload'),
),
],
),
);
}
if (state is DocumentViewerReady) {
if (state.caps.isPdf) {
// Use PDF viewer
return SfPdfViewer.network(state.viewUrl.toString());
} else {
// Placeholder for office docs iframe
return Container(
color: AppTheme.secondaryText,
child: Center(
child: Text(
'Office Document Viewer\n(URL: ${state.viewUrl})',
textAlign: TextAlign.center,
style: const TextStyle(color: AppTheme.primaryText),
),
),
);
}
}
return const Center(child: Text('No document loaded'));
},
),
),
);
}
@override
void dispose() {
_viewerBloc.close();
super.dispose();
}
}