123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412 |
- //
- // TSAIGenerateVC.swift
- // AIEmoji
- //
- // Created by 100Years on 2025/6/24.
- //
- class TSAIGenerateVC: TSAIGenerateBaseVC {
- var reloadViewBlock: (() -> Void)?
- var changeImageBlock: ((UIImage) -> Void)?
- var progressState = TSProgressState.none
- var isSavePhotoMark: Bool = false
- var isNeedSavePhoto: Bool {
- if isSavePhotoMark == false, let _ = infoModel {
- return true
- }
- return false
- }
- var uuidString: String = UUID().uuidString
- var operation: TSGenerateBaseOperation?
- lazy var photoPickerManager: TSPhotoPickerManager = {
- let photoPickerManager = TSPhotoPickerManager(viewController: self)
- return photoPickerManager
- }()
- lazy var generateInView: TSGeneratorView = {
- let generateInView = TSGeneratorView()
- // if generatorModel.advance {
- // 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)
- // }else{
- // generateInView.animationView.setText(time: String(format: "~ %d seconds".localized, 20), info: "")
- // }
-
- let videoCategorys : [TSFuncStyle] = [.photoLive,.videoV2,.textToVideo,.pictureToVideo]
- if videoCategorys.contains(generatorModel.generatorStyle) {
- generateInView.animationView.setText(time: String(format: "~ %d min".localized, 2), info: "Lots of people are creating videos right now, so this might take a bit.".localized)
- }else{
- 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)
- }
- generateInView.clickBackstageBlock = { [weak self] in
- guard let self = self else { return }
- clickBackstageBtn()
- }
- generateInView.clickErrorBlock = { [weak self] style in
- guard let self = self else { return }
- switch style {
- case .netWorkError:
- clickTryAgainBtn()
- case .sensitiveError:
- pickSinglePhoto()
- case .generateToMax:
- clickTryAgainBtn()
- default:
- self.dismiss(animated: false, completion: nil)
- break
- }
- }
- return generateInView
- }()
- override func createView() {
- view.insertSubview(generateInView, at: 0)
- generateInView.snp.makeConstraints { make in
- make.edges.equalToSuperview()
- }
- super.createView()
- contentView.isHidden = true
- }
- override func closePage() {
- if progressState.isResult {
- if isNeedSavePhoto {
- TSCustomAlertController.show(in: self, config: TSCustomAlertController.AlertConfig(
- message: "You haven't saved the photo yet. Are you sure to quit?".localized,
- messageColor: .white,
- messageFont: .systemFont(ofSize: 16),
- cancelTitle: "Quit".localized,
- cancelColor: .white,
- confirmTitle: "Save".localized,
- confirmColor: .themeColor,
- cancelAction: { [weak self] in
- guard let self = self else { return }
- print("用户点击了Leave")
- cancelDidmiss()
- },
- confirmAction: { [weak self] in
- guard let self = self else { return }
- print("用户点击了Stay")
- clickSaveBtn()
- }
- ))
- } else {
- cancelDidmiss()
- }
- } else {
- TSCustomAlertController.show(in: self, config: TSCustomAlertController.AlertConfig(
- message: "As you leave, your generation will be interrupted and no result.".localized,
- messageColor: .white,
- messageFont: .systemFont(ofSize: 16),
- cancelTitle: "Leave".localized,
- cancelColor: .white,
- confirmTitle: "Wait".localized,
- confirmColor: .themeColor,
- cancelAction: { [weak self] in
- guard let self = self else { return }
- print("用户点击了Leave")
- if let model = infoModel {
- TSRMShared.aiGenerateDB.deleteListModel(uuid: model.uuid)
- NotificationCenter.default.post(name: .kAIPhotoDataChanged, object: nil)
- }
- cancelDidmiss()
- },
- confirmAction: {
- print("用户点击了Stay")
- }
- ))
- }
- }
- func cancelDidmiss() {
- operation?.cancel()
- dismiss(animated: true, completion: nil)
- }
- // 重试
- @objc override func clickTryAgainBtn() {
- clickRegenerateBtn()
- }
- // 后台生成
- @objc func clickBackstageBtn() {
- operation?.backstageGeneration()
- NotificationCenter.default.post(name: .kAIPhotoDataChanged, object: nil)
- NotificationCenter.default.post(name: .kAIComeInBackstage, object: nil)
- dismiss(animated: true, completion: nil)
- }
- // 重新生成
- @objc override func clickRegenerateBtn() {
- // 判断 vip
- // if kJudgeVip(externalBool: kPurchaseDefault.freeNumAvailable(type: .aiGenerate) == false, vc: self) { return }
- if kJudgeVip(externalBool: kPurchaseDefault.freeNumAvailable(type: generatorModel.generatorStyle.vipFreeNumType) == false, vc: self) { return }
- infoModel?.actionStatus = .failed // 状态设为失败,走generatorCreat
- uuidString = UUID().uuidString // 设置新的uuid,新的储存数据
- generatorOperation() // 开始生成
- }
- // 保存功能
- // @objc override func clickSaveBtn(){
- // if let image = getSuccessImage() {
- // PhotoManagerShared.saveImageToAlbum(image) { success, error in
- // if success {
- // kSaveSuccesswShared.show(atView:self.view)
- //
- // self.isSavePhotoMark = true
- // }else{
- // debugPrint(error)
- // }
- // }
- // }
- // }
- // 保存功能
- @objc override func clickSaveBtn() {
- isSavePhotoMark = true
- if kJudgeVip(externalBool: true, vc: self) {
- return
- }
- guard let currentModel = infoModel else { return }
- let response = currentModel.response
- let urlString = response.resultUrl
- if currentModel.isVideo {
- TSDownloadManager.getDownLoadVideo(urlString: urlString) { url, _ in
- if let url = url {
- PhotoManagerShared.saveVideoToAlbum(videoURL: url) { success, error in
- if success {
- kSaveSuccesswShared.show(atView: self.view)
- } else {
- debugPrint(error)
- }
- }
- }
- }
- } else {
- TSImageStoreTool.downloadImageWithProgress(urlString: urlString) { image in
- if let image = image {
- PhotoManagerShared.saveImageToAlbum(image) { success, error in
- if success {
- kSaveSuccesswShared.show(atView: self.view)
- } else {
- debugPrint(error)
- }
- }
- } else { // 如果服务器取不到,直接保存当前显示的图片
- if let currentImage = self.getSuccessImage() {
- PhotoManagerShared.saveImageToAlbum(currentImage) { success, error in
- if success {
- kSaveSuccesswShared.show(atView: self.view)
- } else {
- debugPrint(error)
- }
- }
- }
- }
- }
- }
- }
- // override func clickShare() {
- // guard let image = getSuccessImage() else { return }
- // kShareContent(target: self, anyData: image)
- // }
- override func clickShare() {
- isSavePhotoMark = true
- if kJudgeVip(externalBool: true, vc: self) {
- return
- }
- guard let currentModel = infoModel else { return }
- let response = currentModel.response
- let urlString = response.resultUrl
- if currentModel.isVideo {
- TSDownloadManager.getDownLoadVideo(urlString: urlString) { url, _ in
- if let url = url {
- kShareContent(target: self, anyData: url)
- }
- }
- } else {
- TSImageStoreTool.downloadImageWithProgress(urlString: urlString) { image in
- if let image = image {
- kShareContent(target: self, anyData: image)
- } else { // 如果服务器取不到,直接保存当前显示的图片
- if let currentImage = self.getSuccessImage() {
- kShareContent(target: self, anyData: currentImage)
- }
- }
- }
- }
- }
- override func dealThings() {
- uuidString = UUID().uuidString
- generatorOperation()
- }
- func generatorOperation() {
- if let model = infoModel {
- if model.actionStatus == .failed {
- generatorCreat(oldModel: model)
- } else if model.response.resultUrl.count > 0 {
- upDateView(state: .success(model), model: model)
- return
- }
- } else {
- generatorNew()
- }
- }
- }
- extension TSAIGenerateVC {
- func generatorNew() {
- let operation: TSGenerateBasePhotoOperation = TSGenerateBasePhotoOperationQueue.shared.creatOperation(uuid: uuidString)
- self.operation = operation
- operation.$stateDatauPblished.receive(on: DispatchQueue.main).sink { [weak self] state, model in
- guard let self = self else { return }
- self.upDateView(state: state, model: model)
- }.store(in: &cancellable)
- if generatorModel.generatorStyle == .textToVideo {
- guard let actionInfoModel = operation.createActionInfoModel(generateStyleModel: generatorModel) else { return }
- generatorCreat(oldModel: actionInfoModel)
- } else {
- operation.uploadImage(generateStyleModel: generatorModel) { [weak self] actionInfoModel in
- guard let self = self else { return }
- guard let oldModel = actionInfoModel else { return }
- generatorCreat(oldModel: oldModel)
- }
- }
- }
- func generatorCreat(oldModel: TSActionInfoModel) {
- let operation: TSGenerateBasePhotoOperation = TSGenerateBasePhotoOperationQueue.shared.creatOperation(uuid: uuidString)
- self.operation = operation
- operation.$stateDatauPblished.receive(on: DispatchQueue.main).sink { [weak self] state, model in
- guard let self = self else { return }
- self.upDateView(state: state, model: model)
- }.store(in: &cancellable)
- operation.generateStyleModel = generatorModel
- operation.creatImage(oldModel: oldModel) { [weak self] success in
- guard let self = self else { return }
- if success {
- generateInView.setBackgroundGenerateBtnHidden(false)
- }
- }
- }
- }
- extension TSAIGenerateVC {
- func pickSinglePhoto() {
- photoPickerManager.pickCustomSinglePhoto { [weak self] image, errorString in
- guard let self = self else { return }
- if let errorString = errorString {
- TSToastShared.showToast(text: errorString)
- } else {
- if let image = image {
- changeImageBlock?(image)
- generatorModel.upLoadImage = image
- generatorModel.upLoadImageUrl = nil
- generatorNew()
- }
- }
- kDelayMainShort {
- self.photoPickerManager.dismissPageVC()
- }
- }
- }
- func getSuccessImage() -> UIImage? {
- if let image = netWorkImageView.image {
- return image.pngImage
- }
- return nil
- }
- }
- extension TSAIGenerateVC {
- func upDateView(state: TSProgressState, model: TSActionInfoModel?) {
- progressState = state
- switch state {
- case let .failed(errorStr, code):
- if handleGenerateToMax(code: code,completion: { [weak self] in
- guard let self = self else { return }
- self.showError(text: errorStr, code: code)
- }){}else {
- showError(text: errorStr, code: code)
- }
- case .success:
- if let model = model {
- showSuccess(model: model)
- } else {
- showError(text: "")
- }
- case let .progressString(string):
- showProgress(text: string)
- case .none:
- break
- default:
- showLoading()
- }
- }
- func showProgress(text: String) {
- generateInView.updateShowProgress(text: text)
- contentView.isHidden = true
- }
- func showLoading() {
- generateInView.updateShowLoading(text: "Generating".localized + " " + kPercentlocalized(0))
- contentView.isHidden = true
- }
- func showError(text: String, code: Int = 0) {
- generateInView.updateShowError(text: text, code: code)
- contentView.isHidden = true
- xBtn.isHidden = false
- }
- func showSuccess(model: TSActionInfoModel) {
- generateInView.updateShowSuccess()
- contentView.isHidden = false
- xBtn.isHidden = false
- switchOriginalPictureBtn.isHidden = isHiddenSwitch
- infoModel = model
- if let model = infoModel {
- model.request.inputText = generatorModel.inputText
- complete(model)
- }
- kFirstSaveRateAction()
- }
- }
- extension TSAIGenerateVC {
-
- func handleGenerateToMax(code:Int,completion: (() -> Void)? = nil) -> Bool {
- //如果是vip次数超限,则主动触发,让 vc去谈起购买次数的弹窗
- let style = TSNetWorkCode.getGeneratorStyle(code: code)
- if style == .generateToMax{
- kPresentModalVC(target: self, modelVC: TSPurchaseVideoTimesVC(isShowAlertModel: true),transitionStyle:.crossDissolve,completion: completion)
- return true
- }
-
- return false
- }
- }
|