TSAIListPhotoGeneratorBaseVC.swift 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. //
  2. // TSAIListPhotoGeneratorBaseVC.swift
  3. // AIEmoji
  4. //
  5. // Created by 100Years on 2025/4/9.
  6. //
  7. import Kingfisher
  8. struct TSAIListPhotoGeneratorModel {
  9. var upLoadImage:UIImage
  10. var generatorStyle:TSGeneratorImageStyle
  11. var expandEdge:UIEdgeInsets
  12. var expandViewSizes:(CGSize,CGSize)?
  13. var additionalPrompt:String//追加的提示词
  14. //预测宝宝
  15. var upLoadImages:[UIImage]?
  16. init(upLoadImage: UIImage,
  17. generatorStyle: TSGeneratorImageStyle,
  18. expandEdge:UIEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0),
  19. expandViewSizes:(CGSize,CGSize)? = nil,
  20. additionalPrompt:String = "",
  21. upLoadImages:[UIImage]? = nil
  22. ) {
  23. self.upLoadImage = upLoadImage
  24. self.generatorStyle = generatorStyle
  25. self.expandEdge = expandEdge
  26. self.expandViewSizes = expandViewSizes
  27. self.additionalPrompt = additionalPrompt
  28. self.upLoadImages = upLoadImages
  29. }
  30. }
  31. class TSAIListPhotoGeneratorBaseVC: TSAIPhotoGeneratorBaseVC {
  32. init(generatorModel:TSAIListPhotoGeneratorModel,complete:@escaping ((TSActionInfoModel)->Void)) {
  33. self.complete = complete
  34. self.viewModel = TSAIListPhotoGeneratorBaseVM(generatorModel: generatorModel)
  35. super.init()
  36. }
  37. @MainActor required init?(coder: NSCoder) {
  38. fatalError("init(coder:) has not been implemented")
  39. }
  40. var imageModel:TSActionInfoModel?
  41. var complete:((TSActionInfoModel)->Void)
  42. var progressState = TSProgressState.none
  43. var isSavePhotoMark:Bool = false
  44. var isNeedSavePhoto:Bool {
  45. if isSavePhotoMark == false,let _ = imageModel {
  46. return true
  47. }
  48. return false
  49. }
  50. var viewModel: TSAIListPhotoGeneratorBaseVM!
  51. var videoPlayerVC: TSAIListVideoPlayerVC = TSAIListVideoPlayerVC(videoURL: URL(string: "www.baidu.com")!)
  52. lazy var generateInView : TSGeneratorView = {
  53. let generateInView = TSGeneratorView()
  54. generateInView.isUploadImage = false
  55. generateInView.animationView.setText(time: String(format: "~ %d min".localized, 2), info: "Lots of people are creating images right now, so this might take a bit.".localized)
  56. generateInView.clickErrorBlock = { [weak self] style in
  57. guard let self = self else { return }
  58. switch style {
  59. case .netWorkError:
  60. clickTryAgainBtn()
  61. default:
  62. self.dismiss(animated: false, completion: nil)
  63. break
  64. }
  65. }
  66. return generateInView
  67. }()
  68. lazy var expandAreaView: TSAIExpandChangeView = {
  69. let view = TSAIExpandChangeView()
  70. return view
  71. }()
  72. lazy var switchOriginalPictureBtn: TSUIExpandedTouchButton = {
  73. let switchOriginalPictureBtn = TSUIExpandedTouchButton()
  74. switchOriginalPictureBtn.setUpButton(image:UIImage(named: "switch_original_picture"))
  75. switchOriginalPictureBtn.addTarget(self, action: #selector(switchOriginalPictureTouchDown), for: .touchDown)
  76. switchOriginalPictureBtn.addTarget(self, action: #selector(switchOriginalPictureTouchUp), for: [.touchUpInside, .touchUpOutside, .touchCancel])
  77. switchOriginalPictureBtn.isHidden = true
  78. return switchOriginalPictureBtn
  79. }()
  80. lazy var rotatingPictureBtn: TSUIExpandedTouchButton = {
  81. let rotatingPictureBtn = TSUIExpandedTouchButton()
  82. rotatingPictureBtn.setUpButton(image:UIImage(named: "rotating_picture")){ [weak self] in
  83. guard let self = self else { return }
  84. //旋转图片并储存
  85. if let image = netWorkImageView.image?.rotated(by: .degrees90) {
  86. netWorkImageView.image = image
  87. if let resultUrl = self.imageModel?.response.resultUrl,
  88. let url = URL(string: resultUrl){
  89. ImageCache.default.store(image, forKey: url.cacheKey)
  90. }
  91. }
  92. }
  93. rotatingPictureBtn.isHidden = true
  94. return rotatingPictureBtn
  95. }()
  96. override func createView() {
  97. view.addSubview(generateInView)
  98. generateInView.snp.makeConstraints { make in
  99. make.edges.equalToSuperview()
  100. }
  101. super.createView()
  102. contentView.addSubview(switchOriginalPictureBtn)
  103. switchOriginalPictureBtn.snp.makeConstraints { make in
  104. make.bottom.equalTo(-k_Height_safeAreaInsetsBottom() - 76)
  105. make.trailing.equalTo(-16)
  106. make.width.equalTo(40)
  107. make.height.equalTo(40)
  108. }
  109. contentView.addSubview(rotatingPictureBtn)
  110. rotatingPictureBtn.snp.makeConstraints { make in
  111. make.bottom.equalTo(-k_Height_safeAreaInsetsBottom() - 76)
  112. make.trailing.equalTo(-16)
  113. make.width.equalTo(40)
  114. make.height.equalTo(40)
  115. }
  116. bigSaveBtn.setTitleImageSpace(spacing: 0)
  117. if viewModel.generatorModel.generatorStyle == .photoExpand {
  118. setUpExpandAreaView()
  119. }
  120. contentView.isHidden = true
  121. }
  122. func setUpExpandAreaView(){
  123. netWorkImageView.addSubview(expandAreaView)
  124. expandAreaView.snp.makeConstraints { make in
  125. make.top.leading.trailing.bottom.equalTo(0)
  126. }
  127. expandAreaView.showImageView.isHidden = true
  128. expandAreaView.boardView.isHidden = true
  129. if let sizes = self.viewModel.generatorModel.expandViewSizes {
  130. expandAreaView.updateExpandAreaView(width: sizes.0.width, height: sizes.0.height)
  131. expandAreaView.updateImageView(width: sizes.1.width, height: sizes.1.height)
  132. }
  133. }
  134. override func closePage() {
  135. if progressState.isResult {
  136. if isNeedSavePhoto{
  137. TSCustomAlertController.show(in: self, config: TSCustomAlertController.AlertConfig(
  138. message: "You haven't saved the photo yet. Are you sure to quit?".localized,
  139. messageColor: .white,
  140. messageFont: .systemFont(ofSize: 16),
  141. cancelTitle: "Quit".localized,
  142. cancelColor: .white,
  143. confirmTitle: "Save".localized,
  144. confirmColor: .themeColor,
  145. cancelAction: { [weak self] in
  146. guard let self = self else { return }
  147. print("用户点击了Leave")
  148. viewModel.cancelAllRequest()
  149. self.dismiss(animated: true, completion: nil)
  150. },
  151. confirmAction: { [weak self] in
  152. guard let self = self else { return }
  153. print("用户点击了Stay")
  154. clickSaveBtn()
  155. }
  156. ))
  157. }else{
  158. viewModel.cancelAllRequest()
  159. self.dismiss(animated: true, completion: nil)
  160. }
  161. }else{
  162. TSCustomAlertController.show(in: self, config: TSCustomAlertController.AlertConfig(
  163. message: "As you leave, your generation will be interrupted and no result.".localized,
  164. messageColor: .white,
  165. messageFont: .systemFont(ofSize: 16),
  166. cancelTitle: "Leave".localized,
  167. cancelColor: .white,
  168. confirmTitle: "Wait".localized,
  169. confirmColor: .themeColor,
  170. cancelAction: { [weak self] in
  171. guard let self = self else { return }
  172. print("用户点击了Leave")
  173. viewModel.cancelAllRequest()
  174. self.dismiss(animated: true, completion: nil)
  175. },
  176. confirmAction: {
  177. print("用户点击了Stay")
  178. }
  179. ))
  180. }
  181. }
  182. //重试
  183. @objc override func clickTryAgainBtn(){
  184. clickRegenerateBtn()
  185. }
  186. //重新生成
  187. @objc override func clickRegenerateBtn(){
  188. //判断 vip
  189. if kJudgeVip(externalBool: kPurchaseDefault.freeNumAvailable(type: .picToPic) == false, vc: self){ return }
  190. viewModel.uploadAndCreatImage()
  191. }
  192. //保存功能
  193. @objc override func clickSaveBtn(){
  194. guard let imageModel = imageModel else { return }
  195. if viewModel.generatorModel.generatorStyle == .photoLive{
  196. TSDownloadManager.getDownLoadVideo(urlString: imageModel.response.resultUrl) { url, success in
  197. if let url = url {
  198. PhotoManagerShared.saveVideoToAlbum(videoURL: url) { [weak self] success, error in
  199. guard let self = self else { return }
  200. if success {
  201. isSavePhotoMark = true
  202. kSaveSuccesswShared.show(atView:self.view)
  203. }else{
  204. debugPrint(error)
  205. }
  206. }
  207. }
  208. }
  209. }else{
  210. UIImageView.downloadImageWithProgress(urlString: imageModel.response.resultUrl) { image in
  211. if let image = image {
  212. PhotoManagerShared.saveImageToAlbum(image) { [weak self] success, error in
  213. guard let self = self else { return }
  214. if success {
  215. isSavePhotoMark = true
  216. kSaveSuccesswShared.show(atView:self.view)
  217. kFirstSaveRateAction()
  218. }else{
  219. debugPrint(error)
  220. }
  221. }
  222. }
  223. }
  224. }
  225. }
  226. override func clickShare() {
  227. guard let imageModel = imageModel else { return }
  228. if viewModel.generatorModel.generatorStyle == .photoLive{
  229. TSDownloadManager.getDownLoadVideo(urlString: imageModel.response.resultUrl) { url, success in
  230. if let url = url {
  231. kShareContent(target: self, anyData: url)
  232. }
  233. }
  234. }else{
  235. UIImageView.downloadImageWithProgress(urlString: imageModel.response.resultUrl) { image in
  236. if let image = image {
  237. kShareContent(target: self, anyData: image)
  238. }
  239. }
  240. }
  241. }
  242. override func dealThings() {
  243. viewModel.uploadAndCreatImage()
  244. viewModel.$stateDatauPblished.receive(on: DispatchQueue.main).sink {[weak self] (state,model) in
  245. guard let self = self else { return }
  246. self.upDateView(state: state, model: model)
  247. }.store(in: &cancellable)
  248. }
  249. }
  250. extension TSAIListPhotoGeneratorBaseVC {
  251. func getSuccessImage()->UIImage?{
  252. if let image = netWorkImageView.image {
  253. return image.pngImage
  254. }
  255. return nil
  256. }
  257. }
  258. extension TSAIListPhotoGeneratorBaseVC {
  259. func upDateView(state:TSProgressState,model:TSActionInfoModel?){
  260. progressState = state
  261. switch state {
  262. case .failed(let errorStr,let code):
  263. showError(text: errorStr,code:code)
  264. case .success:
  265. if let model = model {
  266. showSuccess(model: model)
  267. }else{
  268. showError(text: "")
  269. }
  270. case .progressString(let string):
  271. showProgress(text: string)
  272. default:
  273. showLoading()
  274. }
  275. }
  276. func showProgress(text:String) {
  277. generateInView.updateShowProgress(text: text)
  278. contentView.isHidden = true
  279. // isClickTheBlankClosePage = false
  280. // bottomView.isHidden = true
  281. // netWorkImageView.isHidden = true
  282. // switchOriginalPictureBtn.isHidden = true
  283. // rotatingPictureBtn.isHidden = true
  284. setVideoHidden()
  285. }
  286. func showLoading(){
  287. generateInView.updateShowLoading(text: "Generating".localized + " ...".localized)
  288. contentView.isHidden = true
  289. // isClickTheBlankClosePage = false
  290. // bottomView.isHidden = true
  291. // netWorkImageView.isHidden = true
  292. // switchOriginalPictureBtn.isHidden = true
  293. // rotatingPictureBtn.isHidden = true
  294. setVideoHidden()
  295. }
  296. func showError(text:String,code:Int = 0){
  297. generateInView.updateShowError(text: text,code: code)
  298. contentView.isHidden = false
  299. // isClickTheBlankClosePage = true
  300. // tryAgainBtn.isHidden = false
  301. // bigSaveBtn.isHidden = true
  302. // bottomView.isHidden = true
  303. // netWorkImageView.isHidden = true
  304. // switchOriginalPictureBtn.isHidden = true
  305. // rotatingPictureBtn.isHidden = true
  306. setVideoHidden()
  307. }
  308. func showSuccess(model:TSActionInfoModel){
  309. generateInView.updateShowSuccess()
  310. contentView.isHidden = false
  311. // isClickTheBlankClosePage = true
  312. // tryAgainBtn.isHidden = false
  313. // bigSaveBtn.isHidden = false
  314. // bottomView.isHidden = false
  315. // netWorkImageView.isHidden = false
  316. imageModel = model
  317. if viewModel.generatorModel.generatorStyle == .futureBaby {
  318. rotatingPictureBtn.isHidden = false
  319. }else{
  320. switchOriginalPictureBtn.isHidden = false
  321. }
  322. isSavePhotoMark = false
  323. self.netWorkImageView.setAsyncImage(urlString: model.response.resultUrl,placeholder:kPlaceholderImage,backgroundColor:netWorkImageView.backgroundColor!)
  324. kPurchaseDefault.useOnceForFree(type: .picToPic)
  325. if let model = imageModel {
  326. complete(model)
  327. }
  328. setVideoURL()
  329. setExpandAreaImage()
  330. }
  331. @objc func switchOriginalPictureTouchDown() {
  332. if viewModel.generatorModel.generatorStyle == .photoExpand {
  333. expandAreaView.onlyBgImage(only: false)
  334. }else{
  335. self.netWorkImageView.image = self.viewModel.generatorModel.upLoadImage
  336. }
  337. }
  338. @objc func switchOriginalPictureTouchUp() {
  339. guard let imageModel = imageModel else { return }
  340. if viewModel.generatorModel.generatorStyle == .photoExpand {
  341. expandAreaView.onlyBgImage(only: true)
  342. }else{
  343. self.netWorkImageView.setAsyncImage(urlString: imageModel.response.resultUrl,placeholder:kPlaceholderImage,backgroundColor:netWorkImageView.backgroundColor!)
  344. }
  345. }
  346. }
  347. extension TSAIListPhotoGeneratorBaseVC {
  348. func setVideoHidden(){
  349. if viewModel.generatorModel.generatorStyle == .photoLive {
  350. videoPlayerVC.removeFromParent()
  351. videoPlayerVC.view.removeFromSuperview()
  352. }
  353. }
  354. func setVideoURL(){
  355. if viewModel.generatorModel.generatorStyle == .photoLive {
  356. if let model = imageModel {
  357. switchOriginalPictureBtn.isHidden = true
  358. self.videoPlayerVC = TSAIListVideoPlayerVC(videoURL: model.videoURL)
  359. self.addChild(self.videoPlayerVC)
  360. self.videoPlayerVC.view.frame = self.netWorkImageView.bounds
  361. self.netWorkImageView.addSubview(self.videoPlayerVC.view)
  362. self.videoPlayerVC.setControlsBottom(bottem: -20)
  363. }
  364. }
  365. }
  366. }
  367. extension TSAIListPhotoGeneratorBaseVC {
  368. func setExpandAreaImage(){
  369. if viewModel.generatorModel.generatorStyle == .photoExpand {
  370. netWorkImageView.image = nil
  371. expandAreaView.bgImageView.setAsyncImage(urlString: imageModel?.response.resultUrl,placeholder:kPlaceholderImage,backgroundColor:netWorkImageView.backgroundColor!)
  372. expandAreaView.showImageView.image = self.viewModel.generatorModel.upLoadImage
  373. }
  374. }
  375. }