WFCCIMService.mm 94 KB

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