1
import 'package:vkdart/util.dart';
2
import 'package:vkdart/vkdart.dart' show VkDartException;
3
import 'package:vkdart/vkontakte.dart';
5
/// Base class Attachment
7
/// See https://dev.vk.com/ru/docs/attachments
8
abstract class AttachmentModel {
10
final Map<String, dynamic> payload;
13
final String attachType;
15
// ignore: public_member_api_docs
16
AttachmentModel(this.payload, {required this.attachType});
18
/// Transforms the attachment object into a specific model, depending on its type.
19
/// There may be exceptions [VkDartException] in the case of a non-correct object,
20
/// or if the type is not supported
21
factory AttachmentModel.fromSpecificModel(
22
Map<String, dynamic> payload, String attachType) =>
24
'photo' => PhotoAttachmentModel(payload),
25
'video' => VideoAttachmentModel(payload),
26
'audio' => AudioAttachmentModel(payload),
27
'doc' => DocumentAttachmentModel(payload),
28
'link' => LinkAttachmentModel(payload),
29
'market' => MarketAttachmentModel(payload),
30
'market_album' => MarketAlbumAttachmentModel(payload),
31
'wall' => WallAttachmentModel(payload),
32
'wall_reply' => WallReplyAttachmentModel(payload),
33
'sticker' => StickerAttachmentModel(payload),
34
'gift' => GiftAttachmentModel(payload),
35
'graffiti' => GraffitiAttachmentModel(payload),
36
'poll' => PollAttachmentModel(payload),
37
'note' => NoteAttachmentModel(payload),
38
'page' => WikiPageAttachmentModel(payload),
39
_ => throw VkDartException('$attachType of attachment has no support!')
42
// ignore: public_member_api_docs
43
bool? checkBoolInProperty(String key) => checkBoolUtil(payload[key]);
46
/// Model Custom Attachment.
47
class CustomAttachmentModel extends AttachmentModel {
48
// ignore: public_member_api_docs
49
CustomAttachmentModel(super.payload, {required super.attachType});
51
/// Parses an attachment from a string.
54
/// CustomAttachmentModel.fromString('photo-1_2_ACCESS_KEY');
56
factory CustomAttachmentModel.fromString(String attachment) {
57
final parseAttachmentRe =
58
RegExp(r'([a-z_]+)(-?\d+)_(\d+)_?(\w+)?', multiLine: true);
60
if (!parseAttachmentRe.hasMatch(attachment)) {
61
throw VkDartException('Incorrect attachment!');
64
final match = parseAttachmentRe.firstMatch(attachment)!;
65
final attachType = match[1]!;
67
final attachmentPayload = <String, dynamic>{
68
'owner_id': int.parse(match[2]!),
69
'id': int.parse(match[3]!),
70
if (match[4] != null) 'access_key': match[4],
73
return AttachmentModel.fromSpecificModel(attachmentPayload, attachType)
74
as CustomAttachmentModel;
77
/// Attachment owner identifier.
78
int get ownerId => payload['owner_id'];
81
int get id => payload['id'];
83
/// Attachment access key.
84
String? get accessKey => payload['access_key'];
88
'$attachType${ownerId}_$id${accessKey != null ? '_$accessKey' : ''}';
91
/// Mixin for attachment likes.
92
mixin AttachmentLikesMixin on AttachmentModel {
93
Map<String, dynamic>? get _likes => payload['likes'];
95
/// the number of users who liked the post;
96
int? get likesCount => _likes?['count'];
98
/// the presence of a "like" mark from the current user ;
99
bool? get isUserLikes => checkBoolUtil(_likes?['user_likes']);
101
/// information about whether the current user can mark "Like";
102
bool? get isLikesCanLike => checkBoolUtil(_likes?['can_like']);
104
/// information about whether the current user can repost the post;
105
bool? get isLikesCanPublish => checkBoolUtil(_likes?['can_publish']);
108
/// Mixin for attachment reposts.
109
mixin AttachmentRepostsMixin on AttachmentModel {
110
Map<String, dynamic>? get _reposts => payload['reposts'];
112
/// the number of reposts;
113
int? get repostsCount => _reposts?['count'];
115
/// Indicates whether the current user has reposted the attachment.
116
bool? get isUserReposted => checkBoolUtil(_reposts?['user_reposted']);
118
/// repost counter on the wall.
119
int? get repostsWallCount => _reposts?['wall_count'];
121
/// counter of reposts in personal messages.
122
int? get repostsMailCount => _reposts?['mail_count'];