Forráskód Böngészése

1.重置SDK
2.处理输入中...

Steven 5 hónapja
szülő
commit
3dbe84f629

+ 5 - 1
KulexiuForStudent/KulexiuForStudent/Common/Base/LoadingManager/KSHudLoagingManager.m

@@ -40,7 +40,9 @@
         self.loadingView.displayText = text;
         [self.loadingView showLoadingView];
         [self.loadingView cancelActionCallback:^{
-            cancel();
+            if (cancel) {
+                cancel();
+            }
         }];
     });
 }
@@ -49,6 +51,7 @@
     dispatch_main_async_safe(^{
         if (self->_loadingView) {
             [self.loadingView hideLoadingView];
+            self->_loadingView = nil;
         }
     });
 }
@@ -83,6 +86,7 @@
     dispatch_main_async_safe(^{
         if (self.HUD) {
             [self.HUD removeFromSuperview];
+            self->_HUD = nil;
         }
         [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
     });

+ 16 - 12
KulexiuForStudent/KulexiuForStudent/Module/Chat/Controller/KSChatConversationViewController.m

@@ -36,21 +36,25 @@
     self.vc.conversationData = self.conversation;
     [self addChildViewController:self.vc];
     [self.view addSubview:self.vc.view];
-}
-
-- (void)viewWillAppear:(BOOL)animated {
-    [super viewWillAppear:animated];
+    
+    // 关注变化
+    MJWeakSelf;
+    [[RACObserve(self.vc.conversationData, title) distinctUntilChanged] subscribeNext:^(NSString *title) {
+        [weakSelf allocTitle:title];
+    }];
 
-    //TODO: 页面appear 禁用
-   [[IQKeyboardManager sharedManager] setEnable:NO];
+    [[RACObserve(self.vc.conversationData, otherSideTyping) distinctUntilChanged] subscribeNext:^(id otherSideTyping) {
+      BOOL otherSideTypingFlag = [otherSideTyping boolValue];
+      if (!otherSideTypingFlag) {
+          [weakSelf.vc checkTitle:YES];
+      }
+      else {
+          NSString *typingText = [NSString stringWithFormat:@"%@...", TIMCommonLocalizableString(TUIKitTyping)];
+          [weakSelf allocTitle:typingText];
+      }
+    }];
 }
 
-- (void)viewWillDisappear:(BOOL)animated {
-    [super viewWillDisappear:animated];
-
-    //TODO: 页面Disappear 启用
-   [[IQKeyboardManager sharedManager] setEnable:YES];
-}
 
 - (void)clearConversation {
     

+ 12 - 0
KulexiuForStudent/KulexiuForStudent/Module/Chat/Controller/TXCustom/KSTXBaseChatViewController.m

@@ -27,7 +27,19 @@ static UIView *gCustomTopView;
 
 @implementation KSTXBaseChatViewController
 
+- (void)viewWillAppear:(BOOL)animated {
+    [super viewWillAppear:animated];
+    // 页面appear 禁用
+    [IQKeyboardManager sharedManager].enableAutoToolbar = NO;
+    [IQKeyboardManager sharedManager].enable = NO;
+}
 
+- (void)viewWillDisappear:(BOOL)animated {
+    [super viewWillDisappear:animated];
+    // 页面Disappear 启用
+    [IQKeyboardManager sharedManager].enableAutoToolbar = YES;
+    [IQKeyboardManager sharedManager].enable = YES;
+}
 
 #pragma mark - Life Cycle
 

+ 117 - 8
KulexiuForStudent/KulexiuForStudent/Module/Chat/Controller/TXCustom/KSTXC2CChatViewController.m

@@ -2,30 +2,139 @@
 //  KSTXC2CChatViewController.m
 //  KulexiuForTeacher
 //
-//  Created by 王智 on 2023/8/10.
+//  Created by 王智 on 2023/8/23.
 //
 
 #import "KSTXC2CChatViewController.h"
+#import "TUIBaseChatViewController+ProtectedAPI.h"
+#import "TUIChatConfig.h"
+#import "TUICloudCustomDataTypeCenter.h"
+#import "TUILinkCellData.h"
+#import "TUIMessageController.h"
+#import "TUIMessageDataProvider.h"
+
+#define kC2CTypingTime 30.0
 
 @interface KSTXC2CChatViewController ()
 
+// 如果满足了一次sendTypingBaseCondation 则当前会话未退出前都使用 sendTypingBaseCondationInVC
+// If one sendTypingBaseCondation is satisfied, sendTypingBaseCondationInVC is used until the current session exits
+
+@property(nonatomic, assign) BOOL sendTypingBaseCondationInVC;
+
+
 @end
 
 @implementation KSTXC2CChatViewController
 
+- (void)dealloc {
+    self.sendTypingBaseCondationInVC = NO;
+}
 - (void)viewDidLoad {
     [super viewDidLoad];
     // Do any additional setup after loading the view.
+    self.sendTypingBaseCondationInVC = NO;
+}
+
+#pragma mark - Override Methods
+- (NSString *)forwardTitleWithMyName:(NSString *)nameStr {
+    return [NSString stringWithFormat:TIMCommonLocalizableString(TUIKitRelayChatHistoryForSomebodyFormat), self.conversationData.title, nameStr];
 }
 
-/*
-#pragma mark - Navigation
+- (void)inputController:(TUIInputController *)inputController didSelectMoreCell:(TUIInputMoreCell *)cell {
+    [super inputController:inputController didSelectMoreCell:cell];
+}
+
+- (void)inputControllerBeginTyping:(TUIInputController *)inputController {
+    [super inputControllerBeginTyping:inputController];
 
-// In a storyboard-based application, you will often want to do a little preparation before navigation
-- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
-    // Get the new view controller using [segue destinationViewController].
-    // Pass the selected object to the new view controller.
+    [self sendTypingMsgByStatus:YES];
 }
-*/
 
+- (void)inputControllerEndTyping:(TUIInputController *)inputController {
+    [super inputControllerEndTyping:inputController];
+
+    [self sendTypingMsgByStatus:NO];
+}
+
+- (BOOL)sendTypingBaseCondation {
+    if (self.sendTypingBaseCondationInVC) {
+        return YES;
+    }
+
+    if ([self.messageController isKindOfClass:TUIMessageController.class]) {
+        TUIMessageController *vc = (TUIMessageController *)self.messageController;
+        NSDictionary *messageFeatureDic = (id)[vc.C2CIncomingLastMsg parseCloudCustomData:messageFeature];
+
+        if (messageFeatureDic && [messageFeatureDic isKindOfClass:[NSDictionary class]] && [messageFeatureDic.allKeys containsObject:@"needTyping"] &&
+            [messageFeatureDic.allKeys containsObject:@"version"]) {
+            BOOL needTyping = NO;
+
+            BOOL versionControl = NO;
+
+            BOOL timeControl = NO;
+
+            if ([messageFeatureDic[@"needTyping"] intValue] == 1) {
+                needTyping = YES;
+            }
+
+            if ([messageFeatureDic[@"version"] intValue] == 1) {
+                versionControl = YES;
+            }
+
+            CFTimeInterval current = [NSDate.new timeIntervalSince1970];
+            long currentTimeFloor = floor(current);
+            long otherSideTimeFloor = floor([vc.C2CIncomingLastMsg.timestamp timeIntervalSince1970]);
+            long interval = currentTimeFloor - otherSideTimeFloor;
+            if (interval <= kC2CTypingTime) {
+                timeControl = YES;
+            }
+
+            if (needTyping && versionControl && timeControl) {
+                self.sendTypingBaseCondationInVC = YES;
+                return YES;
+            }
+        }
+    }
+    return NO;
+}
+- (void)sendTypingMsgByStatus:(BOOL)editing {
+    // switch control
+    if (![TUIChatConfig defaultConfig].enableTypingStatus) {
+        return;
+    }
+
+    if (![self sendTypingBaseCondation]) {
+        return;
+    }
+
+    NSError *error = nil;
+    NSDictionary *param = @{
+        BussinessID : BussinessID_Typing,
+        @"typingStatus" : editing ? @1 : @0,
+        @"version" : @1,
+        @"userAction" : @14,
+        @"actionParam" : editing ? @"EIMAMSG_InputStatus_Ing" : @"EIMAMSG_InputStatus_End",
+    };
+    NSData *data = [NSJSONSerialization dataWithJSONObject:param options:0 error:&error];
+
+    V2TIMMessage *msg = [TUIMessageDataProvider getCustomMessageWithJsonData:data];
+    TUISendMessageAppendParams *appendParams = [[TUISendMessageAppendParams alloc] init];
+    appendParams.isSendPushInfo = NO;
+    appendParams.isOnlineUserOnly = YES;
+    appendParams.priority = V2TIM_PRIORITY_DEFAULT;
+
+    [TUIMessageDataProvider sendMessage:msg
+        toConversation:self.conversationData
+        appendParams:appendParams
+        Progress:^(uint32_t progress) {
+
+        }
+        SuccBlock:^{
+          NSLog(@"success");
+        }
+        FailBlock:^(int code, NSString *desc) {
+          NSLog(@"Fail");
+        }];
+}
 @end

+ 126 - 0
KulexiuForStudent/Pods/Pods.xcodeproj/xcuserdata/wangzhi.xcuserdatad/xcschemes/xcschememanagement.plist

@@ -8,221 +8,347 @@
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>1</integer>
 		</dict>
 		<key>AlipaySDK-iOS.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>2</integer>
 		</dict>
 		<key>Bugly.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>3</integer>
 		</dict>
 		<key>CHIPageControl.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>4</integer>
 		</dict>
 		<key>CocoaAsyncSocket.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>5</integer>
 		</dict>
 		<key>CocoaHTTPServer.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>6</integer>
 		</dict>
 		<key>CocoaLumberjack-CocoaLumberjackPrivacy.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>8</integer>
 		</dict>
 		<key>CocoaLumberjack.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>7</integer>
 		</dict>
 		<key>IQKeyboardManager.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>10</integer>
 		</dict>
 		<key>JCore.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>11</integer>
 		</dict>
 		<key>JPush.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>12</integer>
 		</dict>
 		<key>JXCategoryView.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>13</integer>
 		</dict>
 		<key>JXPagingView.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>14</integer>
 		</dict>
 		<key>MBProgressHUD.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>17</integer>
+		</dict>
+		<key>MJExtension-MJExtension.xcscheme</key>
+		<dict>
+			<key>orderHint</key>
+			<integer>19</integer>
 		</dict>
 		<key>MJExtension.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>18</integer>
+		</dict>
+		<key>MJRefresh-MJRefresh.Privacy.xcscheme</key>
+		<dict>
+			<key>orderHint</key>
+			<integer>21</integer>
 		</dict>
 		<key>MJRefresh.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>20</integer>
 		</dict>
 		<key>Masonry.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>16</integer>
 		</dict>
 		<key>NTLBridge.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>22</integer>
 		</dict>
 		<key>Pods-KulexiuForStudent-KulexiuForStudentUITests.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>24</integer>
 		</dict>
 		<key>Pods-KulexiuForStudent.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>23</integer>
 		</dict>
 		<key>Pods-KulexiuForStudentTests.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>25</integer>
 		</dict>
 		<key>QCloudCOSXML.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>27</integer>
 		</dict>
 		<key>QCloudCore.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>26</integer>
 		</dict>
 		<key>RSKImageCropper.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>30</integer>
 		</dict>
 		<key>Reachability.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>28</integer>
 		</dict>
 		<key>ReactiveObjC.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>29</integer>
+		</dict>
+		<key>SDWebImage-SDWebImage.xcscheme</key>
+		<dict>
+			<key>orderHint</key>
+			<integer>32</integer>
 		</dict>
 		<key>SDWebImage.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>31</integer>
 		</dict>
 		<key>SSZipArchive.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>34</integer>
 		</dict>
 		<key>SocketRocket.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>33</integer>
+		</dict>
+		<key>TIMCommon-TIMCommon_Privacy.xcscheme</key>
+		<dict>
+			<key>orderHint</key>
+			<integer>36</integer>
 		</dict>
 		<key>TIMCommon.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>35</integer>
 		</dict>
 		<key>TUIChat.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>37</integer>
 		</dict>
 		<key>TUIConversation.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>38</integer>
+		</dict>
+		<key>TUICore-TUICore_Privacy.xcscheme</key>
+		<dict>
+			<key>orderHint</key>
+			<integer>40</integer>
 		</dict>
 		<key>TUICore.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>39</integer>
 		</dict>
 		<key>TUIGroup.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>41</integer>
 		</dict>
 		<key>TUISearch.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>42</integer>
 		</dict>
 		<key>TXIMSDK_Plus_iOS.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
 		</dict>
+		<key>TXIMSDK_Plus_iOS.xcscheme_^#shared#^_</key>
+		<dict>
+			<key>orderHint</key>
+			<integer>51</integer>
+		</dict>
+		<key>TXIMSDK_Plus_iOS_XCFramework-TXIMSDK_Plus_iOS_XCFramework_Privacy.xcscheme</key>
+		<dict>
+			<key>orderHint</key>
+			<integer>44</integer>
+		</dict>
+		<key>TXIMSDK_Plus_iOS_XCFramework.xcscheme</key>
+		<dict>
+			<key>orderHint</key>
+			<integer>43</integer>
+		</dict>
 		<key>TXLiteAVSDK_Professional.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>45</integer>
 		</dict>
 		<key>TYCyclePagerView.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>46</integer>
 		</dict>
 		<key>TZImagePickerController.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>47</integer>
 		</dict>
 		<key>Whiteboard-Whiteboard.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>49</integer>
 		</dict>
 		<key>Whiteboard.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>48</integer>
 		</dict>
 		<key>YYModel.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>50</integer>
 		</dict>
 		<key>iOS-KS3SDK.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>9</integer>
 		</dict>
 		<key>lottie-ios.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
+			<key>orderHint</key>
+			<integer>15</integer>
 		</dict>
 	</dict>
 	<key>SuppressBuildableAutocreation</key>

+ 3 - 3
KulexiuForStudent/Pods/TUIChat/TUIChat/UI_Classic/Cell/Custom/TXChatMusicShareCell.m

@@ -32,7 +32,7 @@
     [self.container addSubview:self.musicContentView];
 
     [self.musicContentView mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.left.mas_equalTo(self.avatarView.mas_right).offset(10);
+        make.left.mas_equalTo(self.container.mas_left);
         make.top.mas_equalTo(self.avatarView.mas_top);
         make.width.mas_equalTo(260);
         make.bottom.mas_equalTo(self.container.mas_bottom).offset(-10);
@@ -44,7 +44,7 @@
     [self.musicContentView configWithSongName:data.songName type:data.chargeType authName:data.songAuth sendAvatar:data.teacherAvatar sendName:data.teacherName userId:data.innerMessage.sender tags:data.musicTagNames];
     if (data.direction == MsgDirectionIncoming) {
         [self.musicContentView mas_remakeConstraints:^(MASConstraintMaker *make) {
-            make.left.mas_equalTo(self.avatarView.mas_right).offset(10);
+            make.left.mas_equalTo(self.container.mas_left);
             make.top.mas_equalTo(self.avatarView.mas_top);
             make.width.mas_equalTo(260);
             make.bottom.mas_equalTo(self.container.mas_bottom).offset(-10);
@@ -52,7 +52,7 @@
     }
     else {
         [self.musicContentView mas_remakeConstraints:^(MASConstraintMaker *make) {
-            make.right.mas_equalTo(self.avatarView.mas_left).offset(-10);
+            make.right.mas_equalTo(self.container.mas_right);
             make.top.mas_equalTo(self.avatarView.mas_top);
             make.width.mas_equalTo(260);
             make.bottom.mas_equalTo(self.container.mas_bottom).offset(-10);

+ 7 - 7
KulexiuForStudent/Pods/TUIChat/TUIChat/UI_Classic/Cell/Custom/TXLiveShareCell.m

@@ -31,28 +31,28 @@
     
     [self.container addSubview:self.liveContentView];
     [self.liveContentView mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.right.mas_equalTo(self.avatarView.mas_right).offset(10);
-        make.top.mas_equalTo(self.avatarView.mas_top);
+        make.right.mas_equalTo(self.container.mas_right);
+        make.top.mas_equalTo(self.container.mas_top);
         make.width.mas_equalTo(260);
         make.bottom.mas_equalTo(self.container.mas_bottom).offset(-10);
     }];
-    
 }
+
 - (void)fillWithData:(TXLiveShareMessage *)data {
     [super fillWithData:data];
     [self.liveContentView configCellWithShareAvatar:data.teacherAvatar teacherName:data.teacherName liveDesc:data.liveDescMessage];
     if (data.direction == MsgDirectionIncoming) {
         [self.liveContentView mas_remakeConstraints:^(MASConstraintMaker *make) {
-            make.left.mas_equalTo(self.avatarView.mas_right).offset(10);
-            make.top.mas_equalTo(self.avatarView.mas_top);
+            make.left.mas_equalTo(self.container.mas_left);
+            make.top.mas_equalTo(self.container.mas_top);
             make.width.mas_equalTo(260);
             make.bottom.mas_equalTo(self.container.mas_bottom).offset(-10);
         }];
     }
     else {
         [self.liveContentView mas_remakeConstraints:^(MASConstraintMaker *make) {
-            make.right.mas_equalTo(self.avatarView.mas_left).offset(-10);
-            make.top.mas_equalTo(self.avatarView.mas_top);
+            make.right.mas_equalTo(self.container.mas_right);
+            make.top.mas_equalTo(self.container.mas_top);
             make.width.mas_equalTo(260);
             make.bottom.mas_equalTo(self.container.mas_bottom).offset(-10);
         }];

+ 2 - 0
KulexiuForStudent/Pods/TUIChat/TUIChat/UI_Classic/Chat/TUIBaseChatViewController.h

@@ -151,7 +151,9 @@
  * 获取聊天界面顶部的自定义视图。
  */
 + (UIView *)customTopView;
+
 // 新增
+- (void)checkTitle:(BOOL)force;
 // 多选
 - (void)onSelectMessageMenu:(NSInteger)menuType withData:(TUIMessageCellData *)data;