WFCCIMService.mm 78 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940
  1. //
  2. // WFCCIMService.mm
  3. // WFChatClient
  4. //
  5. // Created by heavyrain on 2017/11/5.
  6. // Copyright © 2017年 WildFireChat. All rights reserved.
  7. //
  8. #import "WFCCIMService.h"
  9. #import "WFCCMediaMessageContent.h"
  10. #import <mars/proto/MessageDB.h>
  11. #import <objc/runtime.h>
  12. #import "WFCCNetworkService.h"
  13. #import <mars/app/app.h>
  14. #import "WFCCGroupSearchInfo.h"
  15. #import "WFCCUnknownMessageContent.h"
  16. #import "WFCCRecallMessageContent.h"
  17. NSString *kSendingMessageStatusUpdated = @"kSendingMessageStatusUpdated";
  18. NSString *kConnectionStatusChanged = @"kConnectionStatusChanged";
  19. NSString *kReceiveMessages = @"kReceiveMessages";
  20. NSString *kRecallMessages = @"kRecallMessages";
  21. NSString *kDeleteMessages = @"kDeleteMessages";
  22. NSString *kMessageDelivered = @"kMessageDelivered";
  23. NSString *kMessageReaded = @"kMessageReaded";
  24. class IMSendMessageCallback : public mars::stn::SendMsgCallback {
  25. private:
  26. void(^m_successBlock)(long long messageUid, long long timestamp);
  27. void(^m_errorBlock)(int error_code);
  28. void(^m_progressBlock)(long uploaded, long total);
  29. WFCCMessage *m_message;
  30. public:
  31. IMSendMessageCallback(WFCCMessage *message, void(^successBlock)(long long messageUid, long long timestamp), void(^progressBlock)(long uploaded, long total), void(^errorBlock)(int error_code)) : mars::stn::SendMsgCallback(), m_message(message), m_successBlock(successBlock), m_progressBlock(progressBlock), m_errorBlock(errorBlock) {};
  32. void onSuccess(long long messageUid, long long timestamp) {
  33. dispatch_async(dispatch_get_main_queue(), ^{
  34. m_message.messageUid = messageUid;
  35. m_message.serverTime = timestamp;
  36. m_message.status = Message_Status_Sent;
  37. if (m_successBlock) {
  38. m_successBlock(messageUid, timestamp);
  39. }
  40. [[NSNotificationCenter defaultCenter] postNotificationName:kSendingMessageStatusUpdated object:@(m_message.messageId) userInfo:@{@"status":@(Message_Status_Sent), @"messageUid":@(messageUid), @"timestamp":@(timestamp)}];
  41. delete this;
  42. });
  43. }
  44. void onFalure(int errorCode) {
  45. dispatch_async(dispatch_get_main_queue(), ^{
  46. m_message.status = Message_Status_Send_Failure;
  47. if (m_errorBlock) {
  48. m_errorBlock(errorCode);
  49. }
  50. [[NSNotificationCenter defaultCenter] postNotificationName:kSendingMessageStatusUpdated object:@(m_message.messageId) userInfo:@{@"status":@(Message_Status_Send_Failure)}];
  51. delete this;
  52. });
  53. }
  54. void onPrepared(long messageId, int64_t savedTime) {
  55. m_message.messageId = messageId;
  56. m_message.serverTime = savedTime;
  57. [[NSNotificationCenter defaultCenter] postNotificationName:kSendingMessageStatusUpdated object:@(m_message.messageId) userInfo:@{@"status":@(Message_Status_Sending), @"message":m_message}];
  58. }
  59. void onMediaUploaded(std::string remoteUrl) {
  60. if ([m_message.content isKindOfClass:[WFCCMediaMessageContent class]]) {
  61. WFCCMediaMessageContent *mediaContent = (WFCCMediaMessageContent *)m_message.content;
  62. mediaContent.remoteUrl = [NSString stringWithUTF8String:remoteUrl.c_str()];
  63. }
  64. }
  65. void onProgress(int uploaded, int total) {
  66. dispatch_async(dispatch_get_main_queue(), ^{
  67. if (m_progressBlock) {
  68. m_progressBlock(uploaded, total);
  69. }
  70. });
  71. }
  72. virtual ~IMSendMessageCallback() {
  73. m_successBlock = nil;
  74. m_errorBlock = nil;
  75. m_progressBlock = nil;
  76. m_message = nil;
  77. }
  78. };
  79. extern WFCCUserInfo* convertUserInfo(const mars::stn::TUserInfo &tui);
  80. class IMCreateGroupCallback : public mars::stn::CreateGroupCallback {
  81. private:
  82. void(^m_successBlock)(NSString *groupId);
  83. void(^m_errorBlock)(int error_code);
  84. public:
  85. IMCreateGroupCallback(void(^successBlock)(NSString *groupId), void(^errorBlock)(int error_code)) : mars::stn::CreateGroupCallback(), m_successBlock(successBlock), m_errorBlock(errorBlock) {};
  86. void onSuccess(std::string groupId) {
  87. dispatch_async(dispatch_get_main_queue(), ^{
  88. if (m_successBlock) {
  89. m_successBlock([NSString stringWithUTF8String:groupId.c_str()]);
  90. }
  91. delete this;
  92. });
  93. }
  94. void onFalure(int errorCode) {
  95. dispatch_async(dispatch_get_main_queue(), ^{
  96. if (m_errorBlock) {
  97. m_errorBlock(errorCode);
  98. }
  99. delete this;
  100. });
  101. }
  102. virtual ~IMCreateGroupCallback() {
  103. m_successBlock = nil;
  104. m_errorBlock = nil;
  105. }
  106. };
  107. class IMGeneralOperationCallback : public mars::stn::GeneralOperationCallback {
  108. private:
  109. void(^m_successBlock)();
  110. void(^m_errorBlock)(int error_code);
  111. public:
  112. IMGeneralOperationCallback(void(^successBlock)(), void(^errorBlock)(int error_code)) : mars::stn::GeneralOperationCallback(), m_successBlock(successBlock), m_errorBlock(errorBlock) {};
  113. void onSuccess() {
  114. dispatch_async(dispatch_get_main_queue(), ^{
  115. if (m_successBlock) {
  116. m_successBlock();
  117. }
  118. delete this;
  119. });
  120. }
  121. void onFalure(int errorCode) {
  122. dispatch_async(dispatch_get_main_queue(), ^{
  123. if (m_errorBlock) {
  124. m_errorBlock(errorCode);
  125. }
  126. delete this;
  127. });
  128. }
  129. virtual ~IMGeneralOperationCallback() {
  130. m_successBlock = nil;
  131. m_errorBlock = nil;
  132. }
  133. };
  134. class IMGeneralStringCallback : public mars::stn::GeneralStringCallback {
  135. private:
  136. void(^m_successBlock)(NSString *generalStr);
  137. void(^m_errorBlock)(int error_code);
  138. public:
  139. IMGeneralStringCallback(void(^successBlock)(NSString *groupId), void(^errorBlock)(int error_code)) : mars::stn::GeneralStringCallback(), m_successBlock(successBlock), m_errorBlock(errorBlock) {};
  140. void onSuccess(std::string str) {
  141. dispatch_async(dispatch_get_main_queue(), ^{
  142. if (m_successBlock) {
  143. m_successBlock([NSString stringWithUTF8String:str.c_str()]);
  144. }
  145. delete this;
  146. });
  147. }
  148. void onFalure(int errorCode) {
  149. dispatch_async(dispatch_get_main_queue(), ^{
  150. if (m_errorBlock) {
  151. m_errorBlock(errorCode);
  152. }
  153. delete this;
  154. });
  155. }
  156. virtual ~IMGeneralStringCallback() {
  157. m_successBlock = nil;
  158. m_errorBlock = nil;
  159. }
  160. };
  161. class RecallMessageCallback : public mars::stn::GeneralOperationCallback {
  162. private:
  163. void(^m_successBlock)();
  164. void(^m_errorBlock)(int error_code);
  165. WFCCMessage *message;
  166. public:
  167. RecallMessageCallback(WFCCMessage *msg, void(^successBlock)(), void(^errorBlock)(int error_code)) : mars::stn::GeneralOperationCallback(), m_successBlock(successBlock), m_errorBlock(errorBlock), message(msg) {};
  168. void onSuccess() {
  169. WFCCRecallMessageContent *recallCnt = [[WFCCRecallMessageContent alloc] init];
  170. recallCnt.operatorId = [WFCCNetworkService sharedInstance].userId;
  171. recallCnt.messageUid = message.messageUid;
  172. message.content = recallCnt;
  173. dispatch_async(dispatch_get_main_queue(), ^{
  174. if (m_successBlock) {
  175. m_successBlock();
  176. }
  177. delete this;
  178. });
  179. }
  180. void onFalure(int errorCode) {
  181. dispatch_async(dispatch_get_main_queue(), ^{
  182. if (m_errorBlock) {
  183. m_errorBlock(errorCode);
  184. }
  185. delete this;
  186. });
  187. }
  188. virtual ~RecallMessageCallback() {
  189. m_successBlock = nil;
  190. m_errorBlock = nil;
  191. }
  192. };
  193. class IMGetChatroomInfoCallback : public mars::stn::GetChatroomInfoCallback {
  194. private:
  195. NSString *chatroomId;
  196. void(^m_successBlock)(WFCCChatroomInfo *chatroomInfo);
  197. void(^m_errorBlock)(int error_code);
  198. public:
  199. IMGetChatroomInfoCallback(NSString *cid, void(^successBlock)(WFCCChatroomInfo *chatroomInfo), void(^errorBlock)(int error_code)) : mars::stn::GetChatroomInfoCallback(), chatroomId(cid), m_successBlock(successBlock), m_errorBlock(errorBlock) {};
  200. void onSuccess(const mars::stn::TChatroomInfo &info) {
  201. WFCCChatroomInfo *chatroomInfo = [[WFCCChatroomInfo alloc] init];
  202. chatroomInfo.chatroomId = chatroomId;
  203. chatroomInfo.title = [NSString stringWithUTF8String:info.title.c_str()];
  204. chatroomInfo.desc = [NSString stringWithUTF8String:info.desc.c_str()];
  205. chatroomInfo.portrait = [NSString stringWithUTF8String:info.portrait.c_str()];
  206. chatroomInfo.extra = [NSString stringWithUTF8String:info.extra.c_str()];
  207. chatroomInfo.state = info.state;
  208. chatroomInfo.memberCount = info.memberCount;
  209. chatroomInfo.createDt = info.createDt;
  210. chatroomInfo.updateDt = info.updateDt;
  211. dispatch_async(dispatch_get_main_queue(), ^{
  212. if (m_successBlock) {
  213. m_successBlock(chatroomInfo);
  214. }
  215. delete this;
  216. });
  217. }
  218. void onFalure(int errorCode) {
  219. dispatch_async(dispatch_get_main_queue(), ^{
  220. if (m_errorBlock) {
  221. m_errorBlock(errorCode);
  222. }
  223. delete this;
  224. });
  225. }
  226. virtual ~IMGetChatroomInfoCallback() {
  227. m_successBlock = nil;
  228. m_errorBlock = nil;
  229. }
  230. };
  231. extern NSMutableArray* convertProtoMessageList(const std::list<mars::stn::TMessage> &messageList, BOOL reverse);
  232. class IMLoadRemoteMessagesCallback : public mars::stn::LoadRemoteMessagesCallback {
  233. private:
  234. void(^m_successBlock)(NSArray<WFCCMessage *> *messages);
  235. void(^m_errorBlock)(int error_code);
  236. public:
  237. IMLoadRemoteMessagesCallback(void(^successBlock)(NSArray<WFCCMessage *> *messages), void(^errorBlock)(int error_code)) : mars::stn::LoadRemoteMessagesCallback(), m_successBlock(successBlock), m_errorBlock(errorBlock) {};
  238. void onSuccess(const std::list<mars::stn::TMessage> &messageList) {
  239. NSMutableArray *messages = convertProtoMessageList(messageList, NO);
  240. dispatch_async(dispatch_get_main_queue(), ^{
  241. if (m_successBlock) {
  242. m_successBlock(messages);
  243. }
  244. delete this;
  245. });
  246. }
  247. void onFalure(int errorCode) {
  248. dispatch_async(dispatch_get_main_queue(), ^{
  249. if (m_errorBlock) {
  250. m_errorBlock(errorCode);
  251. }
  252. delete this;
  253. });
  254. }
  255. virtual ~IMLoadRemoteMessagesCallback() {
  256. m_successBlock = nil;
  257. m_errorBlock = nil;
  258. }
  259. };
  260. class IMGetChatroomMemberInfoCallback : public mars::stn::GetChatroomMemberInfoCallback {
  261. private:
  262. void(^m_successBlock)(WFCCChatroomMemberInfo *chatroomMemberInfo);
  263. void(^m_errorBlock)(int error_code);
  264. public:
  265. IMGetChatroomMemberInfoCallback(void(^successBlock)(WFCCChatroomMemberInfo *chatroomMemberInfo), void(^errorBlock)(int error_code)) : mars::stn::GetChatroomMemberInfoCallback(), m_successBlock(successBlock), m_errorBlock(errorBlock) {};
  266. void onSuccess(const mars::stn::TChatroomMemberInfo &info) {
  267. WFCCChatroomMemberInfo *memberInfo = [[WFCCChatroomMemberInfo alloc] init];
  268. memberInfo.memberCount = info.memberCount;
  269. NSMutableArray *members = [[NSMutableArray alloc] init];
  270. for (std::list<std::string>::const_iterator it = info.olderMembers.begin(); it != info.olderMembers.end(); it++) {
  271. [members addObject:[NSString stringWithUTF8String:it->c_str()]];
  272. }
  273. dispatch_async(dispatch_get_main_queue(), ^{
  274. if (m_successBlock) {
  275. m_successBlock(memberInfo);
  276. }
  277. delete this;
  278. });
  279. }
  280. void onFalure(int errorCode) {
  281. dispatch_async(dispatch_get_main_queue(), ^{
  282. if (m_errorBlock) {
  283. m_errorBlock(errorCode);
  284. }
  285. delete this;
  286. });
  287. }
  288. virtual ~IMGetChatroomMemberInfoCallback() {
  289. m_successBlock = nil;
  290. m_errorBlock = nil;
  291. }
  292. };
  293. class IMGetGroupInfoCallback : public mars::stn::GetGroupInfoCallback {
  294. private:
  295. void(^m_successBlock)(NSArray<WFCCGroupInfo *> *);
  296. void(^m_errorBlock)(int error_code);
  297. public:
  298. IMGetGroupInfoCallback(void(^successBlock)(NSArray<WFCCGroupInfo *> *), void(^errorBlock)(int error_code)) : mars::stn::GetGroupInfoCallback(), m_successBlock(successBlock), m_errorBlock(errorBlock) {};
  299. void onSuccess(const std::list<const mars::stn::TGroupInfo> &groupInfoList) {
  300. NSMutableArray *ret = nil;
  301. if (m_successBlock) {
  302. NSMutableArray *ret = [[NSMutableArray alloc] init];
  303. for (std::list<const mars::stn::TGroupInfo>::const_iterator it = groupInfoList.begin(); it != groupInfoList.end(); it++) {
  304. WFCCGroupInfo *gi = [[WFCCGroupInfo alloc] init];
  305. const mars::stn::TGroupInfo &tgi = *it;
  306. gi.target = [NSString stringWithUTF8String:tgi.target.c_str()];
  307. gi.type = (WFCCGroupType)tgi.type;
  308. gi.memberCount = tgi.memberCount;
  309. gi.name = [NSString stringWithUTF8String:tgi.name.c_str()];
  310. gi.owner = [NSString stringWithUTF8String:tgi.owner.c_str()];
  311. gi.extra = [NSString stringWithUTF8String:tgi.extra.c_str()];
  312. [ret addObject:gi];
  313. }
  314. }
  315. dispatch_async(dispatch_get_main_queue(), ^{
  316. if (m_successBlock) {
  317. m_successBlock(ret);
  318. }
  319. delete this;
  320. });
  321. }
  322. void onFalure(int errorCode) {
  323. dispatch_async(dispatch_get_main_queue(), ^{
  324. if (m_errorBlock) {
  325. m_errorBlock(errorCode);
  326. }
  327. delete this;
  328. });
  329. }
  330. virtual ~IMGetGroupInfoCallback() {
  331. m_successBlock = nil;
  332. m_errorBlock = nil;
  333. }
  334. };
  335. class GeneralUpdateMediaCallback : public mars::stn::UpdateMediaCallback {
  336. public:
  337. void(^m_successBlock)(NSString *remoteUrl);
  338. void(^m_errorBlock)(int error_code);
  339. void(^m_progressBlock)(long uploaded, long total);
  340. GeneralUpdateMediaCallback(void(^successBlock)(NSString *remoteUrl), void(^progressBlock)(long uploaded, long total), void(^errorBlock)(int error_code)) : mars::stn::UpdateMediaCallback(), m_successBlock(successBlock), m_progressBlock(progressBlock), m_errorBlock(errorBlock) {}
  341. void onSuccess(const std::string &remoteUrl) {
  342. NSString *url = [NSString stringWithUTF8String:remoteUrl.c_str()];
  343. dispatch_async(dispatch_get_main_queue(), ^{
  344. if (m_successBlock) {
  345. m_successBlock(url);
  346. }
  347. delete this;
  348. });
  349. }
  350. void onFalure(int errorCode) {
  351. dispatch_async(dispatch_get_main_queue(), ^{
  352. if (m_errorBlock) {
  353. m_errorBlock(errorCode);
  354. }
  355. delete this;
  356. });
  357. }
  358. void onProgress(int current, int total) {
  359. dispatch_async(dispatch_get_main_queue(), ^{
  360. if (m_progressBlock) {
  361. m_progressBlock(current, total);
  362. }
  363. });
  364. }
  365. ~GeneralUpdateMediaCallback() {
  366. m_successBlock = nil;
  367. m_errorBlock = nil;
  368. }
  369. };
  370. static WFCCMessage *convertProtoMessage(const mars::stn::TMessage *tMessage) {
  371. if (tMessage->target.empty()) {
  372. return nil;
  373. }
  374. WFCCMessage *ret = [[WFCCMessage alloc] init];
  375. ret.fromUser = [NSString stringWithUTF8String:tMessage->from.c_str()];
  376. ret.conversation = [[WFCCConversation alloc] init];
  377. ret.conversation.type = (WFCCConversationType)tMessage->conversationType;
  378. ret.conversation.target = [NSString stringWithUTF8String:tMessage->target.c_str()];
  379. ret.conversation.line = tMessage->line;
  380. ret.messageId = tMessage->messageId;
  381. ret.messageUid = tMessage->messageUid;
  382. ret.serverTime = tMessage->timestamp;
  383. NSMutableArray *toUsers = [[NSMutableArray alloc] init];
  384. for (std::list<std::string>::const_iterator it = tMessage->to.begin(); it != tMessage->to.end(); ++it) {
  385. NSString *user = [NSString stringWithUTF8String:(*it).c_str()];
  386. [toUsers addObject:user];
  387. }
  388. ret.toUsers = toUsers;
  389. ret.direction = (WFCCMessageDirection)tMessage->direction;
  390. ret.status = (WFCCMessageStatus)tMessage->status;
  391. WFCCMediaMessagePayload *payload = [[WFCCMediaMessagePayload alloc] init];
  392. payload.contentType = tMessage->content.type;
  393. payload.searchableContent = [NSString stringWithUTF8String:tMessage->content.searchableContent.c_str()];
  394. payload.pushContent = [NSString stringWithUTF8String:tMessage->content.pushContent.c_str()];
  395. payload.content = [NSString stringWithUTF8String:tMessage->content.content.c_str()];
  396. payload.binaryContent = [NSData dataWithBytes:tMessage->content.binaryContent.c_str() length:tMessage->content.binaryContent.length()];
  397. payload.localContent = [NSString stringWithUTF8String:tMessage->content.localContent.c_str()];
  398. payload.mediaType = (WFCCMediaType)tMessage->content.mediaType;
  399. payload.remoteMediaUrl = [NSString stringWithUTF8String:tMessage->content.remoteMediaUrl.c_str()];
  400. payload.localMediaPath = [NSString stringWithUTF8String:tMessage->content.localMediaPath.c_str()];
  401. payload.mentionedType = tMessage->content.mentionedType;
  402. NSMutableArray *mentionedType = [[NSMutableArray alloc] init];
  403. for (std::list<std::string>::const_iterator it = tMessage->content.mentionedTargets.begin(); it != tMessage->content.mentionedTargets.end(); it++) {
  404. [mentionedType addObject:[NSString stringWithUTF8String:(*it).c_str()]];
  405. }
  406. payload.extra = [NSString stringWithUTF8String:tMessage->content.extra.c_str()];
  407. ret.content = [[WFCCIMService sharedWFCIMService] messageContentFromPayload:payload];
  408. return ret;
  409. }
  410. NSMutableArray* convertProtoMessageList(const std::list<mars::stn::TMessage> &messageList, BOOL reverse) {
  411. NSMutableArray *messages = [[NSMutableArray alloc] init];
  412. for (std::list<mars::stn::TMessage>::const_iterator it = messageList.begin(); it != messageList.end(); it++) {
  413. const mars::stn::TMessage &tmsg = *it;
  414. WFCCMessage *msg = convertProtoMessage(&tmsg);
  415. if (msg) {
  416. if (reverse) {
  417. [messages insertObject:msg atIndex:0];
  418. } else {
  419. [messages addObject:msg];
  420. }
  421. }
  422. }
  423. return messages;
  424. }
  425. NSMutableArray* convertProtoDeliveryList(const std::map<std::string, int64_t> &userReceived) {
  426. NSMutableArray *messages = [[NSMutableArray alloc] init];
  427. for(std::map<std::string, int64_t>::const_iterator it = userReceived.begin(); it != userReceived.end(); ++it) {
  428. [messages addObject:[WFCCDeliveryReport delivered:[NSString stringWithUTF8String:it->first.c_str()] timestamp:it->second]];
  429. }
  430. return messages;
  431. }
  432. NSMutableArray* convertProtoReadedList(const std::list<mars::stn::TReadEntry> &userReceived) {
  433. NSMutableArray *messages = [[NSMutableArray alloc] init];
  434. for(std::list<mars::stn::TReadEntry>::const_iterator it = userReceived.begin(); it != userReceived.end(); ++it) {
  435. [messages addObject:[WFCCReadReport readed:[WFCCConversation conversationWithType:(WFCCConversationType)it->conversationType target:[NSString stringWithUTF8String:it->target.c_str()] line:it->line] userId:[NSString stringWithUTF8String:it->userId.c_str()] timestamp:it->readDt]];
  436. }
  437. return messages;
  438. }
  439. static WFCCConversationInfo* convertConversationInfo(const mars::stn::TConversation &tConv) {
  440. WFCCConversationInfo *info = [[WFCCConversationInfo alloc] init];
  441. info.conversation = [[WFCCConversation alloc] init];
  442. info.conversation.type = (WFCCConversationType)tConv.conversationType;
  443. info.conversation.target = [NSString stringWithUTF8String:tConv.target.c_str()];
  444. info.conversation.line = tConv.line;
  445. info.lastMessage = convertProtoMessage(&tConv.lastMessage);
  446. info.draft = [NSString stringWithUTF8String:tConv.draft.c_str()];
  447. info.timestamp = tConv.timestamp;
  448. info.unreadCount = [WFCCUnreadCount countOf:tConv.unreadCount.unread mention:tConv.unreadCount.unreadMention mentionAll:tConv.unreadCount.unreadMentionAll];
  449. info.isTop = tConv.isTop;
  450. info.isSilent = tConv.isSilent;
  451. return info;
  452. }
  453. static WFCCIMService * sharedSingleton = nil;
  454. static void fillTMessageContent(mars::stn::TMessageContent &tmsgcontent, WFCCMessageContent *content) {
  455. WFCCMessagePayload *payload = [content encode];
  456. payload.extra = content.extra;
  457. tmsgcontent.type = payload.contentType;
  458. tmsgcontent.searchableContent = [payload.searchableContent UTF8String] ? [payload.searchableContent UTF8String] : "";
  459. tmsgcontent.pushContent = [payload.pushContent UTF8String] ? [payload.pushContent UTF8String] : "";
  460. tmsgcontent.content = [payload.content UTF8String] ? [payload.content UTF8String] : "";
  461. if (payload.binaryContent != nil) {
  462. tmsgcontent.binaryContent = std::string((const char *)payload.binaryContent.bytes, payload.binaryContent.length);
  463. }
  464. tmsgcontent.localContent = [payload.localContent UTF8String] ? [payload.localContent UTF8String] : "";
  465. if ([payload isKindOfClass:[WFCCMediaMessagePayload class]]) {
  466. WFCCMediaMessagePayload *mediaPayload = (WFCCMediaMessagePayload *)payload;
  467. tmsgcontent.mediaType = mediaPayload.mediaType;
  468. tmsgcontent.remoteMediaUrl = [mediaPayload.remoteMediaUrl UTF8String] ? [mediaPayload.remoteMediaUrl UTF8String] : "";
  469. tmsgcontent.localMediaPath = [mediaPayload.localMediaPath UTF8String] ? [mediaPayload.localMediaPath UTF8String] : "";
  470. }
  471. tmsgcontent.mentionedType = payload.mentionedType;
  472. for (NSString *target in payload.mentionedTargets) {
  473. tmsgcontent.mentionedTargets.insert(tmsgcontent.mentionedTargets.end(), [target UTF8String]);
  474. }
  475. tmsgcontent.extra = [payload.extra UTF8String] ? [payload.extra UTF8String] : "";
  476. }
  477. static void fillTMessage(mars::stn::TMessage &tmsg, WFCCConversation *conv, WFCCMessageContent *content) {
  478. tmsg.conversationType = conv.type;
  479. tmsg.target = conv.target ? [conv.target UTF8String] : "";
  480. tmsg.line = conv.line;
  481. tmsg.from = mars::app::GetAccountUserName();
  482. tmsg.status = mars::stn::MessageStatus::Message_Status_Sending;
  483. tmsg.timestamp = time(NULL)*1000;
  484. tmsg.direction = 0;
  485. fillTMessageContent(tmsg.content, content);
  486. }
  487. @interface WFCCIMService ()
  488. @property(nonatomic, strong)NSMutableDictionary<NSNumber *, Class> *MessageContentMaps;
  489. @end
  490. @implementation WFCCIMService
  491. + (WFCCIMService *)sharedWFCIMService {
  492. if (sharedSingleton == nil) {
  493. @synchronized (self) {
  494. if (sharedSingleton == nil) {
  495. sharedSingleton = [[WFCCIMService alloc] init];
  496. sharedSingleton.MessageContentMaps = [[NSMutableDictionary alloc] init];
  497. }
  498. }
  499. }
  500. return sharedSingleton;
  501. }
  502. - (WFCCMessage *)send:(WFCCConversation *)conversation
  503. content:(WFCCMessageContent *)content
  504. success:(void(^)(long long messageUd, long long timestamp))successBlock
  505. error:(void(^)(int error_code))errorBlock {
  506. return [self sendMedia:conversation content:content expireDuration:0 success:successBlock progress:nil error:errorBlock];
  507. }
  508. - (WFCCMessage *)sendMedia:(WFCCConversation *)conversation
  509. content:(WFCCMessageContent *)content
  510. success:(void(^)(long long messageUid, long long timestamp))successBlock
  511. progress:(void(^)(long uploaded, long total))progressBlock
  512. error:(void(^)(int error_code))errorBlock {
  513. return [self sendMedia:conversation content:content expireDuration:0 success:successBlock progress:progressBlock error:errorBlock];
  514. }
  515. - (WFCCMessage *)send:(WFCCConversation *)conversation
  516. content:(WFCCMessageContent *)content
  517. expireDuration:(int)expireDuration
  518. success:(void(^)(long long messageUid, long long timestamp))successBlock
  519. error:(void(^)(int error_code))errorBlock {
  520. return [self sendMedia:conversation content:content expireDuration:0 success:successBlock progress:nil error:errorBlock];
  521. }
  522. - (WFCCMessage *)send:(WFCCConversation *)conversation
  523. content:(WFCCMessageContent *)content
  524. toUsers:(NSArray<NSString *> *)toUsers
  525. expireDuration:(int)expireDuration
  526. success:(void(^)(long long messageUid, long long timestamp))successBlock
  527. error:(void(^)(int error_code))errorBlock {
  528. return [self sendMedia:conversation content:content toUsers:toUsers expireDuration:0 success:successBlock progress:nil error:errorBlock];
  529. }
  530. - (WFCCMessage *)sendMedia:(WFCCConversation *)conversation
  531. content:(WFCCMessageContent *)content
  532. expireDuration:(int)expireDuration
  533. success:(void(^)(long long messageUid, long long timestamp))successBlock
  534. progress:(void(^)(long uploaded, long total))progressBlock
  535. error:(void(^)(int error_code))errorBlock {
  536. return [self sendMedia:conversation content:content toUsers:nil expireDuration:expireDuration success:successBlock progress:progressBlock error:errorBlock];
  537. }
  538. - (WFCCMessage *)sendMedia:(WFCCConversation *)conversation
  539. content:(WFCCMessageContent *)content
  540. toUsers:(NSArray<NSString *>*)toUsers
  541. expireDuration:(int)expireDuration
  542. success:(void(^)(long long messageUid, long long timestamp))successBlock
  543. progress:(void(^)(long uploaded, long total))progressBlock
  544. error:(void(^)(int error_code))errorBlock {
  545. WFCCMessage *message = [[WFCCMessage alloc] init];
  546. message.conversation = conversation;
  547. message.content = content;
  548. message.toUsers = toUsers;
  549. mars::stn::TMessage tmsg;
  550. if (toUsers.count) {
  551. for (NSString *obj in toUsers) {
  552. tmsg.to.push_back([obj UTF8String]);
  553. }
  554. }
  555. message.status = Message_Status_Sending;
  556. fillTMessage(tmsg, conversation, content);
  557. message.fromUser = [WFCCNetworkService sharedInstance].userId;
  558. mars::stn::sendMessage(tmsg, new IMSendMessageCallback(message, successBlock, progressBlock, errorBlock), expireDuration);
  559. return message;
  560. }
  561. - (BOOL)sendSavedMessage:(WFCCMessage *)message
  562. expireDuration:(int)expireDuration
  563. success:(void(^)(long long messageUid, long long timestamp))successBlock
  564. error:(void(^)(int error_code))errorBlock {
  565. if(mars::stn::sendMessageEx(message.messageId, new IMSendMessageCallback(message, successBlock, nil, errorBlock), expireDuration)) {
  566. return YES;
  567. } else {
  568. return NO;
  569. }
  570. }
  571. - (void)recall:(WFCCMessage *)msg
  572. success:(void(^)(void))successBlock
  573. error:(void(^)(int error_code))errorBlock {
  574. if (msg == nil) {
  575. dispatch_async(dispatch_get_main_queue(), ^{
  576. NSLog(@"recall msg failure, message not exist");
  577. errorBlock(-1);
  578. });
  579. return;
  580. }
  581. mars::stn::recallMessage(msg.messageUid, new RecallMessageCallback(msg, successBlock, errorBlock));
  582. }
  583. - (NSArray<WFCCConversationInfo *> *)getConversationInfos:(NSArray<NSNumber *> *)conversationTypes lines:(NSArray<NSNumber *> *)lines{
  584. std::list<int> types;
  585. for (NSNumber *type in conversationTypes) {
  586. types.push_back([type intValue]);
  587. }
  588. std::list<int> ls;
  589. for (NSNumber *type in lines) {
  590. ls.push_back([type intValue]);
  591. }
  592. std::list<mars::stn::TConversation> convers = mars::stn::MessageDB::Instance()->GetConversationList(types, ls);
  593. NSMutableArray *ret = [[NSMutableArray alloc] init];
  594. for (std::list<mars::stn::TConversation>::iterator it = convers.begin(); it != convers.end(); it++) {
  595. mars::stn::TConversation &tConv = *it;
  596. WFCCConversationInfo *info = convertConversationInfo(tConv);
  597. [ret addObject:info];
  598. }
  599. return ret;
  600. }
  601. - (WFCCConversationInfo *)getConversationInfo:(WFCCConversation *)conversation {
  602. mars::stn::TConversation tConv = mars::stn::MessageDB::Instance()->GetConversation(conversation.type, [conversation.target UTF8String], conversation.line);
  603. return convertConversationInfo(tConv);
  604. }
  605. - (NSArray<WFCCMessage *> *)getMessages:(WFCCConversation *)conversation contentTypes:(NSArray<NSNumber *> *)contentTypes from:(NSUInteger)fromIndex count:(NSInteger)count withUser:(NSString *)user {
  606. std::list<int> types;
  607. for (NSNumber *num in contentTypes) {
  608. types.push_back(num.intValue);
  609. }
  610. bool direction = true;
  611. if (count < 0) {
  612. direction = false;
  613. count = -count;
  614. }
  615. std::list<mars::stn::TMessage> messages = mars::stn::MessageDB::Instance()->GetMessages(conversation.type, [conversation.target UTF8String], conversation.line, types, direction, (int)count, fromIndex, user ? [user UTF8String] : "");
  616. return convertProtoMessageList(messages, YES);
  617. }
  618. - (NSArray<WFCCMessage *> *)getMessages:(NSArray<NSNumber *> *)conversationTypes
  619. lines:(NSArray<NSNumber *> *)lines
  620. contentTypes:(NSArray<NSNumber *> *)contentTypes
  621. from:(NSUInteger)fromIndex
  622. count:(NSInteger)count
  623. withUser:(NSString *)user {
  624. std::list<int> convtypes;
  625. for (NSNumber *ct in conversationTypes) {
  626. convtypes.push_back([ct intValue]);
  627. }
  628. std::list<int> ls;
  629. for (NSNumber *type in lines) {
  630. ls.push_back([type intValue]);
  631. }
  632. std::list<int> types;
  633. for (NSNumber *num in contentTypes) {
  634. types.push_back(num.intValue);
  635. }
  636. bool direction = true;
  637. if (count < 0) {
  638. direction = false;
  639. count = -count;
  640. }
  641. std::list<mars::stn::TMessage> messages = mars::stn::MessageDB::Instance()->GetMessages(convtypes, ls, types, direction, (int)count, fromIndex, user ? [user UTF8String] : "");
  642. return convertProtoMessageList(messages, YES);
  643. }
  644. - (NSArray<WFCCMessage *> *)getMessages:(NSArray<NSNumber *> *)conversationTypes
  645. lines:(NSArray<NSNumber *> *)lines
  646. messageStatus:(WFCCMessageStatus)messageStatus
  647. from:(NSUInteger)fromIndex
  648. count:(NSInteger)count
  649. withUser:(NSString *)user {
  650. std::list<int> convtypes;
  651. for (NSNumber *ct in conversationTypes) {
  652. convtypes.push_back([ct intValue]);
  653. }
  654. std::list<int> ls;
  655. for (NSNumber *type in lines) {
  656. ls.push_back([type intValue]);
  657. }
  658. bool direction = true;
  659. if (count < 0) {
  660. direction = false;
  661. count = -count;
  662. }
  663. std::list<mars::stn::TMessage> messages = mars::stn::MessageDB::Instance()->GetMessages(convtypes, ls, messageStatus, direction, (int)count, fromIndex, user ? [user UTF8String] : "");
  664. return convertProtoMessageList(messages, YES);
  665. }
  666. - (void)getRemoteMessages:(WFCCConversation *)conversation
  667. before:(long long)beforeMessageUid
  668. count:(NSUInteger)count
  669. success:(void(^)(NSArray<WFCCMessage *> *messages))successBlock
  670. error:(void(^)(int error_code))errorBlock {
  671. mars::stn::TConversation conv;
  672. conv.target = [conversation.target UTF8String];
  673. conv.line = conversation.line;
  674. conv.conversationType = conversation.type;
  675. mars::stn::loadRemoteMessages(conv, beforeMessageUid, (int)count, new IMLoadRemoteMessagesCallback(successBlock, errorBlock));
  676. }
  677. - (WFCCMessage *)getMessage:(long)messageId {
  678. mars::stn::TMessage tMsg = mars::stn::MessageDB::Instance()->GetMessageById(messageId);
  679. return convertProtoMessage(&tMsg);
  680. }
  681. - (WFCCMessage *)getMessageByUid:(long long)messageUid {
  682. mars::stn::TMessage tMsg = mars::stn::MessageDB::Instance()->GetMessageByUid(messageUid);
  683. return convertProtoMessage(&tMsg);
  684. }
  685. - (WFCCUnreadCount *)getUnreadCount:(WFCCConversation *)conversation {
  686. mars::stn::TUnreadCount tcount = mars::stn::MessageDB::Instance()->GetUnreadCount(conversation.type, [conversation.target UTF8String], conversation.line);
  687. return [WFCCUnreadCount countOf:tcount.unread mention:tcount.unreadMention mentionAll:tcount.unreadMentionAll];
  688. }
  689. - (WFCCUnreadCount *)getUnreadCount:(NSArray<NSNumber *> *)conversationTypes lines:(NSArray<NSNumber *> *)lines {
  690. std::list<int> types;
  691. std::list<int> ls;
  692. for (NSNumber *type in conversationTypes) {
  693. types.insert(types.end(), type.intValue);
  694. }
  695. for (NSNumber *line in lines) {
  696. ls.insert(ls.end(), line.intValue);
  697. }
  698. mars::stn::TUnreadCount tcount = mars::stn::MessageDB::Instance()->GetUnreadCount(types, ls);
  699. return [WFCCUnreadCount countOf:tcount.unread mention:tcount.unreadMention mentionAll:tcount.unreadMentionAll];
  700. }
  701. - (void)clearUnreadStatus:(WFCCConversation *)conversation {
  702. mars::stn::MessageDB::Instance()->ClearUnreadStatus(conversation.type, [conversation.target UTF8String], conversation.line);
  703. }
  704. - (void)clearUnreadStatus:(NSArray<NSNumber *> *)conversationTypes
  705. lines:(NSArray<NSNumber *> *)lines {
  706. std::list<int> types;
  707. std::list<int> ls;
  708. for (NSNumber *type in conversationTypes) {
  709. types.insert(types.end(), type.intValue);
  710. }
  711. for (NSNumber *line in lines) {
  712. ls.insert(ls.end(), line.intValue);
  713. }
  714. mars::stn::MessageDB::Instance()->ClearUnreadStatus(types, ls);
  715. }
  716. - (void)clearAllUnreadStatus {
  717. mars::stn::MessageDB::Instance()->ClearAllUnreadStatus();
  718. }
  719. - (void)setMediaMessagePlayed:(long)messageId {
  720. WFCCMessage *message = [self getMessage:messageId];
  721. if (!message) {
  722. return;
  723. }
  724. mars::stn::MessageDB::Instance()->updateMessageStatus(messageId, mars::stn::Message_Status_Played);
  725. }
  726. - (NSMutableDictionary<NSString *, NSNumber *> *)getConversationRead:(WFCCConversation *)conversation {
  727. std::map<std::string, int64_t> reads = mars::stn::MessageDB::Instance()->GetConversationRead((int)conversation.type, [conversation.target UTF8String], conversation.line);
  728. NSMutableDictionary *ret = [[NSMutableDictionary alloc] init];
  729. for (std::map<std::string, int64_t>::iterator it = reads.begin(); it != reads.end(); ++it) {
  730. [ret setValue:@(it->second) forKey:[NSString stringWithUTF8String:it->first.c_str()]];
  731. }
  732. return ret;
  733. }
  734. - (NSMutableDictionary<NSString *, NSNumber *> *)getMessageDelivery:(WFCCConversation *)conversation {
  735. std::map<std::string, int64_t> reads = mars::stn::MessageDB::Instance()->GetDelivery((int)conversation.type, [conversation.target UTF8String]);
  736. NSMutableDictionary *ret = [[NSMutableDictionary alloc] init];
  737. for (std::map<std::string, int64_t>::iterator it = reads.begin(); it != reads.end(); ++it) {
  738. [ret setValue:@(it->second) forKey:[NSString stringWithUTF8String:it->first.c_str()]];
  739. }
  740. return ret;
  741. }
  742. - (long long)getMessageDeliveryByUser:(NSString *)userId {
  743. return mars::stn::MessageDB::Instance()->GetDelivery([userId UTF8String]);
  744. }
  745. - (bool)updateMessage:(long)messageId status:(WFCCMessageStatus)status {
  746. WFCCMessage *message = [self getMessage:messageId];
  747. if (!message) {
  748. return NO;
  749. }
  750. mars::stn::MessageDB::Instance()->updateMessageStatus(messageId, (mars::stn::MessageStatus)status);
  751. return YES;
  752. }
  753. - (void)removeConversation:(WFCCConversation *)conversation clearMessage:(BOOL)clearMessage {
  754. mars::stn::MessageDB::Instance()->RemoveConversation(conversation.type, [conversation.target UTF8String], conversation.line, clearMessage);
  755. }
  756. - (void)clearMessages:(WFCCConversation *)conversation {
  757. mars::stn::MessageDB::Instance()->ClearMessages(conversation.type, [conversation.target UTF8String], conversation.line);
  758. }
  759. - (void)clearMessages:(WFCCConversation *)conversation before:(int64_t)before {
  760. mars::stn::MessageDB::Instance()->ClearMessages(conversation.type, conversation.target.length ? [conversation.target UTF8String] : "", conversation.line, before);
  761. }
  762. - (void)setConversation:(WFCCConversation *)conversation top:(BOOL)top
  763. success:(void(^)(void))successBlock
  764. error:(void(^)(int error_code))errorBlock {
  765. // mars::stn::MessageDB::Instance()->updateConversationIsTop(conversation.type, [conversation.target UTF8String], conversation.line, top);
  766. [self setUserSetting:(UserSettingScope)mars::stn::kUserSettingConversationTop key:[NSString stringWithFormat:@"%zd-%d-%@", conversation.type, conversation.line, conversation.target] value:top ? @"1" : @"0" success:successBlock error:errorBlock];
  767. }
  768. - (void)setConversation:(WFCCConversation *)conversation draft:(NSString *)draft {
  769. mars::stn::MessageDB::Instance()->updateConversationDraft((int)conversation.type, [conversation.target UTF8String], conversation.line, draft ? [draft UTF8String] : "");
  770. }
  771. - (void)setConversation:(WFCCConversation *)conversation
  772. timestamp:(long long)timestamp {
  773. mars::stn::MessageDB::Instance()->updateConversationTimestamp((int)conversation.type, [conversation.target UTF8String], conversation.line, timestamp);
  774. }
  775. class IMSearchUserCallback : public mars::stn::SearchUserCallback {
  776. private:
  777. void(^m_successBlock)(NSArray<WFCCUserInfo *> *machedUsers);
  778. void(^m_errorBlock)(int errorCode);
  779. public:
  780. IMSearchUserCallback(void(^successBlock)(NSArray<WFCCUserInfo *> *machedUsers), void(^errorBlock)(int errorCode)) : m_successBlock(successBlock), m_errorBlock(errorBlock) {}
  781. void onSuccess(const std::list<mars::stn::TUserInfo> &users, const std::string &keyword, int page) {
  782. NSMutableArray *outUsers = [[NSMutableArray alloc] initWithCapacity:users.size()];
  783. for(std::list<mars::stn::TUserInfo>::const_iterator it = users.begin(); it != users.end(); it++) {
  784. [outUsers addObject:convertUserInfo(*it)];
  785. }
  786. m_successBlock(outUsers);
  787. delete this;
  788. }
  789. void onFalure(int errorCode) {
  790. m_errorBlock(errorCode);
  791. delete this;
  792. }
  793. ~IMSearchUserCallback() {}
  794. };
  795. - (void)searchUser:(NSString *)keyword
  796. searchType:(WFCCSearchUserType)searchType
  797. page:(int)page
  798. success:(void(^)(NSArray<WFCCUserInfo *> *machedUsers))successBlock
  799. error:(void(^)(int errorCode))errorBlock {
  800. if (self.userSource) {
  801. [self.userSource searchUser:keyword searchType:searchType page:page success:successBlock error:errorBlock];
  802. return;
  803. }
  804. mars::stn::searchUser([keyword UTF8String], searchType, page, new IMSearchUserCallback(successBlock, errorBlock));
  805. }
  806. - (BOOL)isMyFriend:(NSString *)userId {
  807. return mars::stn::MessageDB::Instance()->isMyFriend([userId UTF8String]);
  808. }
  809. - (NSArray<NSString *> *)getMyFriendList:(BOOL)refresh {
  810. NSMutableArray *ret = [[NSMutableArray alloc] init];
  811. std::list<std::string> friendList = mars::stn::MessageDB::Instance()->getMyFriendList(refresh);
  812. for (std::list<std::string>::iterator it = friendList.begin(); it != friendList.end(); it++) {
  813. [ret addObject:[NSString stringWithUTF8String:(*it).c_str()]];
  814. }
  815. return ret;
  816. }
  817. - (NSArray<WFCCUserInfo *> *)searchFriends:(NSString *)keyword {
  818. std::list<mars::stn::TUserInfo> friends = mars::stn::MessageDB::Instance()->SearchFriends([keyword UTF8String], 50);
  819. NSMutableArray<WFCCUserInfo *> *ret = [[NSMutableArray alloc] init];
  820. for (std::list<mars::stn::TUserInfo>::iterator it = friends.begin(); it != friends.end(); it++) {
  821. WFCCUserInfo *userInfo = convertUserInfo(*it);
  822. if (userInfo) {
  823. [ret addObject:userInfo];
  824. }
  825. }
  826. return ret;
  827. }
  828. WFCCChannelInfo *convertProtoChannelInfo(const mars::stn::TChannelInfo &tci) {
  829. if (tci.channelId.empty()) {
  830. return nil;
  831. }
  832. WFCCChannelInfo *channelInfo = [[WFCCChannelInfo alloc] init];
  833. channelInfo.channelId = [NSString stringWithUTF8String:tci.channelId.c_str()];
  834. channelInfo.desc = [NSString stringWithUTF8String:tci.desc.c_str()];
  835. channelInfo.name = [NSString stringWithUTF8String:tci.name.c_str()];
  836. channelInfo.extra = [NSString stringWithUTF8String:tci.extra.c_str()];
  837. channelInfo.portrait = [NSString stringWithUTF8String:tci.portrait.c_str()];
  838. channelInfo.owner = [NSString stringWithUTF8String:tci.owner.c_str()];
  839. channelInfo.secret = [NSString stringWithUTF8String:tci.secret.c_str()];
  840. channelInfo.callback = [NSString stringWithUTF8String:tci.callback.c_str()];
  841. channelInfo.status = tci.status;
  842. channelInfo.updateDt = tci.updateDt;
  843. return channelInfo;
  844. }
  845. class IMCreateChannelCallback : public mars::stn::CreateChannelCallback {
  846. private:
  847. void(^m_successBlock)(WFCCChannelInfo *channelInfo);
  848. void(^m_errorBlock)(int error_code);
  849. public:
  850. IMCreateChannelCallback(void(^successBlock)(WFCCChannelInfo *channelInfo), void(^errorBlock)(int error_code)) : mars::stn::CreateChannelCallback(), m_successBlock(successBlock), m_errorBlock(errorBlock) {};
  851. void onSuccess(const mars::stn::TChannelInfo &channelInfo) {
  852. WFCCChannelInfo *ci = convertProtoChannelInfo(channelInfo);
  853. dispatch_async(dispatch_get_main_queue(), ^{
  854. if (m_successBlock) {
  855. m_successBlock(ci);
  856. }
  857. delete this;
  858. });
  859. }
  860. void onFalure(int errorCode) {
  861. dispatch_async(dispatch_get_main_queue(), ^{
  862. if (m_errorBlock) {
  863. m_errorBlock(errorCode);
  864. }
  865. delete this;
  866. });
  867. }
  868. virtual ~IMCreateChannelCallback() {
  869. m_successBlock = nil;
  870. m_errorBlock = nil;
  871. }
  872. };
  873. class IMSearchChannelCallback : public mars::stn::SearchChannelCallback {
  874. private:
  875. void(^m_successBlock)(NSArray<WFCCChannelInfo *> *machedChannels);
  876. void(^m_errorBlock)(int errorCode);
  877. public:
  878. IMSearchChannelCallback(void(^successBlock)(NSArray<WFCCChannelInfo *> *machedUsers), void(^errorBlock)(int errorCode)) : m_successBlock(successBlock), m_errorBlock(errorBlock) {}
  879. void onSuccess(const std::list<mars::stn::TChannelInfo> &users, const std::string &keyword) {
  880. NSMutableArray *outUsers = [[NSMutableArray alloc] initWithCapacity:users.size()];
  881. for(std::list<mars::stn::TChannelInfo>::const_iterator it = users.begin(); it != users.end(); it++) {
  882. [outUsers addObject:convertProtoChannelInfo(*it)];
  883. }
  884. m_successBlock(outUsers);
  885. delete this;
  886. }
  887. void onFalure(int errorCode) {
  888. m_errorBlock(errorCode);
  889. delete this;
  890. }
  891. ~IMSearchChannelCallback() {}
  892. };
  893. WFCCGroupInfo *convertProtoGroupInfo(mars::stn::TGroupInfo tgi) {
  894. if (tgi.target.empty()) {
  895. return nil;
  896. }
  897. WFCCGroupInfo *groupInfo = [[WFCCGroupInfo alloc] init];
  898. groupInfo.type = (WFCCGroupType)tgi.type;
  899. groupInfo.target = [NSString stringWithUTF8String:tgi.target.c_str()];
  900. groupInfo.name = [NSString stringWithUTF8String:tgi.name.c_str()];
  901. groupInfo.extra = [NSString stringWithUTF8String:tgi.extra.c_str()];;
  902. groupInfo.portrait = [NSString stringWithUTF8String:tgi.portrait.c_str()];
  903. groupInfo.owner = [NSString stringWithUTF8String:tgi.owner.c_str()];
  904. groupInfo.memberCount = tgi.memberCount;
  905. groupInfo.mute = tgi.mute;
  906. groupInfo.joinType = tgi.joinType;
  907. groupInfo.privateChat = tgi.privateChat;
  908. groupInfo.searchable = tgi.searchable;
  909. groupInfo.historyMessage = tgi.historyMessage;
  910. groupInfo.maxMemberCount = tgi.maxMemberCount;
  911. return groupInfo;
  912. }
  913. - (NSArray<WFCCGroupSearchInfo *> *)searchGroups:(NSString *)keyword {
  914. std::list<mars::stn::TGroupSearchResult> groups = mars::stn::MessageDB::Instance()->SearchGroups([keyword UTF8String], 50);
  915. NSMutableArray<WFCCGroupSearchInfo *> *ret = [[NSMutableArray alloc] init];
  916. for (std::list<mars::stn::TGroupSearchResult>::iterator it = groups.begin(); it != groups.end(); it++) {
  917. WFCCGroupSearchInfo *searchGroupInfo = [[WFCCGroupSearchInfo alloc] init];
  918. searchGroupInfo.groupInfo = convertProtoGroupInfo(it->groupInfo);
  919. searchGroupInfo.marchType = it->marchedType;
  920. if (!it->marchedMemberNames.empty()) {
  921. NSMutableArray *members = [[NSMutableArray alloc] init];
  922. for (std::string name : it->marchedMemberNames) {
  923. [members addObject:[NSString stringWithUTF8String:name.c_str()]];
  924. }
  925. searchGroupInfo.marchedMemberNames = [members copy];
  926. }
  927. searchGroupInfo.keyword = keyword;
  928. [ret addObject:searchGroupInfo];
  929. }
  930. return ret;
  931. }
  932. - (NSArray<WFCCFriendRequest *> *)convertFriendRequest:(std::list<mars::stn::TFriendRequest>)tRequests {
  933. NSMutableArray *ret = [[NSMutableArray alloc] init];
  934. for (std::list<mars::stn::TFriendRequest>::iterator it = tRequests.begin(); it != tRequests.end(); it++) {
  935. WFCCFriendRequest *request = [[WFCCFriendRequest alloc] init];
  936. mars::stn::TFriendRequest *tRequest = &(*it);
  937. request.direction = tRequest->direction;
  938. request.target = [NSString stringWithUTF8String:tRequest->target.c_str()];
  939. request.reason = [NSString stringWithUTF8String:tRequest->reason.c_str()];
  940. request.status = tRequest->status;
  941. request.readStatus = tRequest->readStatus;
  942. request.timestamp = tRequest->timestamp;
  943. [ret addObject:request];
  944. }
  945. return ret;
  946. }
  947. - (void)loadFriendRequestFromRemote {
  948. mars::stn::loadFriendRequestFromRemote();
  949. }
  950. - (NSArray<WFCCFriendRequest *> *)getIncommingFriendRequest {
  951. std::list<mars::stn::TFriendRequest> tRequests = mars::stn::MessageDB::Instance()->getFriendRequest(1);
  952. return [self convertFriendRequest:tRequests];
  953. }
  954. - (NSArray<WFCCFriendRequest *> *)getOutgoingFriendRequest {
  955. std::list<mars::stn::TFriendRequest> tRequests = mars::stn::MessageDB::Instance()->getFriendRequest(0);
  956. return [self convertFriendRequest:tRequests];
  957. }
  958. - (void)clearUnreadFriendRequestStatus {
  959. mars::stn::MessageDB::Instance()->clearUnreadFriendRequestStatus();
  960. }
  961. - (int)getUnreadFriendRequestStatus {
  962. return mars::stn::MessageDB::Instance()->unreadFriendRequest();
  963. }
  964. - (void)sendFriendRequest:(NSString *)userId
  965. reason:(NSString *)reason
  966. success:(void(^)())successBlock
  967. error:(void(^)(int error_code))errorBlock {
  968. mars::stn::sendFriendRequest([userId UTF8String], [reason UTF8String], new IMGeneralOperationCallback(successBlock, errorBlock));
  969. }
  970. - (void)handleFriendRequest:(NSString *)userId
  971. accept:(BOOL)accpet
  972. extra:(NSString *)extra
  973. success:(void(^)())successBlock
  974. error:(void(^)(int error_code))errorBlock {
  975. mars::stn::handleFriendRequest([userId UTF8String], accpet, extra ? [extra UTF8String] : "", new IMGeneralOperationCallback(successBlock, errorBlock));
  976. }
  977. - (void)deleteFriend:(NSString *)userId
  978. success:(void(^)())successBlock
  979. error:(void(^)(int error_code))errorBlock {
  980. mars::stn::deleteFriend([userId UTF8String], new IMGeneralOperationCallback(successBlock, errorBlock));
  981. }
  982. - (NSString *)getFriendAlias:(NSString *)friendId {
  983. std::string strAlias = mars::stn::MessageDB::Instance()->GetFriendAlias([friendId UTF8String]);
  984. return [NSString stringWithUTF8String:strAlias.c_str()];
  985. }
  986. - (void)setFriend:(NSString *)friendId
  987. alias:(NSString *)alias
  988. success:(void(^)(void))successBlock
  989. error:(void(^)(int error_code))errorBlock {
  990. mars::stn::setFriendAlias([friendId UTF8String], alias ? [alias UTF8String] : "", new IMGeneralOperationCallback(successBlock, errorBlock));
  991. }
  992. - (NSString *)getFriendExtra:(NSString *)friendId {
  993. std::string extra = mars::stn::MessageDB::Instance()->GetFriendExtra([friendId UTF8String]);
  994. return [NSString stringWithUTF8String:extra.c_str()];
  995. }
  996. - (BOOL)isBlackListed:(NSString *)userId {
  997. return mars::stn::MessageDB::Instance()->isBlackListed([userId UTF8String]);
  998. }
  999. - (NSArray<NSString *> *)getBlackList:(BOOL)refresh {
  1000. NSMutableArray *ret = [[NSMutableArray alloc] init];
  1001. std::list<std::string> friendList = mars::stn::MessageDB::Instance()->getBlackList(refresh);
  1002. for (std::list<std::string>::iterator it = friendList.begin(); it != friendList.end(); it++) {
  1003. [ret addObject:[NSString stringWithUTF8String:(*it).c_str()]];
  1004. }
  1005. return ret;
  1006. }
  1007. - (void)setBlackList:(NSString *)userId
  1008. isBlackListed:(BOOL)isBlackListed
  1009. success:(void(^)(void))successBlock
  1010. error:(void(^)(int error_code))errorBlock {
  1011. mars::stn::blackListRequest([userId UTF8String], isBlackListed, new IMGeneralOperationCallback(successBlock, errorBlock));
  1012. }
  1013. - (WFCCUserInfo *)getUserInfo:(NSString *)userId refresh:(BOOL)refresh {
  1014. return [self getUserInfo:userId inGroup:nil refresh:refresh];
  1015. }
  1016. - (WFCCUserInfo *)getUserInfo:(NSString *)userId inGroup:(NSString *)groupId refresh:(BOOL)refresh {
  1017. if (!userId) {
  1018. return nil;
  1019. }
  1020. if (self.userSource) {
  1021. return [self.userSource getUserInfo:userId refresh:refresh];
  1022. }
  1023. mars::stn::TUserInfo tui = mars::stn::MessageDB::Instance()->getUserInfo([userId UTF8String], groupId ? [groupId UTF8String] : "", refresh);
  1024. if (!tui.uid.empty()) {
  1025. WFCCUserInfo *userInfo = convertUserInfo(tui);
  1026. return userInfo;
  1027. }
  1028. return nil;
  1029. }
  1030. - (NSArray<WFCCUserInfo *> *)getUserInfos:(NSArray<NSString *> *)userIds inGroup:(NSString *)groupId {
  1031. if ([userIds count] == 0) {
  1032. return nil;
  1033. }
  1034. std::list<std::string> strIds;
  1035. for (NSString *userId in userIds) {
  1036. strIds.insert(strIds.end(), [userId UTF8String]);
  1037. }
  1038. std::list<mars::stn::TUserInfo> tuis = mars::stn::MessageDB::Instance()->getUserInfos(strIds, groupId ? [groupId UTF8String] : "");
  1039. NSMutableArray<WFCCUserInfo *> *ret = [[NSMutableArray alloc] init];
  1040. for (std::list<mars::stn::TUserInfo>::iterator it = tuis.begin(); it != tuis.end(); it++) {
  1041. WFCCUserInfo *userInfo = convertUserInfo(*it);
  1042. [ret addObject:userInfo];
  1043. }
  1044. return ret;
  1045. }
  1046. - (void)uploadMedia:(NSString *)fileName
  1047. mediaData:(NSData *)mediaData
  1048. mediaType:(WFCCMediaType)mediaType
  1049. success:(void(^)(NSString *remoteUrl))successBlock
  1050. progress:(void(^)(long uploaded, long total))progressBlock
  1051. error:(void(^)(int error_code))errorBlock {
  1052. mars::stn::uploadGeneralMedia(fileName == nil ? "" : [fileName UTF8String], std::string((char *)mediaData.bytes, mediaData.length), (int)mediaType, new GeneralUpdateMediaCallback(successBlock, progressBlock, errorBlock));
  1053. }
  1054. - (BOOL)syncUploadMedia:(NSString *)fileName
  1055. mediaData:(NSData *)mediaData
  1056. mediaType:(WFCCMediaType)mediaType
  1057. success:(void(^)(NSString *remoteUrl))successBlock
  1058. progress:(void(^)(long uploaded, long total))progressBlock
  1059. error:(void(^)(int error_code))errorBlock {
  1060. NSCondition *condition = [[NSCondition alloc] init];
  1061. __block BOOL success = NO;
  1062. [condition lock];
  1063. [[WFCCIMService sharedWFCIMService] uploadMedia:fileName mediaData:mediaData mediaType:mediaType success:^(NSString *remoteUrl) {
  1064. success = YES;
  1065. [condition lock];
  1066. [condition signal];
  1067. [condition unlock];
  1068. dispatch_async(dispatch_get_main_queue(), ^{
  1069. successBlock(remoteUrl);
  1070. });
  1071. } progress:^(long uploaded, long total) {
  1072. dispatch_async(dispatch_get_main_queue(), ^{
  1073. progressBlock(uploaded, total);
  1074. });
  1075. } error:^(int error_code) {
  1076. success = NO;
  1077. [condition lock];
  1078. [condition signal];
  1079. [condition unlock];
  1080. dispatch_async(dispatch_get_main_queue(), ^{
  1081. errorBlock(error_code);
  1082. });
  1083. }];
  1084. [condition wait];
  1085. [condition unlock];
  1086. return success;
  1087. }
  1088. -(void)modifyMyInfo:(NSDictionary<NSNumber */*ModifyMyInfoType*/, NSString *> *)values
  1089. success:(void(^)())successBlock
  1090. error:(void(^)(int error_code))errorBlock {
  1091. if (self.userSource) {
  1092. [self.userSource modifyMyInfo:values success:successBlock error:errorBlock];
  1093. return;
  1094. }
  1095. std::list<std::pair<int, std::string>> infos;
  1096. for(NSNumber *key in values.allKeys) {
  1097. infos.push_back(std::pair<int, std::string>([key intValue], [values[key] UTF8String]));
  1098. }
  1099. mars::stn::modifyMyInfo(infos, new IMGeneralOperationCallback(successBlock, errorBlock));
  1100. }
  1101. - (BOOL)isGlobalSlient {
  1102. NSString *strValue = [[WFCCIMService sharedWFCIMService] getUserSetting:UserSettingScope_Global_Silent key:@""];
  1103. return [strValue isEqualToString:@"1"];
  1104. }
  1105. - (void)setGlobalSlient:(BOOL)slient
  1106. success:(void(^)(void))successBlock
  1107. error:(void(^)(int error_code))errorBlock {
  1108. [[WFCCIMService sharedWFCIMService] setUserSetting:UserSettingScope_Global_Silent key:@"" value:slient?@"1":@"0" success:^{
  1109. if (successBlock) {
  1110. successBlock();
  1111. }
  1112. } error:^(int error_code) {
  1113. if (errorBlock) {
  1114. errorBlock(error_code);
  1115. }
  1116. }];
  1117. }
  1118. - (BOOL)isUserEnableReceipt {
  1119. NSString *strValue = [[WFCCIMService sharedWFCIMService] getUserSetting:UserSetting_DisableRecipt key:@""];
  1120. return ![strValue isEqualToString:@"1"];
  1121. }
  1122. - (void)setUserEnableReceipt:(BOOL)enable
  1123. success:(void(^)(void))successBlock
  1124. error:(void(^)(int error_code))errorBlock {
  1125. [[WFCCIMService sharedWFCIMService] setUserSetting:UserSetting_DisableRecipt key:@"" value:enable?@"0":@"1" success:^{
  1126. if (successBlock) {
  1127. successBlock();
  1128. }
  1129. } error:^(int error_code) {
  1130. if (errorBlock) {
  1131. errorBlock(error_code);
  1132. }
  1133. }];
  1134. }
  1135. - (BOOL)isHiddenNotificationDetail {
  1136. NSString *strValue = [[WFCCIMService sharedWFCIMService] getUserSetting:UserSettingScope_Hidden_Notification_Detail key:@""];
  1137. return [strValue isEqualToString:@"1"];
  1138. }
  1139. - (void)setHiddenNotificationDetail:(BOOL)hidden
  1140. success:(void(^)(void))successBlock
  1141. error:(void(^)(int error_code))errorBlock {
  1142. [[WFCCIMService sharedWFCIMService] setUserSetting:UserSettingScope_Hidden_Notification_Detail key:@"" value:hidden?@"1":@"0" success:^{
  1143. if (successBlock) {
  1144. successBlock();
  1145. }
  1146. } error:^(int error_code) {
  1147. if (errorBlock) {
  1148. errorBlock(error_code);
  1149. }
  1150. }];
  1151. }
  1152. //UserSettingScope_Hidden_Notification_Detail = 4,
  1153. - (BOOL)isHiddenGroupMemberName:(NSString *)groupId {
  1154. NSString *strValue = [[WFCCIMService sharedWFCIMService] getUserSetting:UserSettingScope_Group_Hide_Nickname key:groupId];
  1155. return [strValue isEqualToString:@"1"];
  1156. }
  1157. - (void)setHiddenGroupMemberName:(BOOL)hidden
  1158. group:(NSString *)groupId
  1159. success:(void(^)(void))successBlock
  1160. error:(void(^)(int error_code))errorBlock {
  1161. [[WFCCIMService sharedWFCIMService] setUserSetting:UserSettingScope_Group_Hide_Nickname key:groupId value:hidden?@"1":@"0" success:^{
  1162. if (successBlock) {
  1163. successBlock();
  1164. }
  1165. } error:^(int error_code) {
  1166. if (errorBlock) {
  1167. errorBlock(error_code);
  1168. }
  1169. }];
  1170. }
  1171. //UserSettingScope_Group_Hide_Nickname = 5,
  1172. - (BOOL)deleteMessage:(long)messageId {
  1173. return mars::stn::MessageDB::Instance()->DeleteMessage(messageId) > 0;
  1174. }
  1175. - (NSArray<WFCCConversationSearchInfo *> *)searchConversation:(NSString *)keyword inConversation:(NSArray<NSNumber *> *)conversationTypes lines:(NSArray<NSNumber *> *)lines {
  1176. if (keyword.length == 0) {
  1177. return nil;
  1178. }
  1179. std::list<int> types;
  1180. std::list<int> ls;
  1181. for (NSNumber *type in conversationTypes) {
  1182. types.insert(types.end(), type.intValue);
  1183. }
  1184. for (NSNumber *line in lines) {
  1185. ls.insert(ls.end(), line.intValue);
  1186. }
  1187. if(lines.count == 0) {
  1188. ls.insert(ls.end(), 0);
  1189. }
  1190. std::list<mars::stn::TConversationSearchresult> tresult = mars::stn::MessageDB::Instance()->SearchConversations(types, ls, [keyword UTF8String], 50);
  1191. NSMutableArray *results = [[NSMutableArray alloc] init];
  1192. for (std::list<mars::stn::TConversationSearchresult>::iterator it = tresult.begin(); it != tresult.end(); it++) {
  1193. WFCCConversationSearchInfo *info = [[WFCCConversationSearchInfo alloc] init];
  1194. [results addObject:info];
  1195. info.conversation = [[WFCCConversation alloc] init];
  1196. info.conversation.type = (WFCCConversationType)(it->conversationType);
  1197. info.conversation.target = [NSString stringWithUTF8String:it->target.c_str()];
  1198. info.conversation.line = it->line;
  1199. info.marchedCount = it->marchedCount;
  1200. info.marchedMessage = convertProtoMessage(&(it->marchedMessage));
  1201. info.keyword = keyword;
  1202. }
  1203. return results;
  1204. }
  1205. - (NSArray<WFCCMessage *> *)searchMessage:(WFCCConversation *)conversation keyword:(NSString *)keyword {
  1206. if (keyword.length == 0) {
  1207. return nil;
  1208. }
  1209. std::list<mars::stn::TMessage> tmessages = mars::stn::MessageDB::Instance()->SearchMessages(conversation.type, [conversation.target UTF8String], conversation.line, [keyword UTF8String], 500);
  1210. return convertProtoMessageList(tmessages, YES);
  1211. }
  1212. - (void)createGroup:(NSString *)groupId
  1213. name:(NSString *)groupName
  1214. portrait:(NSString *)groupPortrait
  1215. type:(WFCCGroupType)type
  1216. members:(NSArray *)groupMembers
  1217. notifyLines:(NSArray<NSNumber *> *)notifyLines
  1218. notifyContent:(WFCCMessageContent *)notifyContent
  1219. success:(void(^)(NSString *groupId))successBlock
  1220. error:(void(^)(int error_code))errorBlock {
  1221. std::list<std::string> memberList;
  1222. for (NSString *member in groupMembers) {
  1223. memberList.push_back([member UTF8String]);
  1224. }
  1225. mars::stn::TMessageContent tcontent;
  1226. fillTMessageContent(tcontent, notifyContent);
  1227. std::list<int> lines;
  1228. for (NSNumber *number in notifyLines) {
  1229. lines.push_back([number intValue]);
  1230. }
  1231. mars::stn::createGroup(groupId == nil ? "" : [groupId UTF8String], groupName == nil ? "" : [groupName UTF8String], groupPortrait == nil ? "" : [groupPortrait UTF8String], type, memberList, lines, tcontent, new IMCreateGroupCallback(successBlock, errorBlock));
  1232. }
  1233. - (void)addMembers:(NSArray *)members
  1234. toGroup:(NSString *)groupId
  1235. notifyLines:(NSArray<NSNumber *> *)notifyLines
  1236. notifyContent:(WFCCMessageContent *)notifyContent
  1237. success:(void(^)())successBlock
  1238. error:(void(^)(int error_code))errorBlock {
  1239. std::list<std::string> memberList;
  1240. for (NSString *member in members) {
  1241. memberList.push_back([member UTF8String]);
  1242. }
  1243. mars::stn::TMessageContent tcontent;
  1244. fillTMessageContent(tcontent, notifyContent);
  1245. std::list<int> lines;
  1246. for (NSNumber *number in notifyLines) {
  1247. lines.push_back([number intValue]);
  1248. }
  1249. mars::stn::addMembers([groupId UTF8String], memberList, lines, tcontent, new IMGeneralOperationCallback(successBlock, errorBlock));
  1250. }
  1251. - (void)kickoffMembers:(NSArray *)members
  1252. fromGroup:(NSString *)groupId
  1253. notifyLines:(NSArray<NSNumber *> *)notifyLines
  1254. notifyContent:(WFCCMessageContent *)notifyContent
  1255. success:(void(^)())successBlock
  1256. error:(void(^)(int error_code))errorBlock {
  1257. std::list<std::string> memberList;
  1258. for (NSString *member in members) {
  1259. memberList.push_back([member UTF8String]);
  1260. }
  1261. mars::stn::TMessageContent tcontent;
  1262. fillTMessageContent(tcontent, notifyContent);
  1263. std::list<int> lines;
  1264. for (NSNumber *number in notifyLines) {
  1265. lines.push_back([number intValue]);
  1266. }
  1267. mars::stn::kickoffMembers([groupId UTF8String], memberList, lines, tcontent, new IMGeneralOperationCallback(successBlock, errorBlock));
  1268. }
  1269. - (void)quitGroup:(NSString *)groupId
  1270. notifyLines:(NSArray<NSNumber *> *)notifyLines
  1271. notifyContent:(WFCCMessageContent *)notifyContent
  1272. success:(void(^)())successBlock
  1273. error:(void(^)(int error_code))errorBlock {
  1274. mars::stn::TMessageContent tcontent;
  1275. fillTMessageContent(tcontent, notifyContent);
  1276. std::list<int> lines;
  1277. for (NSNumber *number in notifyLines) {
  1278. lines.push_back([number intValue]);
  1279. }
  1280. mars::stn::quitGroup([groupId UTF8String], lines, tcontent, new IMGeneralOperationCallback(successBlock, errorBlock));
  1281. }
  1282. - (void)dismissGroup:(NSString *)groupId
  1283. notifyLines:(NSArray<NSNumber *> *)notifyLines
  1284. notifyContent:(WFCCMessageContent *)notifyContent
  1285. success:(void(^)())successBlock
  1286. error:(void(^)(int error_code))errorBlock {
  1287. mars::stn::TMessageContent tcontent;
  1288. fillTMessageContent(tcontent, notifyContent);
  1289. std::list<int> lines;
  1290. for (NSNumber *number in notifyLines) {
  1291. lines.push_back([number intValue]);
  1292. }
  1293. mars::stn::dismissGroup([groupId UTF8String], lines, tcontent, new IMGeneralOperationCallback(successBlock, errorBlock));
  1294. }
  1295. - (void)modifyGroupInfo:(NSString *)groupId
  1296. type:(ModifyGroupInfoType)type
  1297. newValue:(NSString *)newValue
  1298. notifyLines:(NSArray<NSNumber *> *)notifyLines
  1299. notifyContent:(WFCCMessageContent *)notifyContent
  1300. success:(void(^)(void))successBlock
  1301. error:(void(^)(int error_code))errorBlock {
  1302. mars::stn::TMessageContent tcontent;
  1303. fillTMessageContent(tcontent, notifyContent);
  1304. std::list<int> lines;
  1305. for (NSNumber *number in notifyLines) {
  1306. lines.push_back([number intValue]);
  1307. }
  1308. mars::stn::modifyGroupInfo([groupId UTF8String], (int)type, [newValue UTF8String], lines, tcontent, new IMGeneralOperationCallback(successBlock, errorBlock));
  1309. }
  1310. - (void)modifyGroupAlias:(NSString *)groupId
  1311. alias:(NSString *)newAlias
  1312. notifyLines:(NSArray<NSNumber *> *)notifyLines
  1313. notifyContent:(WFCCMessageContent *)notifyContent
  1314. success:(void(^)())successBlock
  1315. error:(void(^)(int error_code))errorBlock {
  1316. mars::stn::TMessageContent tcontent;
  1317. fillTMessageContent(tcontent, notifyContent);
  1318. std::list<int> lines;
  1319. for (NSNumber *number in notifyLines) {
  1320. lines.push_back([number intValue]);
  1321. }
  1322. mars::stn::modifyGroupAlias([groupId UTF8String], [newAlias UTF8String], lines, tcontent, new IMGeneralOperationCallback(successBlock, errorBlock));
  1323. }
  1324. - (NSArray<WFCCGroupMember *> *)getGroupMembers:(NSString *)groupId
  1325. forceUpdate:(BOOL)forceUpdate {
  1326. std::list<mars::stn::TGroupMember> tmembers = mars::stn::MessageDB::Instance()->GetGroupMembers([groupId UTF8String], forceUpdate);
  1327. NSMutableArray *output = [[NSMutableArray alloc] init];
  1328. for(std::list<mars::stn::TGroupMember>::iterator it = tmembers.begin(); it != tmembers.end(); it++) {
  1329. WFCCGroupMember *member = [WFCCGroupMember new];
  1330. member.groupId = [NSString stringWithUTF8String:it->groupId.c_str()];
  1331. member.memberId = [NSString stringWithUTF8String:it->memberId.c_str()];
  1332. member.alias = [NSString stringWithUTF8String:it->alias.c_str()];
  1333. member.type = (WFCCGroupMemberType)it->type;
  1334. member.createTime = it->createDt;
  1335. [output addObject:member];
  1336. }
  1337. return output;
  1338. }
  1339. - (WFCCGroupMember *)getGroupMember:(NSString *)groupId
  1340. memberId:(NSString *)memberId {
  1341. if (!groupId || !memberId) {
  1342. return nil;
  1343. }
  1344. mars::stn::TGroupMember tmember = mars::stn::MessageDB::Instance()->GetGroupMember([groupId UTF8String], [memberId UTF8String]);
  1345. if (tmember.memberId == [memberId UTF8String]) {
  1346. WFCCGroupMember *member = [WFCCGroupMember new];
  1347. member.groupId = groupId;
  1348. member.memberId = memberId;
  1349. member.alias = [NSString stringWithUTF8String:tmember.alias.c_str()];
  1350. member.type = (WFCCGroupMemberType)tmember.type;
  1351. member.createTime = tmember.createDt;
  1352. return member;
  1353. }
  1354. return nil;
  1355. }
  1356. - (void)transferGroup:(NSString *)groupId
  1357. to:(NSString *)newOwner
  1358. notifyLines:(NSArray<NSNumber *> *)notifyLines
  1359. notifyContent:(WFCCMessageContent *)notifyContent
  1360. success:(void(^)())successBlock
  1361. error:(void(^)(int error_code))errorBlock {
  1362. mars::stn::TMessageContent tcontent;
  1363. fillTMessageContent(tcontent, notifyContent);
  1364. std::list<int> lines;
  1365. for (NSNumber *number in notifyLines) {
  1366. lines.push_back([number intValue]);
  1367. }
  1368. mars::stn::transferGroup([groupId UTF8String], [newOwner UTF8String], lines, tcontent, new IMGeneralOperationCallback(successBlock, errorBlock));
  1369. }
  1370. - (void)setGroupManager:(NSString *)groupId
  1371. isSet:(BOOL)isSet
  1372. memberIds:(NSArray<NSString *> *)memberIds
  1373. notifyLines:(NSArray<NSNumber *> *)notifyLines
  1374. notifyContent:(WFCCMessageContent *)notifyContent
  1375. success:(void(^)(void))successBlock
  1376. error:(void(^)(int error_code))errorBlock {
  1377. mars::stn::TMessageContent tcontent;
  1378. fillTMessageContent(tcontent, notifyContent);
  1379. std::list<int> lines;
  1380. for (NSNumber *number in notifyLines) {
  1381. lines.push_back([number intValue]);
  1382. }
  1383. std::list<std::string> memberList;
  1384. for (NSString *member in memberIds) {
  1385. memberList.push_back([member UTF8String]);
  1386. }
  1387. mars::stn::SetGroupManager([groupId UTF8String], memberList, isSet, lines, tcontent, new IMGeneralOperationCallback(successBlock, errorBlock));
  1388. }
  1389. - (void)muteGroupMember:(NSString *)groupId
  1390. isSet:(BOOL)isSet
  1391. memberIds:(NSArray<NSString *> *)memberIds
  1392. notifyLines:(NSArray<NSNumber *> *)notifyLines
  1393. notifyContent:(WFCCMessageContent *)notifyContent
  1394. success:(void(^)(void))successBlock
  1395. error:(void(^)(int error_code))errorBlock {
  1396. mars::stn::TMessageContent tcontent;
  1397. fillTMessageContent(tcontent, notifyContent);
  1398. std::list<int> lines;
  1399. for (NSNumber *number in notifyLines) {
  1400. lines.push_back([number intValue]);
  1401. }
  1402. std::list<std::string> memberList;
  1403. for (NSString *member in memberIds) {
  1404. memberList.push_back([member UTF8String]);
  1405. }
  1406. mars::stn::MuteGroupMember([groupId UTF8String], memberList, isSet, lines, tcontent, new IMGeneralOperationCallback(successBlock, errorBlock));
  1407. }
  1408. - (NSArray<NSString *> *)getFavGroups {
  1409. NSDictionary *favGroupDict = [[WFCCIMService sharedWFCIMService] getUserSettings:UserSettingScope_Favourite_Group];
  1410. NSMutableArray *ids = [[NSMutableArray alloc] init];
  1411. [favGroupDict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
  1412. if ([obj isEqualToString:@"1"]) {
  1413. [ids addObject:key];
  1414. }
  1415. }];
  1416. return ids;
  1417. }
  1418. - (BOOL)isFavGroup:(NSString *)groupId {
  1419. NSString *strValue = [[WFCCIMService sharedWFCIMService] getUserSetting:UserSettingScope_Favourite_Group key:groupId];
  1420. if ([strValue isEqualToString:@"1"]) {
  1421. return YES;
  1422. }
  1423. return NO;
  1424. }
  1425. - (void)setFavGroup:(NSString *)groupId fav:(BOOL)fav success:(void(^)(void))successBlock error:(void(^)(int errorCode))errorBlock {
  1426. [[WFCCIMService sharedWFCIMService] setUserSetting:UserSettingScope_Favourite_Group key:groupId value:fav? @"1" : @"0" success:successBlock error:errorBlock];
  1427. }
  1428. - (WFCCGroupInfo *)getGroupInfo:(NSString *)groupId refresh:(BOOL)refresh {
  1429. if (!groupId) {
  1430. return nil;
  1431. }
  1432. mars::stn::TGroupInfo tgi = mars::stn::MessageDB::Instance()->GetGroupInfo([groupId UTF8String], refresh);
  1433. return convertProtoGroupInfo(tgi);
  1434. }
  1435. - (NSString *)getUserSetting:(UserSettingScope)scope key:(NSString *)key {
  1436. if (!key) {
  1437. key = @"";
  1438. }
  1439. std::string str = mars::stn::MessageDB::Instance()->GetUserSetting(scope, [key UTF8String]);
  1440. return [NSString stringWithUTF8String:str.c_str()];
  1441. }
  1442. - (NSDictionary<NSString *, NSString *> *)getUserSettings:(UserSettingScope)scope {
  1443. std::map<std::string, std::string> settings = mars::stn::MessageDB::Instance()->GetUserSettings(scope);
  1444. NSMutableDictionary *result = [[NSMutableDictionary alloc] init];
  1445. for (std::map<std::string, std::string>::iterator it = settings.begin() ; it != settings.end(); it++) {
  1446. NSString *key = [NSString stringWithUTF8String:it->first.c_str()];
  1447. NSString *value = [NSString stringWithUTF8String:it->second.c_str()];
  1448. [result setObject:value forKey:key];
  1449. }
  1450. return result;
  1451. }
  1452. - (void)setUserSetting:(UserSettingScope)scope key:(NSString *)key value:(NSString *)value
  1453. success:(void(^)())successBlock
  1454. error:(void(^)(int error_code))errorBlock {
  1455. mars::stn::modifyUserSetting(scope, [key UTF8String], [value UTF8String], new IMGeneralOperationCallback(successBlock, errorBlock));
  1456. }
  1457. - (void)setConversation:(WFCCConversation *)conversation silent:(BOOL)silent
  1458. success:(void(^)())successBlock
  1459. error:(void(^)(int error_code))errorBlock {
  1460. [self setUserSetting:(UserSettingScope)mars::stn::kUserSettingConversationSilent key:[NSString stringWithFormat:@"%zd-%d-%@", conversation.type, conversation.line, conversation.target] value:silent ? @"1" : @"0" success:successBlock error:errorBlock];
  1461. }
  1462. - (WFCCMessageContent *)messageContentFromPayload:(WFCCMessagePayload *)payload {
  1463. int contenttype = payload.contentType;
  1464. Class contentClass = self.MessageContentMaps[@(contenttype)];
  1465. if (contentClass != nil) {
  1466. id messageInstance = [[contentClass alloc] init];
  1467. if ([contentClass conformsToProtocol:@protocol(WFCCMessageContent)]) {
  1468. if ([messageInstance respondsToSelector:@selector(decode:)]) {
  1469. [messageInstance performSelector:@selector(decode:)
  1470. withObject:payload];
  1471. }
  1472. }
  1473. return messageInstance;
  1474. }
  1475. WFCCUnknownMessageContent *unknownMsg = [[WFCCUnknownMessageContent alloc] init];
  1476. [unknownMsg decode:payload];
  1477. return unknownMsg;
  1478. }
  1479. - (WFCCMessage *)insert:(WFCCConversation *)conversation
  1480. sender:(NSString *)sender
  1481. content:(WFCCMessageContent *)content
  1482. status:(WFCCMessageStatus)status
  1483. notify:(BOOL)notify
  1484. serverTime:(long long)serverTime {
  1485. WFCCMessage *message = [[WFCCMessage alloc] init];
  1486. message.conversation = conversation;
  1487. message.content = content;
  1488. mars::stn::TMessage tmsg;
  1489. fillTMessage(tmsg, conversation, content);
  1490. if(status >= Message_Status_Unread) {
  1491. tmsg.direction = 1;
  1492. if(conversation.type == Single_Type) {
  1493. tmsg.from = [conversation.target UTF8String];
  1494. } else {
  1495. tmsg.from = [sender UTF8String];
  1496. }
  1497. }
  1498. tmsg.status = (mars::stn::MessageStatus)status;
  1499. if(serverTime > 0) {
  1500. tmsg.timestamp = serverTime;
  1501. }
  1502. long msgId = mars::stn::MessageDB::Instance()->InsertMessage(tmsg);
  1503. message.messageId = msgId;
  1504. message.fromUser = sender;
  1505. if (notify) {
  1506. [[WFCCNetworkService sharedInstance].receiveMessageDelegate onReceiveMessage:@[message] hasMore:NO];
  1507. }
  1508. return message;
  1509. }
  1510. - (void)updateMessage:(long)messageId
  1511. content:(WFCCMessageContent *)content {
  1512. mars::stn::TMessageContent tmc;
  1513. fillTMessageContent(tmc, content);
  1514. mars::stn::MessageDB::Instance()->UpdateMessageContent(messageId, tmc);
  1515. }
  1516. - (void)registerMessageContent:(Class)contentClass {
  1517. int contenttype;
  1518. if (class_getClassMethod(contentClass, @selector(getContentType))) {
  1519. contenttype = [contentClass getContentType];
  1520. self.MessageContentMaps[@(contenttype)] = contentClass;
  1521. int contentflag = [contentClass getContentFlags];
  1522. mars::stn::MessageDB::Instance()->RegisterMessageFlag(contenttype, contentflag);
  1523. } else {
  1524. return;
  1525. }
  1526. }
  1527. - (void)joinChatroom:(NSString *)chatroomId
  1528. success:(void(^)(void))successBlock
  1529. error:(void(^)(int error_code))errorBlock {
  1530. mars::stn::joinChatroom([chatroomId UTF8String], new IMGeneralOperationCallback(successBlock, errorBlock));
  1531. }
  1532. - (void)quitChatroom:(NSString *)chatroomId
  1533. success:(void(^)(void))successBlock
  1534. error:(void(^)(int error_code))errorBlock {
  1535. mars::stn::quitChatroom([chatroomId UTF8String], new IMGeneralOperationCallback(successBlock, errorBlock));
  1536. }
  1537. - (void)getChatroomInfo:(NSString *)chatroomId
  1538. upateDt:(long long)updateDt
  1539. success:(void(^)(WFCCChatroomInfo *chatroomInfo))successBlock
  1540. error:(void(^)(int error_code))errorBlock {
  1541. mars::stn::getChatroomInfo([chatroomId UTF8String], updateDt, new IMGetChatroomInfoCallback(chatroomId, successBlock, errorBlock));
  1542. }
  1543. - (void)getChatroomMemberInfo:(NSString *)chatroomId
  1544. maxCount:(int)maxCount
  1545. success:(void(^)(WFCCChatroomMemberInfo *memberInfo))successBlock
  1546. error:(void(^)(int error_code))errorBlock {
  1547. if (maxCount <= 0) {
  1548. maxCount = 30;
  1549. }
  1550. mars::stn::getChatroomMemberInfo([chatroomId UTF8String], maxCount, new IMGetChatroomMemberInfoCallback(successBlock, errorBlock));
  1551. }
  1552. - (void)createChannel:(NSString *)channelName
  1553. portrait:(NSString *)channelPortrait
  1554. status:(int)status
  1555. desc:(NSString *)desc
  1556. extra:(NSString *)extra
  1557. success:(void(^)(WFCCChannelInfo *channelInfo))successBlock
  1558. error:(void(^)(int error_code))errorBlock {
  1559. if (!extra) {
  1560. extra = @"";
  1561. }
  1562. mars::stn::createChannel("", [channelName UTF8String], [channelPortrait UTF8String], status, [desc UTF8String], [extra UTF8String], "", "", new IMCreateChannelCallback(successBlock, errorBlock));
  1563. }
  1564. - (void)destoryChannel:(NSString *)channelId
  1565. success:(void(^)(void))successBlock
  1566. error:(void(^)(int error_code))errorBlock {
  1567. mars::stn::destoryChannel([channelId UTF8String], new IMGeneralOperationCallback(successBlock, errorBlock));
  1568. }
  1569. - (WFCCChannelInfo *)getChannelInfo:(NSString *)channelId
  1570. refresh:(BOOL)refresh {
  1571. mars::stn::TChannelInfo tgi = mars::stn::MessageDB::Instance()->GetChannelInfo([channelId UTF8String], refresh);
  1572. return convertProtoChannelInfo(tgi);
  1573. }
  1574. - (void)modifyChannelInfo:(NSString *)channelId
  1575. type:(ModifyChannelInfoType)type
  1576. newValue:(NSString *)newValue
  1577. success:(void(^)(void))successBlock
  1578. error:(void(^)(int error_code))errorBlock {
  1579. mars::stn::modifyChannelInfo([channelId UTF8String], type, [newValue UTF8String], new IMGeneralOperationCallback(successBlock, errorBlock));
  1580. }
  1581. - (void)searchChannel:(NSString *)keyword success:(void(^)(NSArray<WFCCChannelInfo *> *machedChannels))successBlock error:(void(^)(int errorCode))errorBlock {
  1582. mars::stn::searchChannel([keyword UTF8String], YES, new IMSearchChannelCallback(successBlock, errorBlock));
  1583. }
  1584. - (BOOL)isListenedChannel:(NSString *)channelId {
  1585. if([@"1" isEqualToString:[self getUserSetting:UserSettingScope_Listened_Channel key:channelId]]) {
  1586. return YES;
  1587. }
  1588. return NO;
  1589. }
  1590. - (void)listenChannel:(NSString *)channelId listen:(BOOL)listen success:(void(^)(void))successBlock error:(void(^)(int errorCode))errorBlock {
  1591. mars::stn::listenChannel([channelId UTF8String], listen, new IMGeneralOperationCallback(successBlock, errorBlock));
  1592. }
  1593. - (NSArray<NSString *> *)getMyChannels {
  1594. NSDictionary *myChannelDict = [[WFCCIMService sharedWFCIMService] getUserSettings:UserSettingScope_My_Channel];
  1595. NSMutableArray *ids = [[NSMutableArray alloc] init];
  1596. [myChannelDict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
  1597. if ([obj isEqualToString:@"1"]) {
  1598. [ids addObject:key];
  1599. }
  1600. }];
  1601. return ids;
  1602. }
  1603. - (NSArray<NSString *> *)getListenedChannels {
  1604. NSDictionary *myChannelDict = [[WFCCIMService sharedWFCIMService] getUserSettings:UserSettingScope_Listened_Channel];
  1605. NSMutableArray *ids = [[NSMutableArray alloc] init];
  1606. [myChannelDict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
  1607. if ([obj isEqualToString:@"1"]) {
  1608. [ids addObject:key];
  1609. }
  1610. }];
  1611. return ids;
  1612. }
  1613. - (NSArray<WFCCPCOnlineInfo *> *)getPCOnlineInfos {
  1614. NSString *pcOnline = [self getUserSetting:UserSettingScope_PC_Online key:@"PC"];
  1615. NSString *webOnline = [self getUserSetting:UserSettingScope_PC_Online key:@"Web"];
  1616. NSString *wxOnline = [self getUserSetting:UserSettingScope_PC_Online key:@"WX"];
  1617. NSMutableArray *output = [[NSMutableArray alloc] init];
  1618. if (pcOnline.length) {
  1619. [output addObject:[WFCCPCOnlineInfo infoFromStr:pcOnline withType:PC_Online]];
  1620. }
  1621. if (webOnline.length) {
  1622. [output addObject:[WFCCPCOnlineInfo infoFromStr:webOnline withType:Web_Online]];
  1623. }
  1624. if (wxOnline.length) {
  1625. [output addObject:[WFCCPCOnlineInfo infoFromStr:wxOnline withType:WX_Online]];
  1626. }
  1627. return output;
  1628. }
  1629. - (void)kickoffPCClient:(NSString *)pcClientId
  1630. success:(void(^)(void))successBlock
  1631. error:(void(^)(int error_code))errorBlock {
  1632. mars::stn::KickoffPCClient([pcClientId UTF8String], new IMGeneralOperationCallback(successBlock, errorBlock));
  1633. }
  1634. - (void)getAuthorizedMediaUrl:(WFCCMediaType)mediaType
  1635. mediaPath:(NSString *)mediaPath
  1636. success:(void(^)(NSString *authorizedUrl))successBlock
  1637. error:(void(^)(int error_code))errorBlock {
  1638. mars::stn::getAuthorizedMediaUrl((int)mediaType, [mediaPath UTF8String], new IMGeneralStringCallback(successBlock, errorBlock));
  1639. }
  1640. - (NSString *)imageThumbPara {
  1641. std::string cstr = mars::stn::GetImageThumbPara();
  1642. if (cstr.empty()) {
  1643. return nil;
  1644. }
  1645. return [NSString stringWithUTF8String:cstr.c_str()];
  1646. }
  1647. - (long)insertMessage:(WFCCMessage *)message {
  1648. mars::stn::TMessage tmsg;
  1649. fillTMessage(tmsg, message.conversation, message.content);
  1650. if(message.status >= Message_Status_Unread) {
  1651. tmsg.direction = 1;
  1652. }
  1653. tmsg.from = [message.fromUser UTF8String];
  1654. tmsg.status = (mars::stn::MessageStatus)message.status;
  1655. tmsg.timestamp = message.serverTime;
  1656. long msgId = mars::stn::MessageDB::Instance()->InsertMessage(tmsg);
  1657. message.messageId = msgId;
  1658. return msgId;
  1659. }
  1660. - (int)getMessageCount:(WFCCConversation *)conversation {
  1661. return mars::stn::MessageDB::Instance()->GetMsgTotalCount((int)conversation.type, [conversation.target UTF8String], conversation.line);
  1662. }
  1663. - (BOOL)beginTransaction {
  1664. return mars::stn::MessageDB::Instance()->BeginTransaction();
  1665. }
  1666. - (void)commitTransaction {
  1667. mars::stn::MessageDB::Instance()->CommitTransaction();
  1668. }
  1669. - (BOOL)isCommercialServer {
  1670. return mars::stn::IsCommercialServer() == true;
  1671. }
  1672. - (BOOL)isReceiptEnabled {
  1673. return mars::stn::IsReceiptEnabled() == true;
  1674. }
  1675. @end