add collapsing threads

This commit is contained in:
zoe 2022-09-30 17:45:07 +02:00
parent 51c3cf8b04
commit ee226713ae
6 changed files with 63 additions and 205 deletions

View File

@ -139,6 +139,5 @@ Future<ConversationModelResult> getAllConversationModels(
}
newMaxIds.removeWhere((key, value) => (appearingIdentities.contains(value)));
print(newMaxIds);
return ConversationModelResult(models, maxIds: newMaxIds);
}

View File

@ -26,7 +26,6 @@ Future<MapEntry<int, PostContext?>> getContextForPost(PostModel model) async {
if (r.statusCode != 200) {
return MapEntry(r.statusCode, null);
}
print(r.body);
final json = jsonDecode(r.body);
List<dynamic> ancestors = json["ancestors"]!;

View File

@ -1,163 +0,0 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:loris/business_logic/chat/chat.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 'package:loris/partials/post.dart';
import 'package:loris/partials/post_text_renderer.dart';
import 'package:loris/themes/themes.dart' as themes;
class Chatwindow extends StatefulWidget {
const Chatwindow({super.key, required this.model});
final ConversationModel model;
@override
State<Chatwindow> createState() => _ChatwindowState();
}
class _ChatwindowState extends State<Chatwindow> {
List<PostModel> models = [];
Future<void> loadContext(PostModel m) async {
final c = await getContextForPost(m);
if (c.key == 200 && mounted) {
setState(() {
print(c.value!.ancestors);
models = c.value!.ancestors +
[widget.model.lastStatus!] +
c.value!.descendants;
});
print(models);
}
}
@override
void initState() {
if (widget.model.lastStatus != null) loadContext(widget.model.lastStatus!);
super.initState();
}
@override
Widget build(BuildContext context) {
return BackdropFilter(
filter:
ImageFilter.blur(sigmaX: 10, sigmaY: 10, tileMode: TileMode.mirror),
child: SimpleDialog(
contentPadding: const EdgeInsets.all(0),
backgroundColor: Theme.of(context).colorScheme.surface,
children: [
Container(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.background,
borderRadius: const BorderRadius.all(themes.defaultRadius)),
width: global.getWidth(context),
constraints: global.getConstraints(context),
height: MediaQuery.of(context).size.height * 2 / 3,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Flexible(
child: ListView.separated(
shrinkWrap: true,
itemBuilder: (context, index) =>
DirectMessage(model: models[index]),
separatorBuilder: (context, index) => const Divider(
color: Colors.transparent,
height: themes.defaultSeperatorHeight,
),
itemCount: models.length),
),
Container(
padding: themes.defaultInsideMargins,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: const BorderRadius.only(
bottomLeft: themes.defaultRadius,
bottomRight: themes.defaultRadius,
topLeft: Radius.circular(0),
topRight: Radius.circular(0)),
border: Border.fromBorderSide(BorderSide(
color: Theme.of(context).colorScheme.secondary,
width: 2,
)),
),
child: TextField(
minLines: 1,
maxLines: 4,
style: Theme.of(context).textTheme.bodyMedium,
expands: false,
decoration: InputDecoration(
suffix: Wrap(
direction: Axis.horizontal,
alignment: WrapAlignment.center,
crossAxisAlignment: WrapCrossAlignment.center,
children: [
IconButton(
onPressed: () {},
icon: const Icon(Icons.attach_file)),
IconButton(
onPressed: () {},
icon: const Icon(Icons.send),
),
],
),
),
),
),
],
),
)
],
));
}
}
class DirectMessage extends StatefulWidget {
const DirectMessage({super.key, required this.model});
final PostModel model;
@override
State<DirectMessage> createState() => _DirectMessageState();
}
class _DirectMessageState extends State<DirectMessage> {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: themes.defaultSeperatorHeight * 2),
child: Align(
alignment: (widget.model.identity ==
"${widget.model.account.acct}@${global.settings!.identities[widget.model.identity]!.instanceUrl}")
? Alignment.centerRight
: Alignment.centerLeft,
child: LayoutBuilder(builder: ((ctx, constraints) {
return Container(
constraints: BoxConstraints(
maxWidth: constraints.maxWidth * 0.96 +
themes.defaultSeperatorHeight * 2,
),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
border: Border.all(
color: Theme.of(context).colorScheme.secondary,
width: 2,
),
borderRadius: const BorderRadius.all(themes.defaultRadius)),
padding: themes.defaultInsideMargins,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
DisplayName(account: widget.model.account),
PostTextRenderer(input: widget.model.content),
],
),
);
})),
),
);
}
}

