AINewConfigWindowController.swift 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. //
  2. // AINewConfigWindowController.swift
  3. // PDF Reader Pro Edition
  4. //
  5. // Created by Niehaoyu on 2024/4/16.
  6. //
  7. import Cocoa
  8. protocol AIConfigWindowDelegate: AnyObject {
  9. func ai_InputViewDidChooseCurFile(aiConfigWindow: AINewConfigWindowController)
  10. }
  11. @objcMembers class AINewConfigWindowController: NSWindowController, NSWindowDelegate, AIInfoInputViewDelegate {
  12. static var currentWindowController: AINewConfigWindowController!
  13. @IBOutlet weak var contendBox: NSBox!
  14. var aiHeaderView: AIHeaderView!
  15. var aiChatView: AIChatView!
  16. var aiTypeItemView: AITypeItemChooseView!
  17. var aiInfoInputView: AIInfoInputView!
  18. var inputStringHeight: CGFloat = 40
  19. var eventLabel: String = "AITools_Start"
  20. weak var aiDelegate: AIConfigWindowDelegate?
  21. var chooseCurFileHandle: ((_ windowVC: AINewConfigWindowController) -> Void)?
  22. deinit {
  23. DistributedNotificationCenter.default.removeObserver(self)
  24. }
  25. @objc static func currentWC() -> AINewConfigWindowController {
  26. if currentWindowController != nil {
  27. return currentWindowController
  28. } else {
  29. let configWC: AINewConfigWindowController = AINewConfigWindowController.init(windowNibName: "AINewConfigWindowController")
  30. currentWindowController = configWC;
  31. return currentWindowController
  32. }
  33. }
  34. override func showWindow(_ sender: Any?) {
  35. super.showWindow(sender)
  36. self.window?.delegate = self
  37. self.aiInfoInputView.setUpTranslateUI()
  38. self.aiChatView.reloadData()
  39. self.aiTypeItemView.refreshUI()
  40. self.refreshViewUI()
  41. }
  42. override func windowDidLoad() {
  43. super.windowDidLoad()
  44. // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
  45. self.window?.title = NSLocalizedString("AI Tools", comment: "")
  46. self.loadAIHeaderView()
  47. self.loadAIChatView()
  48. self.loadAIInputView()
  49. self.loadAITypeItemView()
  50. self.refreshViewUI()
  51. self.refreshViewColor()
  52. DistributedNotificationCenter.default().addObserver(self, selector: #selector(themeChange), name: NSNotification.Name(rawValue: "AppleInterfaceThemeChangedNotification"), object: nil)
  53. }
  54. func refreshViewColor() {
  55. if KMAppearance.isDarkMode() {
  56. self.contendBox.fillColor = NSColor(red: 33/255, green: 33/255, blue: 33/255, alpha: 1)
  57. } else {
  58. self.contendBox.fillColor = NSColor.white
  59. }
  60. self.aiHeaderView.refreshViewColor()
  61. self.aiInfoInputView.refreshUI()
  62. self.aiChatView.reloadData()
  63. self.aiTypeItemView.refreshViewColor()
  64. }
  65. func loadAIHeaderView() {
  66. self.aiHeaderView = AIHeaderView.createFromNib()
  67. self.aiHeaderView.frame = CGRectMake(0, CGRectGetHeight(self.contendBox.frame)-58, CGRectGetWidth(self.contendBox.frame), 28)
  68. self.aiHeaderView.autoresizingMask = [.minXMargin, .maxXMargin, .width, .minYMargin]
  69. self.contendBox.addSubview(self.aiHeaderView)
  70. }
  71. func loadAIChatView() {
  72. self.aiChatView = AIChatView.createFromNib()
  73. self.aiChatView.wantsLayer = true
  74. self.aiChatView.layer?.backgroundColor = NSColor.clear.cgColor
  75. self.aiChatView.frame = CGRectMake(0, 300, CGRectGetWidth(self.contendBox.frame), CGRectGetHeight(self.contendBox.frame)-400)
  76. self.aiChatView.autoresizingMask = [.width, .height]
  77. self.contendBox.addSubview(self.aiChatView)
  78. self.aiChatView.chooseConfigHandle = {[unowned self] view, configType in
  79. DispatchQueue.main.async {
  80. self.chooseAIFunctionWithType(configType)
  81. }
  82. }
  83. self.aiChatView.cancelAIHandle = {[unowned self] view, chatInfoModel in
  84. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.05) {
  85. chatInfoModel.chatInfoState = .stateCancel
  86. self.aiChatView.reloadData()
  87. }
  88. }
  89. self.aiChatView.continueAITranslateHandle = {[unowned self] view, chatInfoModel in
  90. DispatchQueue.main.async {
  91. chatInfoModel.chatInfoState = .stateLoading
  92. self.aiChatView.reloadData()
  93. self.continueAiTranslate(chatInfoModel)
  94. }
  95. }
  96. self.aiChatView.redoHandle = {[unowned self] view, chatInfoModel in
  97. DispatchQueue.main.async {
  98. let newChatModel = AIChatInfoModel.init()
  99. newChatModel.aiConfigType = chatInfoModel.aiConfigType
  100. newChatModel.infoType = chatInfoModel.infoType
  101. newChatModel.filePath = chatInfoModel.filePath
  102. newChatModel.chatInfoState = .stateLoading
  103. newChatModel.uploadContent = chatInfoModel.uploadContent
  104. newChatModel.translateFromLanguage = chatInfoModel.translateFromLanguage
  105. newChatModel.translateToLanguage = chatInfoModel.translateToLanguage
  106. AIChatInfoManager.defaultManager.modelsArrM.append(newChatModel)
  107. self.aiChatView.reloadData()
  108. if newChatModel.aiConfigType == .summarize {
  109. self.aiSummarizeWithModel(newChatModel)
  110. } else if newChatModel.aiConfigType == .reWriting {
  111. self.aiReWritingWithModel(newChatModel)
  112. } else if newChatModel.aiConfigType == .proofreading {
  113. self.aiProofreadingWithModel(newChatModel)
  114. } else if newChatModel.aiConfigType == .translate {
  115. self.startAiTranslateWithModel(newChatModel)
  116. }
  117. }
  118. }
  119. }
  120. func loadAIInputView() {
  121. self.aiInfoInputView = AIInfoInputView.createFromNib()
  122. self.aiInfoInputView.frame = CGRectMake((CGRectGetWidth(self.contendBox.frame)-248)/2.0, 20, 248, 86)
  123. self.aiInfoInputView.autoresizingMask = [.minXMargin, .maxXMargin, .width, .maxYMargin]
  124. self.contendBox.addSubview(self.aiInfoInputView)
  125. self.aiInfoInputView.aiConfigType = .none
  126. self.aiInfoInputView.aiDelegate = self
  127. self.aiInfoInputView.reloadData()
  128. self.aiInfoInputView.startAIHandle = {[unowned self] view in
  129. if view.aiConfigType == .summarize {
  130. let chatModel = AIChatInfoModel.init()
  131. chatModel.aiConfigType = .summarize
  132. chatModel.infoType = .chatFileUpload
  133. chatModel.filePath = self.aiInfoInputView.filePath
  134. AIChatInfoManager.defaultManager.modelsArrM.append(chatModel)
  135. self.aiChatView.reloadData()
  136. self.aiSummarize()
  137. } else if view.aiConfigType == .reWriting {
  138. let chatModel = AIChatInfoModel.init()
  139. chatModel.aiConfigType = .reWriting
  140. chatModel.infoType = .chatStringUpload
  141. chatModel.uploadContent = self.aiInfoInputView.fileEmptyTextView.string
  142. AIChatInfoManager.defaultManager.modelsArrM.append(chatModel)
  143. self.aiChatView.reloadData()
  144. self.aiReWriting()
  145. } else if view.aiConfigType == .proofreading {
  146. let chatModel = AIChatInfoModel.init()
  147. chatModel.aiConfigType = .proofreading
  148. chatModel.infoType = .chatStringUpload
  149. chatModel.uploadContent = self.aiInfoInputView.fileEmptyTextView.string
  150. AIChatInfoManager.defaultManager.modelsArrM.append(chatModel)
  151. self.aiChatView.reloadData()
  152. self.aiProofreading()
  153. } else if view.aiConfigType == .translate {
  154. let chatModel = AIChatInfoModel.init()
  155. chatModel.aiConfigType = .translate
  156. if self.aiInfoInputView.filePath.isEmpty == false {
  157. //文件
  158. chatModel.filePath = self.aiInfoInputView.filePath
  159. chatModel.infoType = .chatFileUpload
  160. } else {
  161. //文字
  162. chatModel.uploadContent = self.aiInfoInputView.fileEmptyTextView.string
  163. chatModel.infoType = .chatStringUpload
  164. }
  165. chatModel.translateFromLanguage = self.aiInfoInputView.fromLanguage
  166. chatModel.translateToLanguage = self.aiInfoInputView.toLanguage
  167. AIChatInfoManager.defaultManager.modelsArrM.append(chatModel)
  168. self.aiChatView.reloadData()
  169. self.startAiTranslate()
  170. }
  171. self.refreshViewUI()
  172. self.aiTypeItemView.reloadData()
  173. }
  174. self.aiInfoInputView.inputFrameUpdateHandle = {[unowned self] view, stringSize in
  175. if view.aiConfigType == .summarize {
  176. self.inputStringHeight = max(stringSize.height, 40)
  177. } else if view.aiConfigType == .reWriting {
  178. self.inputStringHeight = max(stringSize.height, 40)
  179. } else if view.aiConfigType == .proofreading {
  180. self.inputStringHeight = max(stringSize.height, 40)
  181. } else if view.aiConfigType == .translate {
  182. if view.filePath.isEmpty {
  183. self.inputStringHeight = max(stringSize.height, 40)
  184. } else {
  185. self.inputStringHeight = 40
  186. }
  187. }
  188. self.refreshViewUI()
  189. }
  190. self.aiInfoInputView.refreshUI()
  191. }
  192. func loadAITypeItemView() {
  193. self.aiTypeItemView = AITypeItemChooseView.createFromNib()
  194. self.aiTypeItemView.wantsLayer = true
  195. self.aiTypeItemView.layer?.backgroundColor = NSColor.clear.cgColor
  196. self.aiTypeItemView.frame = CGRectMake((CGRectGetWidth(self.contendBox.frame)-246)/2, CGRectGetMaxY(self.aiInfoInputView.frame)+13, 246, 52)
  197. self.aiTypeItemView.autoresizingMask = [.minXMargin, .maxXMargin, .width, .maxYMargin]
  198. self.contendBox.addSubview(self.aiTypeItemView)
  199. self.aiTypeItemView.chooseTypeHandle = {[unowned self] itemView, aiConfigtype in
  200. self.chooseAIFunctionWithType(aiConfigtype)
  201. }
  202. self.aiTypeItemView.clearHandle = {[unowned self] itemView in
  203. if AIChatInfoManager.defaultManager.modelsArrM.count < 1 {
  204. return
  205. }
  206. let alert = NSAlert()
  207. alert.alertStyle = .critical
  208. alert.informativeText = NSLocalizedString("All the AI content will be removed. Are you sure you want to clear the session?", comment: "")
  209. alert.messageText = NSLocalizedString("Clear session", comment: "")
  210. alert.addButton(withTitle: NSLocalizedString("Clear", comment: ""))
  211. alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
  212. let response = alert.runModal()
  213. if response.rawValue == 1000 {
  214. DispatchQueue.main.async {
  215. AIChatInfoManager.defaultManager.clearData()
  216. self.aiChatView.reloadData()
  217. }
  218. }
  219. }
  220. }
  221. func chooseAIFunctionWithType(_ aiConfigType: AIConfigType) -> Void {
  222. if AIInfoManager.default().aiInfo.infoDict.keys.count == 0 {
  223. #if VERSION_DMG
  224. KMPurchaseCompareWindowController.dmgPurchaseInstance().showWindow(nil)
  225. #else
  226. AIPurchaseWindowController.currentWC().showWindow(nil)
  227. #endif
  228. return;
  229. }
  230. if self.eventLabel.isEmpty {
  231. self.eventLabel = "AITools_Start"
  232. }
  233. if aiConfigType == .summarize {
  234. FMTrackEventManager.defaultManager.trackOnceEvent(event: "AITools", withProperties: [self.eventLabel:"AISum"])
  235. } else if aiConfigType == .reWriting {
  236. FMTrackEventManager.defaultManager.trackOnceEvent(event: "AITools", withProperties: [self.eventLabel:"AIRewrite"])
  237. } else if aiConfigType == .proofreading {
  238. FMTrackEventManager.defaultManager.trackOnceEvent(event: "AITools", withProperties: [self.eventLabel:"AIProofread"])
  239. } else if aiConfigType == .translate {
  240. FMTrackEventManager.defaultManager.trackOnceEvent(event: "AITools", withProperties: [self.eventLabel:"AITranslate"])
  241. }
  242. self.aiInfoInputView.aiConfigType = aiConfigType
  243. self.aiInfoInputView.reloadData()
  244. self.aiInfoInputView.aiFunctionTypeChanged()
  245. if self.aiInfoInputView.fileEmptyTextView.string.isEmpty == false {
  246. self.aiInfoInputView.updateCountLabelInfo()
  247. self.aiInfoInputView.refreshStringSize()
  248. }
  249. self.refreshViewUI()
  250. }
  251. func setCurrentPDFSelection(_ string: String) -> Void {
  252. self.aiInfoInputView.fileEmptyTextView.string = string
  253. }
  254. func refreshViewUI() {
  255. self.aiHeaderView.frame = CGRectMake(0, CGRectGetHeight(self.contendBox.frame)-58, CGRectGetWidth(self.contendBox.frame), 28)
  256. if self.aiInfoInputView.aiConfigType == .none {
  257. self.aiInfoInputView.frame = CGRectMake(13, 17, 240, 86)
  258. } else if self.aiInfoInputView.aiConfigType == .summarize {
  259. self.aiInfoInputView.frame = CGRectMake(13, 17, 240, min(96+self.inputStringHeight, 500))
  260. } else if self.aiInfoInputView.aiConfigType == .reWriting {
  261. self.aiInfoInputView.frame = CGRectMake(13, 17, 240, min(72+self.inputStringHeight, 500))
  262. } else if self.aiInfoInputView.aiConfigType == .proofreading {
  263. self.aiInfoInputView.frame = CGRectMake(13, 17, 240, min(72+self.inputStringHeight, 500))
  264. } else if self.aiInfoInputView.aiConfigType == .translate {
  265. self.aiInfoInputView.frame = CGRectMake(13, 17, 240, min(125+self.inputStringHeight, 500))
  266. }
  267. self.aiTypeItemView.frame = CGRectMake(13, CGRectGetMaxY(self.aiInfoInputView.frame)+8, 240, self.aiTypeItemView.viewHeight)
  268. self.aiChatView.frame = CGRectMake(0, CGRectGetMaxY(self.aiTypeItemView.frame)+8, CGRectGetWidth(self.contendBox.frame), CGRectGetHeight(self.contendBox.frame) - CGRectGetMaxY(self.aiTypeItemView.frame) - 16 - 58)
  269. }
  270. //MARK: AI-Action
  271. func aiSummarize() -> Void {
  272. if FileManager.default.fileExists(atPath: self.aiInfoInputView.filePath) {
  273. let chatModel = AIChatInfoModel.init()
  274. chatModel.aiConfigType = .summarize
  275. chatModel.infoType = .chatStringResult
  276. chatModel.filePath = self.aiInfoInputView.filePath
  277. chatModel.chatInfoState = .stateLoading
  278. AIChatInfoManager.defaultManager.modelsArrM.append(chatModel)
  279. self.aiChatView.reloadData()
  280. self.aiSummarizeWithModel(chatModel)
  281. }
  282. }
  283. func aiSummarizeWithModel(_ chatModel: AIChatInfoModel) -> Void {
  284. if FileManager.default.fileExists(atPath: chatModel.filePath) {
  285. AIChatInfoManager.defaultManager.isAILoading = true
  286. //MARK: TestData
  287. // DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 13) {
  288. // DispatchQueue.main.async {
  289. // AIChatInfoManager.defaultManager.isAILoading = false
  290. // chatModel.chatResult = "AI Summary 返回的结果\nAI Summary 返回的结果\nAI Summary 返回的结果\nAI Summary 返回的结果\nAI Summary 返回的结果\nAI Summary 返回的结果\nAI Summary 返回的结果\nAI Summary 返回的结果"
  291. // chatModel.chatInfoState = .stateSuccess
  292. // self.aiChatView.reloadData()
  293. // self.aiTypeItemView.reloadData()
  294. // self.aiInfoInputView.reloadData()
  295. //
  296. // DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 14) {
  297. // DispatchQueue.main.async {
  298. // chatModel.chatInfoState = .stateFailed
  299. // chatModel.chatResult = "Unknown error"
  300. //
  301. // self.aiChatView.reloadData()
  302. // self.aiTypeItemView.reloadData()
  303. // self.aiInfoInputView.reloadData()
  304. // }
  305. // }
  306. // }
  307. // }
  308. //MARK: 正式数据
  309. KMAIRequestServerManager.defaultManager.aiAction(content: chatModel.filePath, state: .extractSummaryFile) { wrapper in
  310. DispatchQueue.main.async {
  311. AIChatInfoManager.defaultManager.isAILoading = false
  312. let resultStr = wrapper.content
  313. chatModel.chatResult = resultStr
  314. chatModel.chatInfoState = wrapper.success ? .stateSuccess : .stateFailed
  315. self.aiChatView.reloadData()
  316. self.aiTypeItemView.reloadData()
  317. self.aiInfoInputView.reloadData()
  318. }
  319. }
  320. }
  321. }
  322. func aiReWriting() -> Void {
  323. //Loading(28+155)->Finish(实际大小)
  324. let chatModel = AIChatInfoModel.init()
  325. chatModel.aiConfigType = .reWriting
  326. chatModel.infoType = .chatStringResult
  327. chatModel.uploadContent = self.aiInfoInputView.fileEmptyTextView.string
  328. chatModel.chatInfoState = .stateLoading
  329. AIChatInfoManager.defaultManager.modelsArrM.append(chatModel)
  330. self.aiChatView.reloadData()
  331. self.aiReWritingWithModel(chatModel)
  332. }
  333. func aiReWritingWithModel(_ chatModel: AIChatInfoModel) -> Void {
  334. AIChatInfoManager.defaultManager.isAILoading = true
  335. //MARK: TestData
  336. // DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
  337. // DispatchQueue.main.async {
  338. // AIChatInfoManager.defaultManager.isAILoading = false
  339. // chatModel.chatInfoState = .stateSuccess
  340. // chatModel.chatResult = "AI Rewrite返回的结果AI Rewrite返回的结果AI Rewrite返回的结果AI Rewrite返回的结果AI Rewrite返回的结果AI Rewrite返回的结果AI Rewrite返回的结果AI Rewrite返回的结果AI Rewrite返回的结果AI Rewrite返回的结果AI Rewrite返回的结果AI Rewrite返回的结果AI Rewrite返回的结果"
  341. // self.aiChatView.reloadData()
  342. // self.aiTypeItemView.reloadData()
  343. // self.aiInfoInputView.reloadData()
  344. // }
  345. // }
  346. //MARK: 正式数据
  347. KMAIRequestServerManager.defaultManager.aiAction(content: chatModel.uploadContent,
  348. state: .rewrite) { wrapper in
  349. DispatchQueue.main.async {
  350. AIChatInfoManager.defaultManager.isAILoading = false
  351. let resultStr = wrapper.content
  352. chatModel.chatResult = resultStr
  353. chatModel.chatInfoState = wrapper.success ? .stateSuccess : .stateFailed
  354. self.aiChatView.reloadData()
  355. self.aiTypeItemView.reloadData()
  356. self.aiInfoInputView.reloadData()
  357. }
  358. }
  359. }
  360. func aiProofreading() -> Void {
  361. let chatModel = AIChatInfoModel.init()
  362. chatModel.aiConfigType = .proofreading
  363. chatModel.infoType = .chatStringResult
  364. chatModel.uploadContent = self.aiInfoInputView.fileEmptyTextView.string
  365. chatModel.chatInfoState = .stateLoading
  366. AIChatInfoManager.defaultManager.modelsArrM.append(chatModel)
  367. self.aiChatView.reloadData()
  368. self.aiProofreadingWithModel(chatModel)
  369. }
  370. func aiProofreadingWithModel(_ chatModel: AIChatInfoModel) -> Void {
  371. AIChatInfoManager.defaultManager.isAILoading = true
  372. //MARK: TestData
  373. // DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
  374. // DispatchQueue.main.async {
  375. // chatModel.chatInfoState = .stateSuccess
  376. // AIChatInfoManager.defaultManager.isAILoading = false
  377. // chatModel.chatResult = "AI Proofreading 返回的结果"
  378. // self.aiChatView.reloadData()
  379. // self.aiTypeItemView.reloadData()
  380. // self.aiInfoInputView.reloadData()
  381. //
  382. // }
  383. // }
  384. //MARK: 正式数据
  385. KMAIRequestServerManager.defaultManager.aiAction(content: chatModel.uploadContent,
  386. state: .correctTypos) { wrapper in
  387. DispatchQueue.main.async {
  388. AIChatInfoManager.defaultManager.isAILoading = false
  389. let resultStr = wrapper.content
  390. chatModel.chatResult = resultStr
  391. chatModel.chatInfoState = wrapper.success ? .stateSuccess : .stateFailed
  392. self.aiChatView.reloadData()
  393. self.aiTypeItemView.reloadData()
  394. self.aiInfoInputView.reloadData()
  395. }
  396. }
  397. }
  398. func startAiTranslate() -> Void {
  399. let chatModel = AIChatInfoModel.init()
  400. chatModel.aiConfigType = .translate
  401. if self.aiInfoInputView.filePath.isEmpty {
  402. //文字
  403. chatModel.infoType = .chatTranslateResult
  404. chatModel.uploadContent = self.aiInfoInputView.fileEmptyTextView.string
  405. chatModel.filePath = ""
  406. } else {
  407. //文件
  408. chatModel.infoType = .chatTranslateResult
  409. chatModel.filePath = self.aiInfoInputView.filePath
  410. chatModel.uploadContent = ""
  411. }
  412. chatModel.translateFromLanguage = self.aiInfoInputView.fromLanguage
  413. chatModel.translateToLanguage = self.aiInfoInputView.toLanguage
  414. chatModel.chatInfoState = .stateLoading
  415. AIChatInfoManager.defaultManager.modelsArrM.append(chatModel)
  416. self.aiChatView.reloadData()
  417. self.startAiTranslateWithModel(chatModel)
  418. }
  419. func startAiTranslateWithModel(_ chatModel: AIChatInfoModel) -> Void {
  420. //MARK: TestData
  421. // DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
  422. // DispatchQueue.main.async {
  423. // chatModel.chatInfoState = .stateInfoConfirm
  424. // chatModel.chatResult = "当前翻译需要的内容:"
  425. // self.aiChatView.reloadData()
  426. //
  427. // }
  428. // }
  429. //MARK: Data
  430. if chatModel.filePath.isEmpty == true {
  431. //文字
  432. AIChatInfoManager.defaultManager.isAILoading = true
  433. KMAIRequestServerManager.defaultManager.aiAction(content: chatModel.uploadContent,
  434. state: .textTranslate,
  435. from: chatModel.translateFromLanguage,
  436. to: chatModel.translateToLanguage) { wrapper in
  437. DispatchQueue.main.async {
  438. AIChatInfoManager.defaultManager.isAILoading = false
  439. let resultStr = wrapper.content
  440. chatModel.chatResult = resultStr
  441. chatModel.chatInfoState = wrapper.success ? .stateSuccess : .stateFailed
  442. self.aiChatView.reloadData()
  443. self.aiTypeItemView.reloadData()
  444. self.aiInfoInputView.reloadData()
  445. }
  446. };
  447. } else {
  448. //文件
  449. AIChatInfoManager.defaultManager.isAILoading = true
  450. KMAIRequestServerManager.defaultManager.aiAction(content: chatModel.filePath,
  451. state: .fileTranslate,
  452. from: chatModel.translateFromLanguage,
  453. to: chatModel.translateToLanguage) { wrapper in
  454. DispatchQueue.main.async {
  455. AIChatInfoManager.defaultManager.isAILoading = false
  456. var success = wrapper.success
  457. let resultStr = wrapper.content
  458. if success == false && resultStr == "501" {
  459. success = true
  460. }
  461. if success {
  462. let infoDict: NSDictionary = wrapper.result
  463. var credit: Int = 0
  464. if infoDict["credit"] != nil {
  465. credit = (infoDict["credit"] ?? "0") as! Int
  466. }
  467. var charCount: Int = 0
  468. if infoDict["charCount"] != nil {
  469. charCount = (infoDict["charCount"] ?? "0") as! Int
  470. }
  471. chatModel.creditsValid = true
  472. if resultStr == "501" {
  473. chatModel.creditsValid = false
  474. }
  475. chatModel.costCredits = credit
  476. chatModel.totalChart = charCount
  477. chatModel.chatInfoState = .stateInfoConfirm
  478. chatModel.chatResult = resultStr
  479. self.aiChatView.reloadData()
  480. self.aiTypeItemView.reloadData()
  481. self.aiInfoInputView.reloadData()
  482. } else {
  483. chatModel.chatResult = resultStr
  484. chatModel.chatInfoState = .stateFailed
  485. self.aiChatView.reloadData()
  486. self.aiTypeItemView.reloadData()
  487. self.aiInfoInputView.reloadData()
  488. }
  489. }
  490. };
  491. }
  492. }
  493. func continueAiTranslate(_ chatModel: AIChatInfoModel) -> Void {
  494. //MARK: TestData
  495. // DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
  496. // DispatchQueue.main.async {
  497. // chatModel.chatInfoState = .stateSuccess
  498. // chatModel.chatResult = "/Users/kdanmobile/Desktop/Quick Start Guide v1.3.0.pdf"
  499. // self.aiChatView.reloadData()
  500. // self.aiTypeItemView.reloadData()
  501. // self.aiInfoInputView.reloadData()
  502. //
  503. // }
  504. // }
  505. KMAIRequestServerManager.defaultManager.aiTranslationFileTranslateHandle(fileKey: chatModel.chatResult,
  506. from: chatModel.translateFromLanguage,
  507. to: chatModel.translateToLanguage) { wrapper in
  508. DispatchQueue.main.async {
  509. AIChatInfoManager.defaultManager.isAILoading = false
  510. let resultStr = wrapper.content
  511. chatModel.chatResult = resultStr
  512. chatModel.chatInfoState = wrapper.success ? .stateSuccess : .stateFailed
  513. self.aiChatView.reloadData()
  514. self.aiTypeItemView.reloadData()
  515. self.aiInfoInputView.reloadData()
  516. }
  517. }
  518. }
  519. //MARK: AIInfoInputViewDelegate
  520. func ai_InputViewDidChooseCurFile(aiInputView: AIInfoInputView) {
  521. guard let callBack = self.chooseCurFileHandle else {
  522. return
  523. }
  524. callBack(self)
  525. }
  526. //MARK: NSWindowDelegate
  527. func windowDidBecomeMain(_ notification: Notification) {
  528. self.aiInfoInputView.reloadData()
  529. }
  530. @objc func themeChange() {
  531. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
  532. self.refreshViewColor()
  533. }
  534. }
  535. }