AINewConfigWindowController.swift 29 KB

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