diff --git a/lib/dialogues/makepost.dart b/lib/dialogues/makepost.dart index 779d9eb..28792c9 100644 --- a/lib/dialogues/makepost.dart +++ b/lib/dialogues/makepost.dart @@ -1,43 +1,26 @@ import 'package:flutter/material.dart'; +import 'package:localization/localization.dart'; +import 'package:loris/business_logic/timeline/timeline.dart'; import '../business_logic/posting/posting.dart' as logic; -class MakePost extends StatelessWidget { - const MakePost({Key? key}) : super(key: key); +class MakePost extends StatefulWidget { + const MakePost({Key? key, this.inReplyTo}) : super(key: key); + final PostModel? inReplyTo; + @override + State createState() => _MakePostState(); +} + +class _MakePostState extends State { @override Widget build(BuildContext context) { return SimpleDialog( - backgroundColor: Theme.of(context).colorScheme.background, - elevation: 0, - contentPadding: const EdgeInsets.all(24), - insetPadding: const EdgeInsets.all(24), - children: [ - TextFormField( - autofocus: true, - keyboardType: TextInputType.multiline, - minLines: 4, - maxLines: null, - ), - const MakePostActionBar(), - ], - ); - } -} - -class MakePostActionBar extends StatelessWidget { - const MakePostActionBar({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Row( - children: [ - IconButton( - onPressed: () { - Navigator.of(context).pop(); - }, - icon: const Icon(Icons.cancel), - ), - ], + alignment: Alignment.center, + title: SelectableText( + textAlign: TextAlign.center, + widget.inReplyTo == null ? "make-post".i18n() : "make-reply".i18n(), + style: Theme.of(context).textTheme.displayMedium), + children: [], ); } } diff --git a/lib/i18n/en.json b/lib/i18n/en.json index 0675867..757859f 100644 --- a/lib/i18n/en.json +++ b/lib/i18n/en.json @@ -47,6 +47,8 @@ "unlisted-visibility": "unlisted", "public-visibility": "public", "private-visibility": "private", - "direct-visibility": "dm" + "direct-visibility": "dm", + "make-reply": "make reply", + "make-post": "make post" } \ No newline at end of file diff --git a/lib/partials/interaction_button.dart b/lib/partials/interaction_button.dart index 94ca219..6671d4f 100644 --- a/lib/partials/interaction_button.dart +++ b/lib/partials/interaction_button.dart @@ -184,11 +184,16 @@ class _InteractionButtonState extends State { await showModalBottomSheet( context: context, builder: ((context) { + SizedBox box = const SizedBox( + height: 24, + ); List c = [ + box, SelectableText( widget.type.name, style: Theme.of(context).textTheme.displayLarge, - ) + ), + box ]; idList.forEach( (key, value) { @@ -231,6 +236,7 @@ class _InteractionButtonState extends State { } }, ); + c.add(box); return SingleChildScrollView( child: Column( mainAxisAlignment: MainAxisAlignment.center, diff --git a/lib/partials/media_attachment.dart b/lib/partials/media_attachment.dart index 53097eb..0eaaf65 100644 --- a/lib/partials/media_attachment.dart +++ b/lib/partials/media_attachment.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:localization/localization.dart'; import 'package:loris/business_logic/timeline/media.dart'; +import 'package:url_launcher/url_launcher_string.dart'; class MediaAttachments extends StatelessWidget { const MediaAttachments({required this.models, Key? key}) : super(key: key); @@ -12,7 +13,12 @@ class MediaAttachments extends StatelessWidget { if (models[i].type == "image" || models[i].type == "gif") { children.add(ImageAttachmentDisplay(model: models[i])); } else { - children.add(Text("media-not-supported".i18n())); + children.add(TextButton.icon( + onPressed: () { + launchUrlString(models[i].url); + }, + icon: const Icon(Icons.open_in_browser), + label: Text("open-media-in-browser".i18n()))); } } diff --git a/lib/partials/post.dart b/lib/partials/post.dart index ceb1e17..1f0e1e9 100644 --- a/lib/partials/post.dart +++ b/lib/partials/post.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:localization/localization.dart'; import 'package:loris/business_logic/account/account.dart'; import 'package:loris/business_logic/timeline/media.dart'; +import 'package:loris/dialogues/makepost.dart'; import 'package:loris/partials/interaction_button.dart'; import 'package:loris/partials/media_attachment.dart'; import 'package:loris/partials/post_options.dart'; @@ -268,8 +269,19 @@ class _PostActionBarState extends State { mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Expanded( - flex: 20, - child: IconButton(onPressed: () {}, icon: const Icon(Icons.reply))), + flex: 20, + child: IconButton( + onPressed: () { + showDialog( + context: context, + builder: ((context) => MakePost( + inReplyTo: widget.model, + ))); + }, + icon: const Icon(Icons.reply), + tooltip: "reply".i18n(), + ), + ), Expanded( flex: 20, child: InteractionButton( @@ -287,6 +299,7 @@ class _PostActionBarState extends State { Expanded( flex: 20, child: IconButton( + tooltip: "post-options".i18n(), onPressed: () { popupPostOptions(context, widget.model); }, diff --git a/lib/partials/thread.dart b/lib/partials/thread.dart index ef2822c..0f49542 100644 --- a/lib/partials/thread.dart +++ b/lib/partials/thread.dart @@ -13,7 +13,8 @@ class Thread extends StatefulWidget { } class _ThreadState extends State { - bool anySensitivePosts = false; + Set contentWarnings = {}; + int sensitivePosts = 0; bool showSensitive = false; @override @@ -25,16 +26,32 @@ class _ThreadState extends State { hideSensitive: !showSensitive, )); if (element.sensitive) { - anySensitivePosts = true; + sensitivePosts += 1; + contentWarnings.add(element.spoilerText); } } - if (anySensitivePosts && c.length > 1) { + if (sensitivePosts > 1 && c.length > 1) { + String s = ""; + int i = 0; + for (var element in contentWarnings) { + if (i == 0) { + s = "$element;"; + } else if (i < contentWarnings.length - 1) { + s = "$s $element;"; + } else { + s = "$s $element"; + } + i++; + } c.insert( 0, Row( mainAxisAlignment: MainAxisAlignment.end, children: [ + Expanded( + child: SelectableText(s), + ), OutlinedButton.icon( onPressed: () { setState(() {