268 lines
8.5 KiB
Dart
268 lines
8.5 KiB
Dart
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,
|
|
this.hidden = true,
|
|
this.ancestors,
|
|
this.descendants,
|
|
this.forceSensitive = false,
|
|
});
|
|
final PostModel originPostModel;
|
|
final Map<String, PostModel>? identities;
|
|
final bool hidden;
|
|
final List<PostModel>? ancestors;
|
|
final List<PostModel>? descendants;
|
|
final bool forceSensitive;
|
|
|
|
@override
|
|
State<FullPostView> createState() => _FullPostViewState();
|
|
}
|
|
|
|
class _FullPostViewState extends State<FullPostView> {
|
|
List<PostModel> ancestors = [];
|
|
List<PostModel> descendants = [];
|
|
Map<String, PostModel> identities = {};
|
|
String activeIdentity = "";
|
|
int idsChecked = 1;
|
|
bool sensitive = false;
|
|
|
|
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 {
|
|
if (widget.ancestors == null || widget.descendants == null) {
|
|
final r = await getContextForPost(widget.originPostModel);
|
|
if (r.value != null && mounted) {
|
|
setState(() {
|
|
ancestors = r.value!.ancestors;
|
|
descendants = r.value!.descendants;
|
|
});
|
|
}
|
|
for (var a in ancestors) {
|
|
if (a.sensitive) {
|
|
sensitive = true;
|
|
}
|
|
}
|
|
for (var d in descendants) {
|
|
if (d.sensitive) {
|
|
sensitive = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@override
|
|
void initState() {
|
|
if (widget.ancestors != null) {
|
|
ancestors = widget.ancestors!;
|
|
}
|
|
if (widget.descendants != null) {
|
|
descendants = widget.descendants!;
|
|
}
|
|
|
|
sensitive = widget.originPostModel.sensitive;
|
|
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<DropdownMenuItem<String>> dropdownButtons = [];
|
|
identities.forEach((key, value) {
|
|
dropdownButtons.add(
|
|
DropdownMenuItem(
|
|
alignment: Alignment.center,
|
|
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(
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: [
|
|
SelectableText(
|
|
"${"post-found-on".i18n()} $idsChecked ${idsChecked == 1 ? "instance".i18n() : "instances".i18n()}",
|
|
textAlign: TextAlign.center,
|
|
),
|
|
const LinearProgressIndicator(),
|
|
],
|
|
)
|
|
: Padding(
|
|
padding: const EdgeInsets.fromLTRB(8, 0, 8, 0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: [
|
|
DropdownButtonHideUnderline(
|
|
child: DropdownButton<String>(
|
|
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();
|
|
},
|
|
),
|
|
),
|
|
if (sensitive || widget.forceSensitive)
|
|
ElevatedButton.icon(
|
|
onPressed: () {
|
|
setState(() {
|
|
Navigator.of(context).pop();
|
|
showDialog(
|
|
context: context,
|
|
builder: (context) => FullPostView(
|
|
originPostModel: widget.originPostModel,
|
|
hidden: !widget.hidden,
|
|
identities: identities,
|
|
ancestors: ancestors,
|
|
descendants: descendants,
|
|
forceSensitive: true,
|
|
),
|
|
);
|
|
});
|
|
},
|
|
icon: Icon(widget.hidden
|
|
? Icons.visibility
|
|
: Icons.visibility_off),
|
|
label: Text(
|
|
widget.hidden ? "show".i18n() : "hide".i18n(),
|
|
))
|
|
]),
|
|
),
|
|
Container(
|
|
constraints: BoxConstraints(
|
|
maxHeight: MediaQuery.of(context).size.height * 2 / 3,
|
|
maxWidth: global.getConstraints(context).maxWidth),
|
|
width: global.getWidth(context),
|
|
child: SingleChildScrollView(
|
|
child: SingleFullPostDisplay(
|
|
ancestors: ancestors,
|
|
descendants: descendants,
|
|
hidden: widget.hidden,
|
|
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,
|
|
this.hidden = true,
|
|
});
|
|
final int level;
|
|
final PostModel model;
|
|
final List<PostModel> ancestors;
|
|
final List<PostModel> descendants;
|
|
final bool hidden;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
List<Post> ancestorWidgets = ancestors
|
|
.map(
|
|
(e) => Post(model: e, hideSensitive: hidden),
|
|
)
|
|
.toList();
|
|
|
|
List<Widget> 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,
|
|
hidden: hidden,
|
|
));
|
|
}
|
|
}
|
|
|
|
List<Widget> c = [];
|
|
c.addAll(ancestorWidgets);
|
|
c.add(Post(
|
|
model: model,
|
|
hideSensitive: hidden,
|
|
));
|
|
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));
|
|
}
|
|
}
|