keyboard_manage_controller.dart 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. import 'package:collection/collection.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:get/get.dart';
  4. import 'package:injectable/injectable.dart';
  5. import 'package:keyboard/base/base_controller.dart';
  6. import 'package:keyboard/data/bean/character_info.dart';
  7. import 'package:keyboard/data/repository/keyboard_repository.dart';
  8. import 'package:keyboard/dialog/character_add_dialog.dart';
  9. import 'package:keyboard/dialog/custom_character/custom_character_add_dialog.dart';
  10. import 'package:keyboard/module/character/content/character_group_content_controller.dart';
  11. import 'package:keyboard/resource/string.gen.dart';
  12. import 'package:keyboard/utils/atmob_log.dart';
  13. import 'package:keyboard/utils/toast_util.dart';
  14. import '../../data/bean/keyboard_info.dart';
  15. enum KeyboardType {
  16. system, //通用键盘
  17. custom, //自定义键盘
  18. }
  19. @injectable
  20. class KeyboardManageController extends BaseController
  21. with GetTickerProviderStateMixin {
  22. final String tag = 'KeyboardManageController';
  23. // 自定义键盘列表
  24. final RxList<KeyboardInfo> _customKeyboardInfoList = RxList();
  25. List<KeyboardInfo> get customKeyboardInfoList => _customKeyboardInfoList;
  26. // 当前自定义键盘
  27. final Rx<KeyboardInfo> _currentCustomKeyboardInfo = KeyboardInfo().obs;
  28. KeyboardInfo get currentCustomKeyboardInfo => _currentCustomKeyboardInfo.value;
  29. //当前自定义键盘人设列表
  30. final RxList<CharacterInfo> _currentCustomKeyboardCharacterList = RxList();
  31. RxList<CharacterInfo> get currentCustomKeyboardCharacterList =>
  32. _currentCustomKeyboardCharacterList;
  33. // 当前自定义键盘亲密度
  34. final RxInt _currentCustomIntimacy = 0.obs;
  35. int get currentCustomIntimacy => _currentCustomIntimacy.value;
  36. // 当前定制亲密度是否有变化
  37. final RxBool _customIntimacyChanged = false.obs;
  38. bool get customIntimacyChanged => _customIntimacyChanged.value;
  39. final RxBool _customKeyboardCharacterListChanged = false.obs;
  40. bool get customKeyboardCharacterListChanged =>
  41. _customKeyboardCharacterListChanged.value;
  42. // 存储排序前的定制人设列表,用于比较是否有变化
  43. late List<CharacterInfo> _oldCustomCharacterList;
  44. // 通用键盘列表
  45. final RxList<KeyboardInfo> _generalKeyboardInfoList = RxList();
  46. List<KeyboardInfo> get generalKeyboardInfoList => _generalKeyboardInfoList;
  47. // 当前通用键盘
  48. final Rx<KeyboardInfo> _currentGeneralKeyboardInfo = KeyboardInfo().obs;
  49. KeyboardInfo get currentGeneralKeyboardInfo =>
  50. _currentGeneralKeyboardInfo.value;
  51. // 当前通用键盘人设列表
  52. final RxList<CharacterInfo> _currentGeneralKeyboardCharacterList = RxList();
  53. List<CharacterInfo> get currentGeneralKeyboardCharacterList =>
  54. _currentGeneralKeyboardCharacterList;
  55. // 当前通用键盘亲密度
  56. final RxInt _currentGeneralIntimacy = 0.obs;
  57. int get currentGeneralIntimacy => _currentGeneralIntimacy.value;
  58. // 当前通用亲密度是否有变化
  59. final RxBool _generalIntimacyChanged = false.obs;
  60. RxBool get generalIntimacyChanged => _generalIntimacyChanged;
  61. final RxBool _generalKeyboardCharacterListChanged = false.obs;
  62. bool get generalKeyboardCharacterListChanged =>
  63. _generalKeyboardCharacterListChanged.value;
  64. // 存储排序前的通用人设列表,用于比较是否有变化
  65. late List<CharacterInfo> _oldGeneralCharacterList;
  66. final KeyboardRepository keyboardRepository;
  67. // 最小人设数量
  68. final _minCount = 9;
  69. // 键盘管理类型
  70. List<String> keyboardManageType = [
  71. StringName.keyboardCustom,
  72. StringName.generalKeyboard,
  73. ];
  74. // 键盘管理页面的tabController,用于控制通用键盘和自定义键盘的切换
  75. late TabController tabController;
  76. // 键盘管理页面的pageController,用于控制通用键盘和自定义键盘的切换
  77. late PageController pageController;
  78. KeyboardManageController(this.keyboardRepository);
  79. @override
  80. void onInit() {
  81. super.onInit();
  82. _dataLoad();
  83. }
  84. _dataLoad() {
  85. tabController = TabController(
  86. length: keyboardManageType.length,
  87. vsync: this,
  88. initialIndex: 0,
  89. );
  90. tabController.addListener(() {
  91. if (tabController.indexIsChanging) {
  92. switchTabKeyboardType(tabController.index);
  93. }
  94. });
  95. pageController = PageController();
  96. getCustomKeyboard();
  97. getGeneralKeyboard();
  98. }
  99. clickBack() {
  100. AtmobLog.i(tag, 'clickBack');
  101. Get.back();
  102. }
  103. // 获取定制键盘
  104. void getCustomKeyboard() {
  105. AtmobLog.i(tag, 'getCustomKeyboard');
  106. keyboardRepository.getKeyboardList(type: KeyboardType.custom.name).then((
  107. keyboardListResponse,
  108. ) {
  109. AtmobLog.i(
  110. tag,
  111. 'keyboardListResponse: ${keyboardListResponse.keyboardInfos}',
  112. );
  113. _customKeyboardInfoList.value = keyboardListResponse.keyboardInfos;
  114. //检查是否是选择的键盘,如果没有选择的键盘,默认选择第一个
  115. if (_customKeyboardInfoList.isNotEmpty) {
  116. _currentCustomKeyboardInfo.value = _customKeyboardInfoList.firstWhere(
  117. (element) => element.isChoose == true,
  118. orElse: () => _customKeyboardInfoList.first,
  119. );
  120. _currentCustomIntimacy.value =
  121. _currentCustomKeyboardInfo.value.intimacy ?? 0;
  122. _currentCustomIntimacy.listen((intimacy) {
  123. _customIntimacyChanged.value =
  124. _currentCustomKeyboardInfo.value.intimacy != intimacy;
  125. AtmobLog.d(tag, 'intimacyChanged: $_customIntimacyChanged');
  126. });
  127. String? id = _currentCustomKeyboardInfo.value.id;
  128. if (id != null) {
  129. getKeyboardCharacterList(keyboardId: id, isCustom: true);
  130. }
  131. }
  132. });
  133. }
  134. // 获取通用键盘
  135. void getGeneralKeyboard() {
  136. AtmobLog.i(tag, 'getGeneralKeyboard');
  137. keyboardRepository.getKeyboardList(type: KeyboardType.system.name).then((
  138. keyboardListResponse,
  139. ) {
  140. AtmobLog.i(
  141. tag,
  142. 'keyboardListResponse: ${keyboardListResponse.keyboardInfos}',
  143. );
  144. _generalKeyboardInfoList.value = keyboardListResponse.keyboardInfos;
  145. _currentGeneralKeyboardInfo.value = _generalKeyboardInfoList.first;
  146. _currentGeneralIntimacy.value =
  147. _currentGeneralKeyboardInfo.value.intimacy ?? 0;
  148. _currentGeneralIntimacy.listen((intimacy) {
  149. _generalIntimacyChanged.value =
  150. _currentGeneralKeyboardInfo.value.intimacy != intimacy;
  151. AtmobLog.d(tag, 'intimacyChanged: $_generalIntimacyChanged');
  152. });
  153. String? id = _currentGeneralKeyboardInfo.value.id;
  154. if (id != null) {
  155. getKeyboardCharacterList(keyboardId: id, isCustom: false);
  156. }
  157. });
  158. }
  159. // 获取当前键盘人设列表
  160. void getKeyboardCharacterList({
  161. required String keyboardId,
  162. required bool isCustom,
  163. }) {
  164. if (isCustom) {
  165. keyboardRepository.getKeyboardCharacterList(keyboardId: keyboardId).then((
  166. keyboardCharacterListResponse,
  167. ) {
  168. AtmobLog.i(
  169. tag,
  170. 'keyboardCharacterListResponse: ${keyboardCharacterListResponse.characterInfos.toString()}',
  171. );
  172. _currentCustomKeyboardCharacterList.assignAll(
  173. keyboardCharacterListResponse.characterInfos,
  174. );
  175. _oldCustomCharacterList = List<CharacterInfo>.from(
  176. _currentCustomKeyboardCharacterList,
  177. );
  178. _customKeyboardCharacterListChanged.value = false;
  179. _currentCustomKeyboardCharacterList.listen((event) {
  180. _customKeyboardCharacterListChanged.value =
  181. !ListEquality().equals(_oldCustomCharacterList, event);
  182. AtmobLog.d(
  183. tag,
  184. '_customKeyboardCharacterListChanged: $_customKeyboardCharacterListChanged',
  185. );
  186. });
  187. });
  188. } else {
  189. keyboardRepository.getKeyboardCharacterList(keyboardId: keyboardId).then((
  190. keyboardCharacterListResponse,
  191. ) {
  192. AtmobLog.i(
  193. tag,
  194. 'keyboardCharacterListResponse: ${keyboardCharacterListResponse.characterInfos.toString()}',
  195. );
  196. if (_currentGeneralKeyboardInfo.value.id == keyboardId) {
  197. _currentGeneralKeyboardCharacterList.value =
  198. keyboardCharacterListResponse.characterInfos;
  199. _oldGeneralCharacterList = List<CharacterInfo>.from(
  200. _currentGeneralKeyboardCharacterList,
  201. );
  202. _generalKeyboardCharacterListChanged.value = false;
  203. _currentGeneralKeyboardCharacterList.listen((event) {
  204. _generalKeyboardCharacterListChanged.value =
  205. !ListEquality().equals(_oldGeneralCharacterList, event);
  206. AtmobLog.d(
  207. tag,
  208. '_generalKeyboardCharacterListChanged: $_generalKeyboardCharacterListChanged',
  209. );
  210. });
  211. }
  212. if (_currentCustomKeyboardInfo.value.id == keyboardId) {
  213. _currentCustomKeyboardCharacterList.value =
  214. keyboardCharacterListResponse.characterInfos;
  215. }
  216. });
  217. }
  218. }
  219. // 切换当前定制键盘
  220. void switchCustomKeyboard(String? keyboardName) {
  221. _currentCustomKeyboardInfo.value = _customKeyboardInfoList.firstWhere(
  222. (element) => element.name == keyboardName,
  223. orElse: () => _customKeyboardInfoList.first,
  224. );
  225. String? keyboardId = _currentCustomKeyboardInfo.value.id;
  226. _currentCustomIntimacy.value =
  227. _currentCustomKeyboardInfo.value.intimacy ?? 0;
  228. if (keyboardId != null) {
  229. getKeyboardCharacterList(keyboardId: keyboardId, isCustom: true);
  230. }
  231. }
  232. // 切换当前通用键盘
  233. void switchGeneralKeyboard(String? keyboardName) {
  234. _currentGeneralKeyboardInfo.value = _generalKeyboardInfoList.firstWhere(
  235. (element) => element.name == keyboardName,
  236. orElse: () => _generalKeyboardInfoList.first,
  237. );
  238. String? keyboardId = _currentGeneralKeyboardInfo.value.id;
  239. _currentGeneralIntimacy.value =
  240. _currentGeneralKeyboardInfo.value.intimacy ?? 0;
  241. if (keyboardId != null) {
  242. getKeyboardCharacterList(keyboardId: keyboardId, isCustom: false);
  243. }
  244. }
  245. // tab切换
  246. void switchTabKeyboardType(int index) {
  247. // AtmobLog.i(tag, 'onTabChanged: $index');
  248. pageController.animateToPage(
  249. index,
  250. duration: const Duration(milliseconds: 300),
  251. curve: Curves.easeInToLinear,
  252. );
  253. }
  254. // page切换
  255. void switchPageKeyboardType(int index) {
  256. // AtmobLog.i(tag, 'onPageChanged: $index');
  257. tabController.animateTo(index, duration: const Duration(milliseconds: 300));
  258. if (index == 0) {
  259. _currentGeneralIntimacy.value =
  260. _currentGeneralKeyboardInfo.value.intimacy ?? 0;
  261. _currentGeneralKeyboardCharacterList.value = _oldGeneralCharacterList;
  262. _generalIntimacyChanged.value = false;
  263. _generalKeyboardCharacterListChanged.value = false;
  264. getCustomKeyboard();
  265. } else {
  266. _currentCustomIntimacy.value =
  267. _currentCustomKeyboardInfo.value.intimacy ?? 0;
  268. _currentCustomKeyboardCharacterList.value = _oldCustomCharacterList;
  269. _customIntimacyChanged.value = false;
  270. _customKeyboardCharacterListChanged.value = false;
  271. getGeneralKeyboard();
  272. }
  273. }
  274. // 更新亲密度
  275. void updateIntimacy(int intimacy, bool isCustom) {
  276. if (isCustom) {
  277. _currentCustomIntimacy.value = intimacy;
  278. } else {
  279. _currentGeneralIntimacy.value = intimacy;
  280. }
  281. }
  282. // 排序
  283. void onReorder(int oldIndex, int newIndex, bool isCustom) {
  284. if (isCustom) {
  285. reorderList(_currentCustomKeyboardCharacterList, oldIndex, newIndex);
  286. } else {
  287. reorderList(_currentGeneralKeyboardCharacterList, oldIndex, newIndex);
  288. }
  289. }
  290. // 排序
  291. void reorderList<T>(RxList<T> list, int oldIndex, int newIndex) {
  292. AtmobLog.d(tag, 'reorderList: $oldIndex, $newIndex');
  293. final item = list.removeAt(oldIndex);
  294. list.insert(newIndex, item);
  295. }
  296. void clickSave(bool isCustom) {
  297. isCustom
  298. ? saveCustomKeyboardCharacterList()
  299. : saveGeneralKeyboardCharacterList();
  300. }
  301. void saveCustomKeyboardCharacterList() {
  302. if (_customIntimacyChanged.value) {
  303. AtmobLog.i(tag, 'clickSave intimacyChanged');
  304. _currentCustomKeyboardInfo.value.intimacy = currentCustomIntimacy;
  305. String? keyboardId = _currentCustomKeyboardInfo.value.id;
  306. if (keyboardId != null) {
  307. keyboardRepository
  308. .updateKeyboardInfo(
  309. keyboardId: keyboardId,
  310. intimacy: currentCustomIntimacy,
  311. )
  312. .then((value) {
  313. ToastUtil.show(StringName.keyboardSaveSuccess);
  314. CharacterGroupContentController characterGroupContentController =
  315. Get.find<CharacterGroupContentController>();
  316. characterGroupContentController.refreshData();
  317. })
  318. .catchError((error) {
  319. ToastUtil.show(StringName.keyboardSaveFailed);
  320. _customIntimacyChanged.value = false;
  321. });
  322. }
  323. }
  324. if (_customKeyboardCharacterListChanged.value) {
  325. AtmobLog.i(tag, 'clickSave keyboardChanged');
  326. String? keyboardId = _currentCustomKeyboardInfo.value.id;
  327. if (keyboardId != null) {
  328. List<String> characterIds =
  329. _currentCustomKeyboardCharacterList
  330. .map((e) => e.id)
  331. .toList()
  332. .cast<String>();
  333. keyboardRepository
  334. .keyboardCharacterUpdate(
  335. characterIds: characterIds,
  336. keyboardId: keyboardId,
  337. )
  338. .then((value) {
  339. _oldCustomCharacterList = List<CharacterInfo>.from(
  340. _currentCustomKeyboardCharacterList,
  341. );
  342. CharacterGroupContentController characterGroupContentController =
  343. Get.find<CharacterGroupContentController>();
  344. characterGroupContentController.refreshData();
  345. ToastUtil.show(StringName.keyboardSaveSuccess);
  346. })
  347. .catchError((error) {
  348. ToastUtil.show(StringName.keyboardSaveFailed);
  349. _customKeyboardCharacterListChanged.value = false;
  350. });
  351. }
  352. }
  353. }
  354. void saveGeneralKeyboardCharacterList() {
  355. if (_generalIntimacyChanged.value) {
  356. AtmobLog.i(tag, 'clickSave intimacyChanged');
  357. _currentGeneralKeyboardInfo.value.intimacy = currentGeneralIntimacy;
  358. String? keyboardId = _currentGeneralKeyboardInfo.value.id;
  359. if (keyboardId != null) {
  360. keyboardRepository
  361. .updateKeyboardInfo(
  362. keyboardId: keyboardId,
  363. intimacy: currentGeneralIntimacy,
  364. )
  365. .then((value) {
  366. ToastUtil.show(StringName.keyboardSaveSuccess);
  367. })
  368. .catchError((error) {
  369. ToastUtil.show(StringName.keyboardSaveFailed);
  370. _generalIntimacyChanged.value = false;
  371. });
  372. }
  373. }
  374. if (_generalKeyboardCharacterListChanged.value) {
  375. AtmobLog.i(tag, 'clickSave keyboardChanged');
  376. String? keyboardId = _currentGeneralKeyboardInfo.value.id;
  377. if (keyboardId != null) {
  378. List<String> characterIds =
  379. _currentGeneralKeyboardCharacterList
  380. .map((e) => e.id)
  381. .toList()
  382. .cast<String>();
  383. keyboardRepository
  384. .keyboardCharacterUpdate(
  385. characterIds: characterIds,
  386. keyboardId: keyboardId,
  387. )
  388. .then((value) {
  389. _oldGeneralCharacterList = List<CharacterInfo>.from(
  390. _currentGeneralKeyboardCharacterList,
  391. );
  392. ToastUtil.show(StringName.keyboardSaveSuccess);
  393. })
  394. .catchError((error) {
  395. ToastUtil.show(StringName.keyboardSaveFailed);
  396. _generalKeyboardCharacterListChanged.value = false;
  397. });
  398. }
  399. }
  400. }
  401. void clickRemoveCharacter(CharacterInfo characterInfo, bool isCustom) {
  402. if (isCustom) {
  403. if (_currentCustomKeyboardCharacterList.length <= _minCount) {
  404. ToastUtil.show("最少需要保持$_minCount个人设");
  405. return;
  406. }
  407. AtmobLog.i(tag, 'clickRemoveCharacter');
  408. _currentCustomKeyboardCharacterList.remove(characterInfo);
  409. } else {
  410. if (_currentGeneralKeyboardCharacterList.length <= _minCount) {
  411. ToastUtil.show("最少需要保持$_minCount个人设");
  412. return;
  413. }
  414. AtmobLog.i(tag, 'clickRemoveCharacter');
  415. _currentGeneralKeyboardCharacterList.remove(characterInfo);
  416. }
  417. }
  418. clickAddCharacter({required bool isCustom}) {
  419. if (isCustom) {
  420. CharacterAddDialog.show(
  421. currentKeyboardInfo: currentCustomKeyboardInfo,
  422. clickCallback: () {
  423. getKeyboardCharacterList(
  424. keyboardId: _currentCustomKeyboardInfo.value.id ?? "",
  425. isCustom: true,
  426. );
  427. },
  428. );
  429. } else {
  430. CharacterAddDialog.show(
  431. currentKeyboardInfo: currentGeneralKeyboardInfo,
  432. clickCallback: () {
  433. getGeneralKeyboard();
  434. },
  435. );
  436. }
  437. }
  438. clickCustomCharacter() {
  439. AtmobLog.i(tag, 'clickCustomCharacter');
  440. CustomCharacterAddDialog.show(currentKeyboardInfo: currentCustomKeyboardInfo, clickCallback: (){
  441. getKeyboardCharacterList(
  442. keyboardId: _currentCustomKeyboardInfo.value.id ?? "",
  443. isCustom: true,
  444. );
  445. });
  446. }
  447. @override
  448. void onClose() {
  449. tabController.dispose();
  450. pageController.dispose();
  451. super.onClose();
  452. }
  453. }