feat(service): Implement automatic sticker pack downloading
This commit is contained in:
parent
f04729261b
commit
e373f5cffe
@ -250,6 +250,14 @@ files:
|
||||
implements:
|
||||
- JsonImplementation
|
||||
attributes:
|
||||
- name: StickerPackAddedEvent
|
||||
extends: BackgroundEvent
|
||||
implements:
|
||||
- JsonImplementation
|
||||
attributes:
|
||||
stickerPack:
|
||||
type: StickerPack
|
||||
deserialise: true
|
||||
generate_builder: true
|
||||
builder_name: "Event"
|
||||
builder_baseclass: "BackgroundEvent"
|
||||
|
@ -10,7 +10,9 @@ import 'package:moxxmpp/moxxmpp.dart' as moxxmpp;
|
||||
import 'package:moxxyv2/service/database/database.dart';
|
||||
import 'package:moxxyv2/service/helpers.dart';
|
||||
import 'package:moxxyv2/service/httpfiletransfer/helpers.dart';
|
||||
import 'package:moxxyv2/service/service.dart';
|
||||
import 'package:moxxyv2/service/xmpp.dart';
|
||||
import 'package:moxxyv2/shared/events.dart';
|
||||
import 'package:moxxyv2/shared/helpers.dart';
|
||||
import 'package:moxxyv2/shared/models/sticker.dart';
|
||||
import 'package:moxxyv2/shared/models/sticker_pack.dart';
|
||||
@ -106,6 +108,40 @@ class StickersService {
|
||||
|
||||
return stickerDirPath;
|
||||
}
|
||||
|
||||
Future<void> importFromPubSubWithEvent(moxxmpp.JID jid, String stickerPackId) async {
|
||||
final stickerPack = await importFromPubSub(jid, stickerPackId);
|
||||
if (stickerPack == null) return;
|
||||
|
||||
sendEvent(
|
||||
StickerPackAddedEvent(
|
||||
stickerPack: stickerPack,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Takes the jid of the host [jid] and the id [stickerPackId] of the sticker pack
|
||||
/// and tries to fetch and install it, including publishing on our own PubSub node.
|
||||
///
|
||||
/// On success, returns the installed StickerPack. On failure, returns null.
|
||||
Future<StickerPack?> importFromPubSub(moxxmpp.JID jid, String stickerPackId) async {
|
||||
final result = await GetIt.I.get<moxxmpp.XmppConnection>()
|
||||
.getManagerById<moxxmpp.StickersManager>(moxxmpp.stickersManager)!
|
||||
.fetchStickerPack(jid.toBare(), stickerPackId);
|
||||
|
||||
if (result.isType<moxxmpp.PubSubError>()) {
|
||||
_log.warning('Failed to fetch sticker pack $jid:$stickerPackId');
|
||||
return null;
|
||||
}
|
||||
|
||||
final stickerPackRaw = StickerPack.fromMoxxmpp(
|
||||
result.get<moxxmpp.StickerPack>(),
|
||||
false,
|
||||
);
|
||||
|
||||
// Install the sticker pack
|
||||
return installFromPubSub(stickerPackRaw);
|
||||
}
|
||||
|
||||
Future<StickerPack?> installFromPubSub(StickerPack remotePack) async {
|
||||
assert(!remotePack.local, 'Sticker pack must be remote');
|
||||
@ -175,33 +211,7 @@ class StickersService {
|
||||
|
||||
// Publish but don't block
|
||||
unawaited(
|
||||
_publishStickerPack(
|
||||
moxxmpp.StickerPack(
|
||||
remotePack.id,
|
||||
remotePack.name,
|
||||
remotePack.description,
|
||||
moxxmpp.hashFunctionFromName(remotePack.hashAlgorithm),
|
||||
remotePack.hashValue,
|
||||
remotePack.stickers
|
||||
.map((sticker) => moxxmpp.Sticker(
|
||||
moxxmpp.FileMetadataData(
|
||||
mediaType: sticker.mediaType,
|
||||
desc: sticker.desc,
|
||||
size: sticker.size,
|
||||
width: sticker.width,
|
||||
height: sticker.height,
|
||||
thumbnails: [],
|
||||
hashes: sticker.hashes,
|
||||
),
|
||||
sticker.urlSources
|
||||
// ignore: unnecessary_lambdas
|
||||
.map((src) => moxxmpp.StatelessFileSharingUrlSource(src))
|
||||
.toList(),
|
||||
sticker.suggests,
|
||||
),).toList(),
|
||||
remotePack.restricted,
|
||||
),
|
||||
),
|
||||
_publishStickerPack(remotePack.toMoxxmpp()),
|
||||
);
|
||||
|
||||
return remotePack.copyWith(
|
||||
|
@ -28,6 +28,7 @@ import 'package:moxxyv2/service/preferences.dart';
|
||||
import 'package:moxxyv2/service/roster.dart';
|
||||
import 'package:moxxyv2/service/service.dart';
|
||||
import 'package:moxxyv2/service/state.dart';
|
||||
import 'package:moxxyv2/service/stickers.dart';
|
||||
import 'package:moxxyv2/shared/error_types.dart';
|
||||
import 'package:moxxyv2/shared/eventhandler.dart';
|
||||
import 'package:moxxyv2/shared/events.dart';
|
||||
@ -1170,7 +1171,30 @@ class XmppService {
|
||||
final stickerHashKey = event.stickerPackId != null ?
|
||||
getStickerHashKey(event.sfs!.metadata.hashes) :
|
||||
null;
|
||||
|
||||
// The potential sticker pack
|
||||
final stickerPack = event.stickerPackId != null ?
|
||||
await GetIt.I.get<StickersService>().getStickerPackById(
|
||||
event.stickerPackId!,
|
||||
) :
|
||||
null;
|
||||
|
||||
// Automatically download the sticker pack, if
|
||||
// - a sticker was received,
|
||||
// - the sender is in the roster,
|
||||
// - we don't have the sticker pack locally,
|
||||
// - and it is enabled in the settings
|
||||
if (event.stickerPackId != null &&
|
||||
stickerPack == null &&
|
||||
prefs.autoDownloadStickersFromContacts &&
|
||||
isInRoster) {
|
||||
unawaited(
|
||||
GetIt.I.get<StickersService>().importFromPubSubWithEvent(
|
||||
event.fromJid,
|
||||
event.stickerPackId!,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Create the message in the database
|
||||
final ms = GetIt.I.get<MessageService>();
|
||||
final dimensions = _getDimensions(event);
|
||||
|
@ -1,5 +1,7 @@
|
||||
import 'dart:convert';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:moxxmpp/moxxmpp.dart' as moxxmpp;
|
||||
import 'package:moxxyv2/service/helpers.dart';
|
||||
|
||||
part 'sticker.freezed.dart';
|
||||
part 'sticker.g.dart';
|
||||
@ -22,6 +24,24 @@ class Sticker with _$Sticker {
|
||||
) = _Sticker;
|
||||
|
||||
const Sticker._();
|
||||
|
||||
/// Moxxmpp
|
||||
factory Sticker.fromMoxxmpp(moxxmpp.Sticker sticker, String stickerPackId) => Sticker(
|
||||
getStickerHashKey(sticker.metadata.hashes),
|
||||
sticker.metadata.mediaType!,
|
||||
sticker.metadata.desc!,
|
||||
sticker.metadata.size!,
|
||||
sticker.metadata.width,
|
||||
sticker.metadata.height,
|
||||
sticker.metadata.hashes,
|
||||
sticker.sources
|
||||
.whereType<moxxmpp.StatelessFileSharingUrlSource>()
|
||||
.map((src) => src.url)
|
||||
.toList(),
|
||||
'',
|
||||
stickerPackId,
|
||||
sticker.suggests,
|
||||
);
|
||||
|
||||
/// JSON
|
||||
factory Sticker.fromJson(Map<String, dynamic> json) => _$StickerFromJson(json);
|
||||
@ -48,4 +68,21 @@ class Sticker with _$Sticker {
|
||||
'suggests': jsonEncode(suggests),
|
||||
};
|
||||
}
|
||||
|
||||
moxxmpp.Sticker toMoxxmpp() => moxxmpp.Sticker(
|
||||
moxxmpp.FileMetadataData(
|
||||
mediaType: mediaType,
|
||||
desc: desc,
|
||||
size: size,
|
||||
width: width,
|
||||
height: height,
|
||||
thumbnails: [],
|
||||
hashes: hashes,
|
||||
),
|
||||
urlSources
|
||||
// ignore: unnecessary_lambdas
|
||||
.map((src) => moxxmpp.StatelessFileSharingUrlSource(src))
|
||||
.toList(),
|
||||
suggests,
|
||||
);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:moxxmpp/moxxmpp.dart' as moxxmpp;
|
||||
import 'package:moxxyv2/service/database/helpers.dart';
|
||||
import 'package:moxxyv2/shared/models/sticker.dart';
|
||||
|
||||
@ -19,6 +20,20 @@ class StickerPack with _$StickerPack {
|
||||
) = _StickerPack;
|
||||
|
||||
const StickerPack._();
|
||||
|
||||
/// Moxxmpp
|
||||
factory StickerPack.fromMoxxmpp(moxxmpp.StickerPack pack, bool local) => StickerPack(
|
||||
pack.id,
|
||||
pack.name,
|
||||
pack.summary,
|
||||
pack.stickers
|
||||
.map((sticker) => Sticker.fromMoxxmpp(sticker, pack.id))
|
||||
.toList(),
|
||||
pack.hashAlgorithm.toName(),
|
||||
pack.hashValue,
|
||||
pack.restricted,
|
||||
local,
|
||||
);
|
||||
|
||||
/// JSON
|
||||
factory StickerPack.fromJson(Map<String, dynamic> json) => _$StickerPackFromJson(json);
|
||||
@ -43,5 +58,17 @@ class StickerPack with _$StickerPack {
|
||||
...json,
|
||||
'restricted': boolToInt(restricted),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
moxxmpp.StickerPack toMoxxmpp() => moxxmpp.StickerPack(
|
||||
id,
|
||||
name,
|
||||
description,
|
||||
moxxmpp.hashFunctionFromName(hashAlgorithm),
|
||||
hashValue,
|
||||
stickers
|
||||
.map((sticker) => sticker.toMoxxmpp())
|
||||
.toList(),
|
||||
restricted,
|
||||
);
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import 'package:moxxyv2/ui/bloc/conversations_bloc.dart' as conversations;
|
||||
import 'package:moxxyv2/ui/bloc/newconversation_bloc.dart' as new_conversation;
|
||||
import 'package:moxxyv2/ui/bloc/profile_bloc.dart' as profile;
|
||||
import 'package:moxxyv2/ui/bloc/sharedmedia_bloc.dart' as sharedmedia;
|
||||
import 'package:moxxyv2/ui/bloc/stickers_bloc.dart' as stickers;
|
||||
import 'package:moxxyv2/ui/prestart.dart';
|
||||
import 'package:moxxyv2/ui/service/progress.dart';
|
||||
|
||||
@ -32,6 +33,7 @@ void setupEventHandler() {
|
||||
EventTypeMatcher<PreStartDoneEvent>(preStartDone),
|
||||
EventTypeMatcher<ServiceReadyEvent>(onServiceReady),
|
||||
EventTypeMatcher<MessageNotificationTappedEvent>(onNotificationTappend),
|
||||
EventTypeMatcher<StickerPackAddedEvent>(onStickerPackAdded),
|
||||
]);
|
||||
|
||||
GetIt.I.registerSingleton<EventHandler>(handler);
|
||||
@ -159,3 +161,9 @@ Future<void> onNotificationTappend(MessageNotificationTappedEvent event, { dynam
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> onStickerPackAdded(StickerPackAddedEvent event, { dynamic extra }) async {
|
||||
GetIt.I.get<stickers.StickersBloc>().add(
|
||||
stickers.StickerPackAddedEvent(event.stickerPack),
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user