View File

@ -84,6 +84,9 @@
"file-description": "file description",
"loading...": "loading",
"failed-to-send": "failed to send!",
"sending-file": "sending file"
"sending-file": "sending file",
"open-media-in-browser": "open media in browser",
"unread": "unread",
"expand": "expand"
}

View File

@ -1,7 +1,8 @@
import 'package:flutter/material.dart';
import 'package:localization/localization.dart';
import 'package:loris/business_logic/chat/chat.dart';
import 'package:loris/dialogues/chatwindow.dart';
import 'package:loris/dialogues/full_post_view.dart';
import 'package:loris/dialogues/profile_view.dart';
import 'package:loris/partials/loadingbox.dart';
import 'package:loris/partials/post.dart';
import 'package:loris/partials/post_text_renderer.dart';
@ -66,12 +67,16 @@ class _ChatState extends State<Chat> {
model: conversations[index],
onTap: () {
showDialog(
barrierColor: Colors.transparent,
context: context,
builder: (context) => Chatwindow(
model: conversations[index],
),
);
barrierColor: Colors.transparent,
context: context,
builder: (context) {
final con = conversations[index];
if (con.lastStatus != null) {
return FullPostView(
originPostModel: con.lastStatus!);
}
return ProfileView(model: con.accounts.first);
});
},
);
}),
@ -103,7 +108,7 @@ class ConversationButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
final List<DisplayName> people = [];
final List<Widget> people = [];
for (var p in model.accounts) {
people.add(DisplayName(account: p));
}
@ -131,7 +136,11 @@ class ConversationButton extends StatelessWidget {
padding: themes.defaultInsideMargins,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
children: people +
[
Divider(
color: Theme.of(context).hintColor,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@ -152,15 +161,7 @@ class ConversationButton extends StatelessWidget {
),
if (model.lastStatus != null)
PostTextRenderer(input: model.lastStatus!.content),
Divider(
color: Theme.of(context).hintColor,
),
SelectableText(
"conversation-participants".i18n(),
style: Theme.of(context).textTheme.displaySmall,
),
] +
people,
],
),
),
),

View File

@ -22,14 +22,30 @@ class _ThreadState extends State<Thread> {
Set<String> contentWarnings = {};
int sensitivePosts = 0;
bool showSensitive = false;
bool collapsed = false;
@override
Widget build(BuildContext context) {
List<Widget> c = [];
List<Widget> c = [
Align(
alignment: Alignment.centerRight,
child: TextButton.icon(
onPressed: () {
setState(() {
collapsed = !collapsed;
});
},
icon: Icon(collapsed ? Icons.fullscreen : Icons.fullscreen_exit),
label: Text(collapsed ? "expand".i18n() : "collapse".i18n())),
)
];
for (var element in widget.model.posts) {
c.add(Post(
model: element,
hideSensitive: !showSensitive,
c.add(Visibility(
visible: !collapsed,
child: Post(
model: element,
hideSensitive: !showSensitive,
),
));
if (element.sensitive) {
sensitivePosts += 1;
@ -55,25 +71,27 @@ class _ThreadState extends State<Thread> {
}
i++;
}
c.insert(
0,
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(
child: SelectableText(s),
),
ElevatedButton.icon(
onPressed: () {
setState(() {
showSensitive = !showSensitive;
});
},
icon:
Icon(showSensitive ? Icons.visibility_off : Icons.visibility),
label: Text(showSensitive ? "hide".i18n() : "show".i18n()),
),
],
Visibility(
visible: !collapsed,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(child: SelectableText(s)),
ElevatedButton.icon(
onPressed: () {
setState(() {
showSensitive = !showSensitive;
});
},
icon: Icon(
showSensitive ? Icons.visibility_off : Icons.visibility),
label: Text(showSensitive ? "hide".i18n() : "show".i18n()),
),
],
),
),
);
}
@ -114,6 +132,7 @@ class _ThreadState extends State<Thread> {
child: Padding(
padding: themes.defaultInsideMargins,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: c,
),
),