Fix uploaded assets getting deleted and fix new audio messages loading wrong file

This commit is contained in:
Nutcake 2023-05-28 16:38:59 +02:00
parent c368fb6fe5
commit 9ab4774f34
5 changed files with 80 additions and 37 deletions

View file

@ -141,6 +141,7 @@ class RecordApi {
filename: filename,
thumbnailUri: imageDigest.dbUri,
digests: digests,
extraTags: ["image"],
);
progressCallback?.call(.1);
final status = await tryPreprocessRecord(client, record: record);
@ -151,6 +152,7 @@ class RecordApi {
client,
assets: digests.where((digest) => toUpload.any((diff) => digest.asset.hash == diff.hash)).toList(),
progressCallback: (progress) => progressCallback?.call(.2 + progress * .6));
await upsertRecord(client, record: record);
progressCallback?.call(1);
return record;
}
@ -170,6 +172,7 @@ class RecordApi {
filename: filename,
thumbnailUri: "",
digests: digests,
extraTags: ["voice", "message"],
);
progressCallback?.call(.1);
final status = await tryPreprocessRecord(client, record: record);
@ -180,6 +183,7 @@ class RecordApi {
client,
assets: digests.where((digest) => toUpload.any((diff) => digest.asset.hash == diff.hash)).toList(),
progressCallback: (progress) => progressCallback?.call(.2 + progress * .6));
await upsertRecord(client, record: record);
progressCallback?.call(1);
return record;
}
@ -203,6 +207,7 @@ class RecordApi {
filename: fileDigest.name,
thumbnailUri: JsonTemplate.thumbUrl,
digests: digests,
extraTags: ["document"],
);
progressCallback?.call(.1);
final status = await tryPreprocessRecord(client, record: record);
@ -213,6 +218,7 @@ class RecordApi {
client,
assets: digests.where((digest) => toUpload.any((diff) => digest.asset.hash == diff.hash)).toList(),
progressCallback: (progress) => progressCallback?.call(.2 + progress * .6));
await upsertRecord(client, record: record);
progressCallback?.call(1);
return record;
}

View file

@ -111,6 +111,7 @@ class Record {
required String filename,
required String thumbnailUri,
required List<AssetDigest> digests,
List<String>? extraTags,
}) {
final combinedRecordId = RecordId(id: Record.generateId(), ownerId: userId, isValid: true);
return Record(
@ -118,11 +119,12 @@ class Record {
combinedRecordId: combinedRecordId,
assetUri: assetUri,
name: filename,
tags: [
tags: ([
filename,
"message_item",
"message_id:${Message.generateId()}"
],
"message_id:${Message.generateId()}",
"contacts-plus-plus"
] + (extraTags ?? [])).unique(),
recordType: recordType,
thumbnailUri: thumbnailUri,
isPublic: false,

View file

@ -20,20 +20,23 @@ class MessageAsset extends StatelessWidget {
@override
Widget build(BuildContext context) {
final content = jsonDecode(message.content);
PhotoAsset? photoAsset;
try {
photoAsset = PhotoAsset.fromTags((content["tags"] as List).map((e) => "$e").toList());
} catch (_) {}
final formattedName = FormatNode.fromText(content["name"]);
return Container(
constraints: const BoxConstraints(maxWidth: 300),
child: Column(
children: [
CachedNetworkImage(
SizedBox(
height: 256,
width: double.infinity,
child: CachedNetworkImage(
imageUrl: Aux.neosDbToHttp(content["thumbnailUri"]),
imageBuilder: (context, image) {
return InkWell(
onTap: () async {
PhotoAsset? photoAsset;
try {
photoAsset = PhotoAsset.fromTags((content["tags"] as List).map((e) => "$e").toList());
} catch (_) {}
await Navigator.push(
context, MaterialPageRoute(builder: (context) =>
PhotoView(
@ -47,12 +50,16 @@ class MessageAsset extends StatelessWidget {
},
child: Hero(
tag: message.id,
child: ClipRRect(borderRadius: BorderRadius.circular(16), child: Image(image: image,)),
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Image(image: image, fit: BoxFit.cover,),
),
),
);
},
errorWidget: (context, url, error) => const Icon(Icons.image_not_supported, size: 128,),
placeholder: (context, uri) => const CircularProgressIndicator(),
errorWidget: (context, url, error) => const Icon(Icons.broken_image, size: 64,),
placeholder: (context, uri) => const Center(child: CircularProgressIndicator()),
),
),
const SizedBox(height: 8,),
Row(

View file

@ -45,6 +45,14 @@ class _MessageAudioPlayerState extends State<MessageAudioPlayer> with WidgetsBin
.then((value) => _audioPlayer.setFilePath(value.path)).whenComplete(() => _audioPlayer.setLoopMode(LoopMode.off));
}
@override
void didUpdateWidget(covariant MessageAudioPlayer oldWidget) {
super.didUpdateWidget(oldWidget);
final audioCache = Provider.of<AudioCacheClient>(context);
_audioFileFuture = audioCache.cachedNetworkAudioFile(AudioClipContent.fromMap(jsonDecode(widget.message.content)))
.then((value) => _audioPlayer.setFilePath(value.path)).whenComplete(() => _audioPlayer.setLoopMode(LoopMode.off));
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);

View file

@ -47,6 +47,13 @@ class _MessageInputBarState extends State<MessageInputBar> {
set _isRecording(value) => _recordingStartTime = value ? DateTime.now() : null;
bool _recordingCancelled = false;
@override
void dispose() {
_recorder.dispose();
_messageTextController.dispose();
super.dispose();
}
Future<void> sendTextMessage(ApiClient client, MessagingClient mClient, String content) async {
if (content.isEmpty) return;
final message = Message(
@ -160,7 +167,6 @@ class _MessageInputBarState extends State<MessageInputBar> {
if (_isRecording) {
if (_recordingCancelled) {
setState(() {
_recordingCancelled = false;
_isRecording = false;
});
final recording = await _recorder.stop();
@ -319,7 +325,9 @@ class _MessageInputBarState extends State<MessageInputBar> {
),
child: switch((_attachmentPickerOpen, _isRecording)) {
(_, true) => IconButton(
onPressed: () {},
onPressed: () {
},
icon: Icon(Icons.delete, color: _recordingCancelled ? Theme.of(context).colorScheme.error : null,),
),
(false, _) => IconButton(
@ -513,13 +521,25 @@ class _MessageInputBarState extends State<MessageInputBar> {
},
icon: const Icon(Icons.send),
) : GestureDetector(
onTapUp: (_) {
_recordingCancelled = true;
},
onTapDown: widget.disabled ? null : (_) async {
HapticFeedback.vibrate();
if (!await _recorder.hasPermission()) {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text("No permission to record audio."),
));
}
return;
}
final dir = await getTemporaryDirectory();
await _recorder.start(
path: "${dir.path}/A-${const Uuid().v4()}.ogg",
encoder: AudioEncoder.opus,
samplingRate: 44100,
path: "${dir.path}/A-${const Uuid().v4()}.wav",
encoder: AudioEncoder.wav,
samplingRate: 44100
);
setState(() {
_isRecording = true;
@ -527,7 +547,7 @@ class _MessageInputBarState extends State<MessageInputBar> {
},
child: IconButton(
icon: const Icon(Icons.mic_outlined),
onPressed: () {
onPressed: _isSending ? null : () {
// Empty onPressed for that sweet sweet ripple effect
},
),