fixed exception when uploading files with no mimetype

This commit is contained in:
zoe 2022-09-29 15:55:58 +02:00
parent d4a6186a35
commit 2f32510bce
3 changed files with 98 additions and 33 deletions

View File

@ -91,11 +91,23 @@ Future<ConversationModelResult> _getConversationModels(
return ConversationModelResult([]); return ConversationModelResult([]);
} }
return ConversationModelResult(jsonDecode(result.body) String? newMaxId = result.headers["link"];
.map<ConversationModel>( final firstOpen = newMaxId?.indexOf("<");
(e) => ConversationModel.fromJson(e, identityName), final firstClose = newMaxId?.indexOf(">");
) newMaxId = newMaxId?.substring(firstOpen! + 1, firstClose);
.toList()); if (newMaxId != null) {
final maxIdUri = Uri.parse(newMaxId);
newMaxId = maxIdUri.queryParameters["max_id"];
}
return ConversationModelResult(
jsonDecode(result.body)
.map<ConversationModel>(
(e) => ConversationModel.fromJson(e, identityName),
)
.toList(),
maxIds: {identityName: newMaxId},
);
} }
Future<ConversationModelResult> getAllConversationModels( Future<ConversationModelResult> getAllConversationModels(
@ -104,19 +116,29 @@ Future<ConversationModelResult> getAllConversationModels(
global.settings!.identities.forEach((key, value) { global.settings!.identities.forEach((key, value) {
futureResults.add(_getConversationModels(key, maxIds[key])); futureResults.add(_getConversationModels(key, maxIds[key]));
}); });
List<ConversationModelResult> results = [];
List<ConversationModel> models = []; List<ConversationModel> models = [];
for (var element in futureResults) { for (var element in futureResults) {
models.addAll((await element).models); final r = await element;
results.add(r);
models.addAll(r.models);
} }
models.sort(); models.sort();
models = models.reversed.toList().sublist(0, global.settings!.batchSize); models = models.reversed.toList();
Map<String, String?> newMaxIds = {}; if (models.length > global.settings!.batchSize) {
for (var element in models) { models = models.sublist(0, global.settings!.batchSize);
if (newMaxIds[element.identity] == null) {
newMaxIds.addAll({element.identity: element.id});
} else if (element.id.compareTo(newMaxIds[element.identity]!) < 0) {
newMaxIds.addAll({element.identity: element.id});
}
} }
Map<String, String?> newMaxIds = {};
for (var element in results) {
newMaxIds.addAll(element.maxIds);
}
Set<String> appearingIdentities = {};
for (var i in models) {
appearingIdentities.add(i.identity);
}
newMaxIds.removeWhere((key, value) => (appearingIdentities.contains(value)));
print(newMaxIds);
return ConversationModelResult(models, maxIds: newMaxIds); return ConversationModelResult(models, maxIds: newMaxIds);
} }

View File

@ -449,7 +449,7 @@ class FileUploadDisplay extends StatelessWidget {
), ),
], ],
), ),
if (lookupMimeType(file.path)!.startsWith("image/")) if (lookupMimeType(file.path)?.startsWith("image/") ?? false)
Image.asset( Image.asset(
file.path, file.path,
fit: BoxFit.fitWidth, fit: BoxFit.fitWidth,

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:localization/localization.dart'; import 'package:localization/localization.dart';
import 'package:loris/business_logic/chat/chat.dart'; import 'package:loris/business_logic/chat/chat.dart';
import 'package:loris/partials/loadingbox.dart';
import 'package:loris/partials/post_text_renderer.dart'; import 'package:loris/partials/post_text_renderer.dart';
import 'package:loris/themes/themes.dart' as themes; import 'package:loris/themes/themes.dart' as themes;
import 'package:loris/global.dart' as global; import 'package:loris/global.dart' as global;
@ -16,37 +17,59 @@ class _ChatState extends State<Chat> {
List<ConversationModel> conversations = []; List<ConversationModel> conversations = [];
// map that stores max ids for each identity // map that stores max ids for each identity
Map<String, String?> maxIds = {}; Map<String, String?> maxIds = {};
final scrollController = ScrollController();
bool loading = false;
// loads more conversations and properly stores all ids
Future<void> updateConversations() async { Future<void> updateConversations() async {
if (loading) return;
loading = true;
final models = await getAllConversationModels(maxIds); final models = await getAllConversationModels(maxIds);
print(models.maxIds);
setState(() { setState(() {
conversations.addAll(models.models); conversations.addAll(models.models);
maxIds = models.maxIds; maxIds = models.maxIds;
}); });
loading = false;
} }
@override @override
void initState() { void initState() {
updateConversations(); updateConversations();
scrollController.addListener(() {
if (scrollController.position.maxScrollExtent - scrollController.offset <
MediaQuery.of(context).size.height) {
updateConversations();
}
});
super.initState(); super.initState();
} }
@override
void dispose() {
scrollController.dispose();
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(
children: [ children: [
Expanded( Expanded(
child: ListView.separated( child: ListView.separated(
controller: scrollController,
shrinkWrap: true, shrinkWrap: true,
itemBuilder: (context, index) => ConversationButton( itemBuilder: ((context, index) {
model: conversations[index], if (index >= conversations.length) return const LoadingBox();
), return ConversationButton(
model: conversations[index],
onPressed: () {},
);
}),
separatorBuilder: (context, index) => const Divider( separatorBuilder: (context, index) => const Divider(
height: themes.defaultSeperatorHeight, height: themes.defaultSeperatorHeight,
color: Colors.transparent, color: Colors.transparent,
), ),
itemCount: conversations.length), itemCount: conversations.length + 1),
), ),
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
@ -63,35 +86,55 @@ class ConversationButton extends StatelessWidget {
const ConversationButton({ const ConversationButton({
super.key, super.key,
required this.model, required this.model,
required this.onPressed,
}); });
final ConversationModel model; final ConversationModel model;
final void Function() onPressed;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: const BorderRadius.all(themes.defaultRadius), borderRadius: const BorderRadius.all(themes.defaultRadius),
color: Theme.of(context).colorScheme.surface, border: Border.fromBorderSide(BorderSide(
color: Theme.of(context).colorScheme.secondary, width: 2)),
), ),
margin: const EdgeInsets.fromLTRB(themes.defaultSeperatorHeight * 2, 0, margin: const EdgeInsets.fromLTRB(themes.defaultSeperatorHeight * 2, 0,
themes.defaultSeperatorHeight * 2, 0), themes.defaultSeperatorHeight * 2, 0),
width: global.getWidth(context), width: global.getWidth(context),
constraints: global.getConstraints(context), constraints: global.getConstraints(context),
child: Padding( child: InkWell(
padding: themes.defaultInsideMargins, borderRadius: const BorderRadius.all(themes.defaultRadius),
child: Column( onTap: onPressed,
crossAxisAlignment: CrossAxisAlignment.stretch, child: Ink(
children: [ decoration: BoxDecoration(
Wrap( borderRadius: const BorderRadius.all(themes.defaultRadius),
alignment: WrapAlignment.spaceBetween, color: Theme.of(context).colorScheme.surface,
),
child: Padding(
padding: themes.defaultInsideMargins,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
SelectableText(model.getAccountsString()), if (model.unread)
SelectableText("${"you-are".i18n()} ${model.identity}"), Row(
children: [
const Icon(Icons.mark_chat_unread),
SelectableText("unread".i18n())
],
),
Wrap(
alignment: WrapAlignment.spaceBetween,
children: [
if (model.unread) SelectableText(model.getAccountsString()),
SelectableText("${"you-are".i18n()} ${model.identity}"),
],
),
if (model.lastStatus != null)
PostTextRenderer(input: model.lastStatus!.content),
], ],
), ),
if (model.lastStatus != null) ),
PostTextRenderer(input: model.lastStatus!.content),
],
), ),
), ),
); );