import 'package:flutter/material.dart'; import 'package:localization/localization.dart'; import 'package:loris/business_logic/network_tools/get_post_from_url.dart'; import 'package:loris/business_logic/posts/posts.dart'; import 'package:loris/business_logic/timeline/timeline.dart'; import 'package:loris/global.dart' as global; import '../partials/post.dart'; class FullPostView extends StatefulWidget { const FullPostView({ super.key, required this.originPostModel, this.identities, }); final PostModel originPostModel; final Map? identities; @override State createState() => _FullPostViewState(); } class _FullPostViewState extends State { List ancestors = []; List descendants = []; Map identities = {}; String activeIdentity = ""; int idsChecked = 1; void loadIdentities() async { global.settings!.identities.forEach((key, value) async { if (!identities.containsKey(key)) { final r = await getPostFromUrl(key, widget.originPostModel.uri); if (r.values.first != null && mounted) { setState(() { identities.addAll({key: r.values.first!}); }); } if (mounted) { setState(() { idsChecked++; }); } } }); } void loadPosts() async { final r = await getContextForPost(widget.originPostModel); if (r.value != null && mounted) { setState(() { ancestors = r.value!.ancestors; descendants = r.value!.descendants; }); } } @override void initState() { if (widget.identities != null) { idsChecked = global.settings!.identities.length; } identities = widget.identities ?? {}; identities.addAll({ widget.originPostModel.identity: widget.originPostModel, }); activeIdentity = widget.originPostModel.identity; loadPosts(); loadIdentities(); super.initState(); } @override Widget build(BuildContext context) { List> dropdownButtons = []; identities.forEach((key, value) { dropdownButtons.add( DropdownMenuItem( value: key, child: Text(key, style: Theme.of(context).textTheme.bodyMedium), ), ); }); return SimpleDialog( contentPadding: const EdgeInsets.fromLTRB(0, 24, 0, 0), children: [ global.settings!.identities.length > idsChecked ? Column( children: [ SelectableText( "${"post-found-on".i18n()} $idsChecked ${idsChecked == 1 ? "instance".i18n() : "instances".i18n()}"), const LinearProgressIndicator(), ], ) : Row(mainAxisAlignment: MainAxisAlignment.center, children: [ DropdownButtonHideUnderline( child: DropdownButton( alignment: Alignment.center, value: activeIdentity, style: Theme.of(context).textTheme.bodyMedium, iconEnabledColor: Theme.of(context).colorScheme.onSurface, items: dropdownButtons, onChanged: (value) { setState(() { Navigator.of(context).pop(); showDialog( context: context, builder: (context) => FullPostView( originPostModel: identities[value]!, identities: identities, ), ); }); loadPosts(); }, ), ), ]), Container( height: MediaQuery.of(context).size.height * 2 / 3, constraints: global.getConstraints(context), width: global.getWidth(context), child: SingleChildScrollView( child: SingleFullPostDisplay( ancestors: ancestors, descendants: descendants, level: 0, model: identities[activeIdentity]!.reblog ?? identities[activeIdentity]!, ), ), ) ], ); } } class SingleFullPostDisplay extends StatelessWidget { const SingleFullPostDisplay({ super.key, required this.level, required this.model, required this.ancestors, required this.descendants, }); final int level; final PostModel model; final List ancestors; final List descendants; @override Widget build(BuildContext context) { List ancestorWidgets = ancestors .map( (e) => Post(model: e), ) .toList(); List descendantsWidgets = []; // seems most efficient // considering that lists aren't v long for (var element in descendants) { if (element.inReplyTo == model.id) { descendantsWidgets.add(SingleFullPostDisplay( level: level + 1, model: element, ancestors: const [], descendants: descendants, )); } } List c = []; c.addAll(ancestorWidgets); c.add(Post(model: model)); c.addAll(descendantsWidgets); return Container( padding: EdgeInsets.fromLTRB(level == 0 ? 4 : 4, 0, level == 0 ? 4 : 0, 0), decoration: BoxDecoration( border: level == 0 ? const Border() : Border( left: BorderSide( width: 4, color: level.isEven ? Theme.of(context).colorScheme.secondary : Theme.of(context).colorScheme.primary, ), ), ), child: Column(children: c)); } }