import 'package:dio/dio.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:voyagehandbook/api/wikimedia.dart'; import 'package:voyagehandbook/util/drawer.dart'; import 'package:voyagehandbook/util/render.dart'; import 'package:voyagehandbook/util/storage.dart'; import 'package:voyagehandbook/util/styles.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; /* Voyage Handbook - The open-source WikiVoyage reader Copyright (C) 2023 Matyáš Caras This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /// Renders a single WikiVoyage article class ArticleView extends StatefulWidget { const ArticleView({super.key, required this.pageKey, required this.name}); final String pageKey; final String name; @override State createState() => _ArticleViewState(); } class _ArticleViewState extends State { var _content = []; @override didChangeDependencies() { super.didChangeDependencies(); loadPage(); } @override void initState() { super.initState(); addToRecents(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( actions: (kDebugMode) ? [ IconButton( onPressed: () => loadPage(), icon: const Icon(Icons.restart_alt)) ] : null), drawer: genDrawer(0, context), body: Center( child: SizedBox( height: MediaQuery.of(context).size.height, width: MediaQuery.of(context).size.width * 0.9, child: SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: _content, ), ), ), ), ); } void loadPage() async { if (!mounted) return; var renderer = PageRenderer( Theme.of(context).colorScheme, MediaQuery.of(context).size.height, MediaQuery.of(context).size.width, context, AppLocalizations.of(context)!); try { _content = [ SizedBox( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height, child: await renderer .renderFromPageHTML(await WikiApi.getRawPage(widget.pageKey)), ) ]; } catch (e) { if (e.toString().contains("Failed host lookup")) { // user is offline var offline = await StorageAccess.getOfflinePage(widget.pageKey); if (offline == null) { // Not downloaded, show error if (!mounted) return; _content = [ Text( AppLocalizations.of(context)!.renderError, style: PageStyles.h1, ), const SizedBox( height: 10, ), Text(AppLocalizations.of(context)!.offlineError) ]; } else { // Render offline version if (!mounted) return; _content = [ SizedBox( width: MediaQuery.of(context).size.width * 0.9, height: MediaQuery.of(context).size.height, child: await renderer.renderFromPageHTML(offline), ) ]; } } else { _content = [ Text( AppLocalizations.of(context)!.renderError, style: PageStyles.h1, ), const SizedBox( height: 10, ), Text(e.toString()) ]; } } setState(() {}); } void addToRecents() { StorageAccess.addToRecents(widget.name, widget.pageKey); if (kDebugMode) { print("Added ${widget.name} to recent"); } } }