AINewConfigController.swift 27 KB

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