fixed exception when uploading files with no mimetype
This commit is contained in:
parent
d4a6186a35
commit
2f32510bce
|
@ -91,11 +91,23 @@ Future<ConversationModelResult> _getConversationModels(
|
|||
return ConversationModelResult([]);
|
||||
}
|
||||
|
||||
return ConversationModelResult(jsonDecode(result.body)
|
||||
.map<ConversationModel>(
|
||||
(e) => ConversationModel.fromJson(e, identityName),
|
||||
)
|
||||
.toList());
|
||||
String? newMaxId = result.headers["link"];
|
||||
final firstOpen = newMaxId?.indexOf("<");
|
||||
final firstClose = newMaxId?.indexOf(">");
|
||||
newMaxId = newMaxId?.substring(firstOpen! + 1, firstClose);
|
||||
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(
|
||||
|
@ -104,19 +116,29 @@ Future<ConversationModelResult> getAllConversationModels(
|
|||
global.settings!.identities.forEach((key, value) {
|
||||
futureResults.add(_getConversationModels(key, maxIds[key]));
|
||||
});
|
||||
List<ConversationModelResult> results = [];
|
||||
List<ConversationModel> models = [];
|
||||
for (var element in futureResults) {
|
||||
models.addAll((await element).models);
|
||||
final r = await element;
|
||||
results.add(r);
|
||||
models.addAll(r.models);
|
||||
}
|
||||
models.sort();
|
||||
models = models.reversed.toList().sublist(0, global.settings!.batchSize);
|
||||
Map<String, String?> newMaxIds = {};
|
||||
for (var element in models) {
|
||||
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});
|
||||
}
|
||||
models = models.reversed.toList();
|
||||
if (models.length > global.settings!.batchSize) {
|
||||
models = models.sublist(0, global.settings!.batchSize);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -449,7 +449,7 @@ class FileUploadDisplay extends StatelessWidget {
|
|||
),
|
||||
],
|
||||
),
|
||||
if (lookupMimeType(file.path)!.startsWith("image/"))
|
||||
if (lookupMimeType(file.path)?.startsWith("image/") ?? false)
|
||||
Image.asset(
|
||||
file.path,
|
||||
fit: BoxFit.fitWidth,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:localization/localization.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/themes/themes.dart' as themes;
|
||||
import 'package:loris/global.dart' as global;
|
||||
|
@ -16,37 +17,59 @@ class _ChatState extends State<Chat> {
|
|||
List<ConversationModel> conversations = [];
|
||||
// map that stores max ids for each identity
|
||||
Map<String, String?> maxIds = {};
|
||||
final scrollController = ScrollController();
|
||||
bool loading = false;
|
||||
|
||||
// loads more conversations and properly stores all ids
|
||||
Future<void> updateConversations() async {
|
||||
if (loading) return;
|
||||
loading = true;
|
||||
final models = await getAllConversationModels(maxIds);
|
||||
print(models.maxIds);
|
||||
setState(() {
|
||||
conversations.addAll(models.models);
|
||||
maxIds = models.maxIds;
|
||||
});
|
||||
loading = false;
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
updateConversations();
|
||||
scrollController.addListener(() {
|
||||
if (scrollController.position.maxScrollExtent - scrollController.offset <
|
||||
MediaQuery.of(context).size.height) {
|
||||
updateConversations();
|
||||
}
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ListView.separated(
|
||||
controller: scrollController,
|
||||
shrinkWrap: true,
|
||||
itemBuilder: (context, index) => ConversationButton(
|
||||
model: conversations[index],
|
||||
),
|
||||
itemBuilder: ((context, index) {
|
||||
if (index >= conversations.length) return const LoadingBox();
|
||||
return ConversationButton(
|
||||
model: conversations[index],
|
||||
onPressed: () {},
|
||||
);
|
||||
}),
|
||||
separatorBuilder: (context, index) => const Divider(
|
||||
height: themes.defaultSeperatorHeight,
|
||||
color: Colors.transparent,
|
||||
),
|
||||
itemCount: conversations.length),
|
||||
itemCount: conversations.length + 1),
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
|
@ -63,35 +86,55 @@ class ConversationButton extends StatelessWidget {
|
|||
const ConversationButton({
|
||||
super.key,
|
||||
required this.model,
|
||||
required this.onPressed,
|
||||
});
|
||||
final ConversationModel model;
|
||||
final void Function() onPressed;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
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,
|
||||
themes.defaultSeperatorHeight * 2, 0),
|
||||
width: global.getWidth(context),
|
||||
constraints: global.getConstraints(context),
|
||||
child: Padding(
|
||||
padding: themes.defaultInsideMargins,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Wrap(
|
||||
alignment: WrapAlignment.spaceBetween,
|
||||
child: InkWell(
|
||||
borderRadius: const BorderRadius.all(themes.defaultRadius),
|
||||
onTap: onPressed,
|
||||
child: Ink(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.all(themes.defaultRadius),
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
),
|
||||
child: Padding(
|
||||
padding: themes.defaultInsideMargins,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
SelectableText(model.getAccountsString()),
|
||||
SelectableText("${"you-are".i18n()} ${model.identity}"),
|
||||
if (model.unread)
|
||||
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),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue