YMHomeController.m 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. //
  2. // YMHomeController.m
  3. // MSYOUPAI
  4. //
  5. // Created by You on 2024/4/18.
  6. // Copyright © 2024 MS. All rights reserved.
  7. //
  8. #import "YMHomeController.h"
  9. #import "YMHomePageViewModel.h"
  10. #import "YMHomePageBannerView.h"
  11. #import "YMHomeChildController.h"
  12. #import "YMSheetPopupView.h" // 添加底部弹窗组件导入
  13. #import "YMPopupView.h" // 添加弹窗管理器导入
  14. #import "YMGroupGreetingPopupView.h"
  15. #import "YMGroupGreetingViewModel.h"
  16. #import "YMSheetPopupView.h" // 添加底部弹窗组件导入
  17. #import "YMPopupView.h" // 添加弹窗管理器导入
  18. #define LZCategoryViewHeight 54.0f
  19. @interface YMHomeController ()<JXCategoryViewDelegate,JXCategoryListContainerViewDelegate>
  20. {
  21. dispatch_source_t _timer;
  22. }
  23. /// 首页VM
  24. @property (nonatomic, strong) YMHomePageViewModel *viewModel;
  25. @property (nonatomic, strong) YMGroupGreetingViewModel *groupGreetingViewModel;
  26. @property (nonatomic, strong) YMGroupGreetingPopupView *greetingView;
  27. @property (nonatomic, strong) YMPopupView *greetingPopupView;
  28. /// 首页Banner视图
  29. @property (nonatomic, strong) YMHomePageBannerView *bannerView;
  30. @property (nonatomic, strong) JXCategoryTitleView *categoryView;
  31. /// 搜索按钮
  32. @property (nonatomic, strong) UILabel *searchLabel;
  33. /// 搜索按钮
  34. @property (nonatomic, strong) UIButton *searchBtn;
  35. @property (nonatomic, strong) UIButton *zhidingBtn;
  36. /// banner视图高度
  37. @property (nonatomic, assign) CGFloat bannerViewHeight;
  38. @property (nonatomic, assign) NSInteger selectIndex;
  39. @end
  40. @implementation YMHomeController
  41. @dynamic viewModel;
  42. - (void)viewDidLoad {
  43. [super viewDidLoad];
  44. [self setNavHidden:YES];
  45. self.selectIndex = 0;
  46. [OCNotificationCenter addObserver:self selector:@selector(updateOnline) name:@"youpaifuserOnlineUpdate" object:nil];
  47. UIView *categoryBgV = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, KScreenWidth,[self preferredCategoryViewHeight])];
  48. [self.view addSubview:categoryBgV];
  49. // UIImageView *homeImgV = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, KScreenWidth,adapt(170))];
  50. // homeImgV.userInteractionEnabled = true;
  51. // homeImgV.image = [UIImage imageNamed:@"home_top_bg"];
  52. // [categoryBgV addSubview:homeImgV];
  53. JXCategoryTitleView *categoryView = [[JXCategoryTitleView alloc] initWithFrame:CGRectMake(0.0f, StatusBarHeight, KScreenWidth - 16 * 2.0f - 24, LZCategoryViewHeight)];
  54. categoryView.backgroundColor = [UIColor clearColor];
  55. categoryView.titles = self.titles;
  56. categoryView.delegate = self;
  57. categoryView.titleSelectedColor = DecColorFromRGBA(0, 0, 0, 1);
  58. categoryView.titleColor = DecColorFromRGBA(0, 0, 0, 0.5);
  59. categoryView.titleColorGradientEnabled = YES;
  60. categoryView.titleFont = LCFont(18.0f);
  61. categoryView.titleSelectedFont = LCBoldFont(18.0f);
  62. categoryView.cellWidth = adapt(53);
  63. categoryView.cellSpacing = 0;
  64. categoryView.contentEdgeInsetLeft = 15;
  65. categoryView.averageCellSpacingEnabled = NO;
  66. [categoryBgV addSubview:categoryView];
  67. self.categoryView = categoryView;
  68. JXCategoryIndicatorImageView *indicatorImageView = [[JXCategoryIndicatorImageView alloc] init];
  69. indicatorImageView.indicatorImageViewSize = CGSizeMake(adapt(68), 44);
  70. UIImageView *indicatorImgv = [[UIImageView alloc] init];
  71. indicatorImgv.image = [UIImage imageNamed:@"home_indicator_img"];
  72. indicatorImgv.contentMode = UIViewContentModeScaleAspectFit;
  73. [indicatorImageView addSubview:indicatorImgv];
  74. [indicatorImgv mas_makeConstraints:^(MASConstraintMaker *make) {
  75. make.center.equalTo(indicatorImageView);
  76. make.width.mas_equalTo(46);
  77. make.height.mas_equalTo(32);
  78. }];
  79. categoryView.indicators = @[indicatorImageView];
  80. // UIView *topView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, StatusBarHeight + LZCategoryViewHeight, KScreenWidth, (adapt(90) + adapt(56) + 30))];
  81. // [categoryBgV addSubview:topView];
  82. // self.bannerView.frame = topView.bounds;
  83. // [topView addSubview: self.bannerView];
  84. // self.bannerView.frame = CGRectZero;
  85. // self.bannerView.hidden = YES;
  86. JXCategoryListContainerView *listContainerView = [[JXCategoryListContainerView alloc] initWithType:JXCategoryListContainerType_CollectionView delegate:self];
  87. // listContainerView.listCellBackgroundColor = [UIColor whiteColor];
  88. listContainerView.frame = CGRectMake(0.0f,categoryBgV.mj_h, KScreenWidth, KScreenHeight - categoryBgV.mj_h - TabbarHeight);
  89. [self.view addSubview:listContainerView];
  90. categoryView.listContainer = listContainerView;
  91. // self.zhidingBtn.frame = CGRectMake(KScreenWidth - 16 - 24 - 10 - 24,(LZCategoryViewHeight - 44) / 2.0f + StatusBarHeight + 13,26,26);
  92. // [categoryBgV addSubview: self.zhidingBtn];
  93. self.searchBtn.frame = CGRectMake(KScreenWidth - 16 - 69,(LZCategoryViewHeight - 44) / 2.0f + StatusBarHeight,69,44);
  94. [categoryBgV addSubview:self.searchBtn];
  95. [self.searchBtn addSubview:self.searchLabel];
  96. [self.searchLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  97. make.left.equalTo(self.searchBtn).offset(8);
  98. make.centerY.equalTo(self.searchBtn).offset(3);
  99. }];
  100. }
  101. - (CGFloat)preferredCategoryViewHeight {
  102. //return (LZCategoryViewHeight + StatusBarHeight + adapt(90) + adapt(56) + 30);
  103. return (LZCategoryViewHeight + StatusBarHeight);
  104. }
  105. -(void)zhidingClick{
  106. [self.categoryView reloadData];
  107. }
  108. - (void)viewDidAppear:(BOOL)animated {
  109. [super viewDidAppear:animated];
  110. // self.navigationController.interactivePopGestureRecognizer.enabled = (self.categoryView.selectedIndex == 0);
  111. }
  112. - (void)viewWillAppear:(BOOL)animated{
  113. [super viewWillAppear:animated];
  114. [self.viewModel judgementsIsOpenAdolescentModel];
  115. }
  116. - (void)viewWillDisappear:(BOOL)animated{
  117. [super viewWillDisappear:animated];
  118. self.navigationController.interactivePopGestureRecognizer.enabled = YES;
  119. }
  120. - (void)ym_setupViews{
  121. [self.view setNeedsUpdateConstraints];
  122. [self.view updateConstraintsIfNeeded];
  123. }
  124. - (void)updateViewConstraints{
  125. // [self.pagerView mas_makeConstraints:^(MASConstraintMaker *make) {
  126. // make.top.equalTo(self.view).offset(kYMStatusBarHeight);
  127. // make.left.equalTo(self.view);
  128. // make.right.equalTo(self.view);
  129. // make.bottom.equalTo(self.view);
  130. // }];
  131. [super updateViewConstraints];
  132. }
  133. - (void)ym_bindViewModel{
  134. [self.bannerView ym_bindViewModel:self.viewModel.bannerVM];
  135. self.viewModel.refreshHomeListData = ^{
  136. NSLog(@"刷新首页数据");
  137. [OCNotificationCenter postNotificationName:REFRESH_HOME_NOTIFICATION object:nil userInfo:@{}];
  138. };
  139. [[YMGlobalUtils shared] getConfig];
  140. // if([self.viewModel isFemaleGender]){
  141. // self.zhidingBtn.hidden = false;
  142. // }else{
  143. // self.zhidingBtn.hidden = true;
  144. // }
  145. [self headerRefreshing];
  146. }
  147. /// 更新在线状态
  148. - (void)updateOnline{
  149. if (self->_timer) {
  150. dispatch_source_cancel(self->_timer);
  151. }
  152. if ([LCSaveData getTokenString] == nil) {
  153. return;
  154. }
  155. [LCHttpHelper requestWithURLString:onlineUpdate parameters:nil needToken:YES type:HttpRequestTypePost success:^(id responseObject) {
  156. NSDictionary* dict = (NSDictionary*)responseObject;
  157. NSInteger code = [[dict objectForKey:@"code"] integerValue];
  158. if (code==0) {//成功
  159. NSInteger user_online_open = [[[dict objectForKey:@"data"]objectForKey:@"user_online_open"] integerValue];
  160. int user_online_time = [[[dict objectForKey:@"data"]objectForKey:@"user_online_time"] intValue];
  161. if (user_online_open == 1) {
  162. __block int timeout= user_online_time;
  163. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
  164. self->_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
  165. dispatch_source_set_timer(self->_timer,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0); //每秒执行
  166. dispatch_source_set_event_handler(self->_timer, ^{
  167. if(timeout<=0){
  168. dispatch_source_cancel(self->_timer);
  169. dispatch_async(dispatch_get_main_queue(), ^{
  170. [self updateOnline];
  171. });
  172. }else{
  173. // NSString *strTime = [NSString stringWithFormat:@"%.2dS",timeout];
  174. dispatch_async(dispatch_get_main_queue(), ^{
  175. //设置界面的按钮显示 根据自己需求设置
  176. //NSLog(@"strTime strTime %@",strTime);
  177. //NSLog(@"当前时间挫%lld",[[LCTools getCurrentTimestamp] longLongValue]);
  178. });
  179. timeout--;
  180. }});
  181. dispatch_resume(self->_timer);
  182. }
  183. }
  184. } failure:^(NSError *error) {
  185. }];
  186. }
  187. - (void)headerRefreshing{
  188. [self.viewModel getAdvertData];
  189. // [self.viewModel getLevelIconData];
  190. [self.viewModel getBadgesAndNobilityIconData];
  191. [self.viewModel.bannerVM getOnTvData];
  192. [OCNotificationCenter postNotificationName:REFRESH_HOME_NOTIFICATION object:nil userInfo:@{}];
  193. }
  194. - (YMHomePageBannerView *)bannerView{
  195. if (!_bannerView) {
  196. _bannerView = [[YMHomePageBannerView alloc]init];
  197. @weakify(self)
  198. _bannerView.bannerViewHeightBlock = ^(CGFloat bannerViewHeight) {
  199. @strongify(self)
  200. self.bannerViewHeight = bannerViewHeight;
  201. };
  202. }
  203. return _bannerView;
  204. }
  205. - (UILabel *)searchLabel {
  206. if (!_searchLabel) {
  207. _searchLabel = [[UILabel alloc] init];
  208. _searchLabel.text = @"寻找";
  209. _searchLabel.textColor = UIColor.whiteColor;
  210. _searchLabel.font = LCFont(11);
  211. }
  212. return _searchLabel;
  213. }
  214. - (UIButton *)searchBtn{
  215. if (!_searchBtn) {
  216. _searchBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  217. [_searchBtn setImage:ImageByName(@"ym_home_page_xunzhao") forState:UIControlStateNormal];
  218. WS(weakSelf)
  219. [[[_searchBtn rac_signalForControlEvents:UIControlEventTouchUpInside] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(__kindof UIButton * _Nullable sender) {
  220. [weakSelf.viewModel gotoSearchUser];
  221. }];
  222. }
  223. return _searchBtn;
  224. }
  225. - (UIButton *)zhidingBtn{
  226. if (!_zhidingBtn) {
  227. _zhidingBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  228. [_zhidingBtn setImage:ImageByName(@"home_msg_zhiding") forState:UIControlStateNormal];
  229. _zhidingBtn.hidden = true;
  230. WS(weakSelf)
  231. [[[_zhidingBtn rac_signalForControlEvents:UIControlEventTouchUpInside] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(__kindof UIButton * _Nullable sender) {
  232. [weakSelf showZhidingBottomSheet];
  233. }];
  234. }
  235. return _zhidingBtn;
  236. }
  237. /**
  238. * 显示置顶功能底部选择弹窗
  239. * 包含自动置顶、群打招呼、取消三个选项
  240. */
  241. - (void)showZhidingBottomSheet {
  242. // 创建底部弹窗视图
  243. YMSheetPopupView *sheetView = [[YMSheetPopupView alloc] init];
  244. // 配置弹窗选项列表
  245. NSArray *optionList = @[
  246. @"自动置顶",
  247. @"群打招呼"
  248. ];
  249. // 配置弹窗数据
  250. [sheetView configutationWithItemList:optionList];
  251. // 设置选择回调
  252. WS(weakSelf)
  253. sheetView.selectIndexBlock = ^(NSInteger index) {
  254. [weakSelf handleZhidingSelection:index];
  255. };
  256. // 设置关闭回调(对应"取消"选项)
  257. sheetView.closeBlock = ^{
  258. // 用户点击取消按钮
  259. NSLog(@"用户取消了置顶操作");
  260. [YMPopupView removeLastPopView];
  261. };
  262. // 创建弹窗管理器并显示
  263. YMPopupView *popupView = [YMPopupView initWithCustomView:sheetView];
  264. popupView.popDuration = 0.3; // 弹出动画时间
  265. popupView.positionStyle = YMPositionStyleBottom; // 底部弹出
  266. popupView.popStyle = YMPopupStyleSmoothFromBottom; // 从底部滑入动画
  267. popupView.dismissStyle = YMDismissStyleSmoothToBottom; // 滑出到底部动画
  268. popupView.isClickBgDismiss = YES; // 点击背景关闭
  269. popupView.bgAlpha = 0.5; // 背景透明度
  270. // 显示弹窗
  271. [popupView pop];
  272. }
  273. /**
  274. * 处理置顶选择结果
  275. * @param index 选择的选项索引(0:自动置顶, 1:群打招呼)
  276. */
  277. - (void)handleZhidingSelection:(NSInteger)index {
  278. switch (index) {
  279. case 0:
  280. // 自动置顶
  281. NSLog(@"选择了:自动置顶");
  282. [self performAutoZhiding];
  283. break;
  284. case 1:
  285. // 群打招呼
  286. NSLog(@"选择了:群打招呼");
  287. [self performGroupGreeting];
  288. break;
  289. default:
  290. break;
  291. }
  292. // 关闭弹窗
  293. [YMPopupView removeLastPopView];
  294. }
  295. /**
  296. * 执行自动置顶功能
  297. */
  298. - (void)performAutoZhiding {
  299. // 调用原有的置顶数据方法
  300. [self.viewModel zhidingData];
  301. // 可以添加额外的自动置顶逻辑
  302. // 例如:显示成功提示、刷新列表等
  303. NSLog(@"自动置顶功能已执行");
  304. }
  305. /**
  306. * 执行群打招呼功能
  307. */
  308. - (void)performGroupGreeting {
  309. // 先请求获取推荐用户列表
  310. [self requestGroupGreetingUserList:YES];
  311. }
  312. /**
  313. * 请求群打招呼用户列表
  314. */
  315. - (void)requestGroupGreetingUserList:(BOOL)isNew {
  316. WS(weakSelf)
  317. [self.groupGreetingViewModel getGroupGreetingDataIsNew:isNew completion:^(BOOL isSuccess) {
  318. if (isSuccess) {
  319. [weakSelf showGroupGreetingPopupView];
  320. }
  321. }];
  322. }
  323. /**
  324. * 显示群打招呼弹窗
  325. */
  326. - (void)showGroupGreetingPopupView {
  327. [_greetingPopupView dismiss];
  328. // 创建群打招呼弹窗
  329. _greetingView = [[YMGroupGreetingPopupView alloc] initWithFrame:UIScreen.mainScreen.bounds];
  330. [_greetingView configureWithUserList:self.groupGreetingViewModel.listDataArray];
  331. WS(weakSelf)
  332. // 设置换一换回调
  333. _greetingView.refreshBlock = ^{
  334. [weakSelf requestGroupGreetingUserList:NO];
  335. };
  336. // 设置发送打招呼回调
  337. _greetingView.sendBlock = ^{
  338. [weakSelf sendGroupGreetingRequest];
  339. };
  340. _greetingView.clickBlankAreaBlock = ^{
  341. [weakSelf.greetingPopupView dismiss];
  342. };
  343. // 使用YMPopupView显示弹窗
  344. _greetingPopupView = [YMPopupView initWithCustomView:_greetingView];
  345. _greetingPopupView.positionStyle = YMPositionStyleCenter;
  346. _greetingPopupView.popDuration = 0.3; // 弹出动画时间
  347. _greetingPopupView.popStyle = YMPopupStyleFade; // 从底部滑入动画
  348. _greetingPopupView.dismissStyle = YMDismissStyleFade; // 滑出到底部动画
  349. _greetingPopupView.isClickBgDismiss = YES; // 点击背景关闭
  350. _greetingPopupView.bgAlpha = 0.5; // 背景透明度
  351. // 设置关闭回调
  352. _greetingView.closeBlock = ^{
  353. [weakSelf.greetingPopupView dismiss];
  354. };
  355. [_greetingPopupView pop];
  356. }
  357. /**
  358. * 发送群打招呼请求
  359. */
  360. - (void)sendGroupGreetingRequest {
  361. // 显示加载提示
  362. [ZCHUDHelper show];
  363. NSArray *arr = self.groupGreetingViewModel.listDataArray;
  364. NSString *str = @"";
  365. for (int i = 0; i < arr.count; i++) {
  366. YMGroupGreetingUserModel *model = arr[i];
  367. str = [str stringByAppendingString:[NSString stringWithFormat:@"%@",@(model.userId)]];
  368. if (i != arr.count - 1) {
  369. str = [str stringByAppendingString:@","];
  370. }
  371. }
  372. str = [NSString stringWithFormat:@"[%@]",str];
  373. // 请求参数
  374. NSDictionary *params = @{
  375. @"user_ids": str
  376. };
  377. [LCHttpHelper requestWithURLString:HomeBeckonSend parameters:params needToken:YES type:HttpRequestTypePost success:^(id responseObject) {
  378. [ZCHUDHelper dismiss];
  379. NSDictionary *dict = (NSDictionary *)responseObject;
  380. NSInteger code = [[dict objectForKey:@"code"] integerValue];
  381. if (code == 0) {
  382. //NSString *message = [dict stringValueForKey:@"message" defaultValue:@"打招呼发送成功"];
  383. [ZCHUDHelper showTitle:@"打招呼成功" showtime:2];
  384. [self.greetingPopupView dismiss];
  385. //[self.greetingView makeToast:@"打招呼成功" duration:2 position:CSToastPositionCenter];
  386. } else {
  387. NSString *message = [dict stringValueForKey:@"message" defaultValue:@"打招呼发送失败"];
  388. //[ZCHUDHelper showTitle:message];
  389. [ZCHUDHelper showTitle:message];
  390. //[self.greetingView makeToast:message duration:2 position:CSToastPositionCenter];
  391. }
  392. } failure:^(NSError *error) {
  393. [ZCHUDHelper dismiss];
  394. [ZCHUDHelper showTitle:@"网络请求失败"];
  395. }];
  396. }
  397. - (NSInteger)numberOfListsInlistContainerView:(JXCategoryListContainerView *)listContainerView {
  398. return self.titles.count;
  399. }
  400. - (id<JXCategoryListContentViewDelegate>)listContainerView:(JXCategoryListContainerView *)listContainerView initListForIndex:(NSInteger)index {
  401. YMHomeChildController *childVC = [[YMHomeChildController alloc] initWithViewModel:self.viewModel.homePageVMListDataArray[index]];
  402. childVC.jxCategoryPageIndex = index;
  403. return childVC;
  404. }
  405. - (void)categoryView:(JXCategoryBaseView *)categoryView didSelectedItemAtIndex:(NSInteger)index{
  406. self.selectIndex = index;
  407. }
  408. - (NSArray <NSString *> *)titles{
  409. BOOL isFemaleGender = [OCUserDefaults boolForKey:kIS_FEMALE_GENDER];
  410. if (isFemaleGender) {
  411. return @[@"男神",@"在线"];
  412. } else {
  413. return @[@"推荐",@"在线"];
  414. }
  415. }
  416. @end