218 lines
6.0 KiB
Dart
218 lines
6.0 KiB
Dart
import 'dart:convert';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
import 'package:lamiter/Class/Diagnosis/urban_disease.dart';
|
|
import 'package:lamiter/Component/AppBar/title_app_bar.dart';
|
|
import 'package:lamiter/Component/toggle_info_layout.dart';
|
|
import 'package:lamiter/Extension/build_context.dart';
|
|
import 'package:lamiter/Extension/iterable.dart';
|
|
import 'package:lamiter/Provider/Diagnosis/Diagnosis_Item/urban_disease_provider.dart';
|
|
import 'package:lamiter/Provider/Language/language_provider.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|
|
|
class UrbanDiseaseDetailsPage extends StatelessWidget {
|
|
final UrbanDisease? disease;
|
|
|
|
const UrbanDiseaseDetailsPage({
|
|
super.key,
|
|
required this.disease,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final languageProvider = Provider.of<LanguageProvider>(context);
|
|
|
|
return GestureDetector(
|
|
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
|
|
child: Scaffold(
|
|
appBar: TitleAppBar(
|
|
title: languageProvider.getLocaleString(disease?.name ?? ''),
|
|
),
|
|
body: Stack(
|
|
children: [
|
|
// _BackgroundImage(),
|
|
SafeArea(
|
|
bottom: false,
|
|
child: Container(
|
|
alignment: Alignment.center,
|
|
child: ListView(
|
|
children: [
|
|
disease != null
|
|
? _DiseaseLayout(disease: disease!)
|
|
: const SizedBox.shrink(),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _DiseaseLayout extends StatefulWidget {
|
|
final UrbanDisease disease;
|
|
const _DiseaseLayout({required this.disease});
|
|
|
|
@override
|
|
State<_DiseaseLayout> createState() => _DiseaseLayoutState();
|
|
}
|
|
|
|
class _DiseaseLayoutState extends State<_DiseaseLayout> {
|
|
String? image;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
loadImage();
|
|
});
|
|
}
|
|
|
|
Future<void> loadImage() async {
|
|
image = await context
|
|
.read<UrbanDiseaseProvider>()
|
|
.getImageWithId(context, widget.disease.id);
|
|
setState(() {});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final languageProvider = Provider.of<LanguageProvider>(context);
|
|
|
|
return Column(
|
|
children: [
|
|
Column(
|
|
children: [
|
|
_FixedInfoLayout(
|
|
infoWidget: _html2widget(
|
|
context,
|
|
languageProvider.getLocaleString(widget.disease.info),
|
|
),
|
|
),
|
|
ToggleInfoLayout(
|
|
title: AppLocalizations.of(context).body_alert,
|
|
infoWidget: _image(context, image),
|
|
fullFit: true,
|
|
),
|
|
].separator(SizedBox(height: 16.sp)).toList(),
|
|
),
|
|
Column(
|
|
children: [
|
|
ToggleInfoLayout(
|
|
title: AppLocalizations.of(context).western_tips,
|
|
infoWidget: _content(context,
|
|
languageProvider.getLocaleString(widget.disease.WMTips)),
|
|
),
|
|
ToggleInfoLayout(
|
|
title: AppLocalizations.of(context).chinese_tips,
|
|
infoWidget: _content(context,
|
|
languageProvider.getLocaleString(widget.disease.TCMTips)),
|
|
),
|
|
].separator(SizedBox(height: 16.sp)).toList(),
|
|
),
|
|
ToggleInfoLayout(
|
|
title: AppLocalizations.of(context).urban_syndrome_tips,
|
|
infoWidget: _html2widget(
|
|
context,
|
|
languageProvider.getLocaleString(widget.disease.urbanHealthTips),
|
|
),
|
|
),
|
|
]
|
|
.padding(EdgeInsets.symmetric(horizontal: 24.sp))
|
|
.separator(Divider(
|
|
indent: 32.sp,
|
|
endIndent: 32.sp,
|
|
color: context.inverseSurface.withOpacity(0.5),
|
|
height: 32.sp,
|
|
))
|
|
.firstPadding(EdgeInsets.only(top: 16.sp))
|
|
.lastPadding(EdgeInsets.only(bottom: 16.sp))
|
|
.toList(),
|
|
);
|
|
}
|
|
}
|
|
|
|
Widget _title(BuildContext context, String text) {
|
|
return Text(
|
|
text,
|
|
style: context.tM!.copyWith(fontWeight: FontWeight.bold),
|
|
);
|
|
}
|
|
|
|
Widget _content(BuildContext context, String text) {
|
|
return SelectableText(
|
|
text,
|
|
style: context.tM,
|
|
textAlign: TextAlign.justify,
|
|
);
|
|
}
|
|
|
|
Widget _image(BuildContext context, String? img64) {
|
|
return SizedBox(
|
|
width: double.infinity, // Your desired width
|
|
child: AspectRatio(
|
|
aspectRatio: 1, // Replace with your image's aspect ratio
|
|
child: img64 == null
|
|
? const SizedBox.shrink()
|
|
: Image.memory(
|
|
base64Decode(img64),
|
|
fit: BoxFit.cover, // Fit as needed
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Column _html2widget(BuildContext context, String htmlData) {
|
|
List<Widget> widgets = [];
|
|
List<Widget> temp = [];
|
|
|
|
for (String line in htmlData.split('</br>')) {
|
|
if (line.contains('<b>')) {
|
|
temp = [];
|
|
line = line.split('<b>')[1];
|
|
line = line.split('</b>')[0];
|
|
temp.add(_title(context, line));
|
|
} else {
|
|
temp.add(_content(context, line));
|
|
widgets.add(
|
|
Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: temp.separator(SizedBox(height: 6.sp)).toList(),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: widgets
|
|
.separator(
|
|
Divider(
|
|
height: 32.sp,
|
|
color: context.primary.withOpacity(0.25),
|
|
),
|
|
)
|
|
.toList(),
|
|
);
|
|
}
|
|
|
|
class _FixedInfoLayout extends StatelessWidget {
|
|
final Widget infoWidget;
|
|
|
|
const _FixedInfoLayout({required this.infoWidget});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Container(
|
|
padding: EdgeInsets.symmetric(vertical: 16.sp, horizontal: 16.sp),
|
|
decoration: BoxDecoration(
|
|
border: Border.all(color: context.inversePrimary),
|
|
),
|
|
child: infoWidget,
|
|
);
|
|
}
|
|
}
|