TUIMessageBaseMediaDataProvider.m 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. //
  2. // TUIMessageSearchDataProvider.m
  3. // TXIMSDK_TUIKit_iOS
  4. //
  5. // Created by kayev on 2021/7/8.
  6. // Copyright © 2023 Tencent. All rights reserved.
  7. //
  8. #import "TUIMessageBaseMediaDataProvider.h"
  9. #import "TUIMessageBaseDataProvider+ProtectedAPI.h"
  10. /**
  11. * Message pull method
  12. */
  13. typedef NS_ENUM(NSInteger, TUIMediaLoadType) {
  14. TUIMediaLoadType_Older = 1,
  15. TUIMediaLoadType_Newer = 2,
  16. TUIMediaLoadType_Older_And_Newer = 3,
  17. };
  18. @interface TUIMessageBaseMediaDataProvider ()
  19. @property(nonatomic) TUIChatConversationModel *conversationModel;
  20. @property(nonatomic, assign) TUIMediaLoadType loadType;
  21. @property(nonatomic, strong) V2TIMMessage *loadMessage;
  22. @property(nonatomic, assign) BOOL isOlderNoMoreMsg;
  23. @property(nonatomic, assign) BOOL isNewerNoMoreMsg;
  24. @end
  25. @implementation TUIMessageBaseMediaDataProvider
  26. - (instancetype)initWithConversationModel:(nullable TUIChatConversationModel *)conversationModel {
  27. self = [super initWithConversationModel:conversationModel];
  28. if (self) {
  29. self.conversationModel = conversationModel;
  30. self.isOlderNoMoreMsg = NO;
  31. self.isNewerNoMoreMsg = NO;
  32. self.pageCount = 20;
  33. self.medias = [NSMutableArray array];
  34. }
  35. return self;
  36. }
  37. - (void)loadMediaWithMessage:(V2TIMMessage *)curMessage {
  38. self.loadMessage = curMessage;
  39. self.loadType = TUIMediaLoadType_Older_And_Newer;
  40. /**
  41. * When the message is being sent, an exception will occur when pulling the before and after video (picture) messages through the current message. Only the
  42. * current message is displayed here for the time being.
  43. */
  44. if (self.loadMessage.status != V2TIM_MSG_STATUS_SENDING) {
  45. [self loadMedia];
  46. } else {
  47. NSMutableArray *medias = self.medias;
  48. TUIMessageCellData *data = [self.class getMediaCellData:self.loadMessage];
  49. if (data) {
  50. [medias addObject:data];
  51. self.medias = medias;
  52. }
  53. }
  54. }
  55. - (void)loadOlderMedia {
  56. if (self.loadMessage.status != V2TIM_MSG_STATUS_SENDING) {
  57. TUIMessageCellData *firstData = (TUIMessageCellData *)self.medias.firstObject;
  58. self.loadMessage = firstData.innerMessage;
  59. self.loadType = TUIMediaLoadType_Older;
  60. [self loadMedia];
  61. }
  62. }
  63. - (void)loadNewerMedia {
  64. if (self.loadMessage.status != V2TIM_MSG_STATUS_SENDING) {
  65. TUIMessageCellData *lastData = (TUIMessageCellData *)self.medias.lastObject;
  66. self.loadMessage = lastData.innerMessage;
  67. self.loadType = TUIMediaLoadType_Newer;
  68. [self loadMedia];
  69. }
  70. }
  71. - (void)loadMedia {
  72. if (!self.loadMessage) {
  73. return;
  74. }
  75. if (![self isNeedLoad:self.loadType]) {
  76. return;
  77. }
  78. @weakify(self);
  79. [self loadMediaMessage:self.loadMessage
  80. loadType:self.loadType
  81. SucceedBlock:^(NSArray<V2TIMMessage *> *_Nonnull olders, NSArray<V2TIMMessage *> *_Nonnull newers) {
  82. @strongify(self);
  83. NSMutableArray *medias = self.medias;
  84. for (V2TIMMessage *msg in olders) {
  85. TUIMessageCellData *data = [self.class getMediaCellData:msg];
  86. if (data) {
  87. [medias insertObject:data atIndex:0];
  88. }
  89. }
  90. if (self.loadType == TUIMediaLoadType_Older_And_Newer) {
  91. TUIMessageCellData *data = [self.class getMediaCellData:self.loadMessage];
  92. if (data) {
  93. [medias addObject:data];
  94. ;
  95. }
  96. }
  97. for (V2TIMMessage *msg in newers) {
  98. TUIMessageCellData *data = [self.class getMediaCellData:msg];
  99. if (data) {
  100. [medias addObject:data];
  101. }
  102. }
  103. self.medias = medias;
  104. }
  105. FailBlock:^(int code, NSString *desc) {
  106. NSLog(@"load message failed!");
  107. }];
  108. }
  109. - (BOOL)isNeedLoad:(TUIMediaLoadType)type {
  110. if ((TUIMediaLoadType_Older == type && self.isOlderNoMoreMsg) || (TUIMediaLoadType_Newer == type && self.isNewerNoMoreMsg) ||
  111. (TUIMediaLoadType_Older_And_Newer == type && self.isOlderNoMoreMsg && self.isNewerNoMoreMsg)) {
  112. return NO;
  113. }
  114. return YES;
  115. }
  116. - (void)loadMediaMessage:(V2TIMMessage *)loadMsg
  117. loadType:(TUIMediaLoadType)type
  118. SucceedBlock:(void (^)(NSArray<V2TIMMessage *> *_Nonnull olders, NSArray<V2TIMMessage *> *_Nonnull newers))succeedBlock
  119. FailBlock:(V2TIMFail)failBlock {
  120. if (self.isLoadingData) {
  121. failBlock(ERR_SUCC, @"loading");
  122. return;
  123. }
  124. self.isLoadingData = YES;
  125. dispatch_group_t group = dispatch_group_create();
  126. __block NSArray *olders = @[];
  127. __block NSArray *newers = @[];
  128. __block BOOL isOldLoadFail = NO;
  129. __block BOOL isNewLoadFail = NO;
  130. __block int failCode = 0;
  131. __block NSString *failDesc = nil;
  132. /**
  133. * Loading the oldest 20 media messages starting from the positioning message
  134. */
  135. if (TUIMediaLoadType_Older == type || TUIMediaLoadType_Older_And_Newer == type) {
  136. dispatch_group_enter(group);
  137. V2TIMMessageListGetOption *option = [[V2TIMMessageListGetOption alloc] init];
  138. option.getType = V2TIM_GET_LOCAL_OLDER_MSG;
  139. option.count = self.pageCount;
  140. option.groupID = self.conversationModel.groupID;
  141. option.userID = self.conversationModel.userID;
  142. option.lastMsg = loadMsg;
  143. option.messageTypeList = @[ @(V2TIM_ELEM_TYPE_IMAGE), @(V2TIM_ELEM_TYPE_VIDEO) ];
  144. [V2TIMManager.sharedInstance getHistoryMessageList:option
  145. succ:^(NSArray<V2TIMMessage *> *msgs) {
  146. olders = msgs ?: @[];
  147. if (olders.count < self.pageCount) {
  148. self.isOlderNoMoreMsg = YES;
  149. }
  150. dispatch_group_leave(group);
  151. }
  152. fail:^(int code, NSString *desc) {
  153. isOldLoadFail = YES;
  154. failCode = code;
  155. failDesc = desc;
  156. dispatch_group_leave(group);
  157. }];
  158. }
  159. /**
  160. * Load the latest 20 rich media messages starting from the positioning message
  161. */
  162. if (TUIMediaLoadType_Newer == type || TUIMediaLoadType_Older_And_Newer == type) {
  163. dispatch_group_enter(group);
  164. V2TIMMessageListGetOption *option = [[V2TIMMessageListGetOption alloc] init];
  165. option.getType = V2TIM_GET_LOCAL_NEWER_MSG;
  166. option.count = self.pageCount;
  167. option.groupID = self.conversationModel.groupID;
  168. option.userID = self.conversationModel.userID;
  169. option.lastMsg = loadMsg;
  170. option.messageTypeList = @[ @(V2TIM_ELEM_TYPE_IMAGE), @(V2TIM_ELEM_TYPE_VIDEO) ];
  171. [V2TIMManager.sharedInstance getHistoryMessageList:option
  172. succ:^(NSArray<V2TIMMessage *> *msgs) {
  173. newers = msgs ?: @[];
  174. if (newers.count < self.pageCount) {
  175. self.isNewerNoMoreMsg = YES;
  176. }
  177. dispatch_group_leave(group);
  178. }
  179. fail:^(int code, NSString *desc) {
  180. isNewLoadFail = YES;
  181. failCode = code;
  182. failDesc = desc;
  183. dispatch_group_leave(group);
  184. }];
  185. }
  186. @weakify(self);
  187. dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
  188. @strongify(self);
  189. self.isLoadingData = NO;
  190. if (isOldLoadFail || isNewLoadFail) {
  191. dispatch_async(dispatch_get_main_queue(), ^{
  192. failBlock(failCode, failDesc);
  193. });
  194. }
  195. self.isFirstLoad = NO;
  196. dispatch_async(dispatch_get_main_queue(), ^{
  197. succeedBlock(olders, newers);
  198. });
  199. });
  200. }
  201. - (void)removeCache {
  202. [self.medias removeAllObjects];
  203. self.isNewerNoMoreMsg = NO;
  204. self.isOlderNoMoreMsg = NO;
  205. self.isFirstLoad = YES;
  206. }
  207. + (TUIMessageCellData *)getMediaCellData:(V2TIMMessage *)message {
  208. // subclass override required
  209. return nil;
  210. }
  211. @end