diff --git a/AnimeGen.xcodeproj/project.xcworkspace/xcuserdata/Francesco.xcuserdatad/UserInterfaceState.xcuserstate b/AnimeGen.xcodeproj/project.xcworkspace/xcuserdata/Francesco.xcuserdatad/UserInterfaceState.xcuserstate index 3da9f9b1..96ee1220 100644 Binary files a/AnimeGen.xcodeproj/project.xcworkspace/xcuserdata/Francesco.xcuserdatad/UserInterfaceState.xcuserstate and b/AnimeGen.xcodeproj/project.xcworkspace/xcuserdata/Francesco.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/AnimeGen/APIs/Hmtai/HmtaiSender.swift b/AnimeGen/APIs/Hmtai/HmtaiSender.swift index e6f39f7e..d0cdc0df 100644 --- a/AnimeGen/APIs/Hmtai/HmtaiSender.swift +++ b/AnimeGen/APIs/Hmtai/HmtaiSender.swift @@ -5,7 +5,6 @@ // Created by cranci on 03/03/24. // -import Foundation import UIKit extension ViewController { diff --git a/AnimeGen/APIs/kyoko.swift b/AnimeGen/APIs/kyoko.swift index 1f4f2c13..c1c54449 100644 --- a/AnimeGen/APIs/kyoko.swift +++ b/AnimeGen/APIs/kyoko.swift @@ -28,24 +28,20 @@ extension ViewController { let apiEndpoint = "\(endpointPrefix)\(randomCategory)" guard let url = URL(string: apiEndpoint) else { - showAlert(withTitle: "Invalid URL", message: "Please wait, the api may be down.", viewController: self) print("Invalid URL") stopLoadingIndicator() return } - let task = URLSession.shared.dataTask(with: url) { [weak self] (data, response, error) in - guard let self = self else { return } + let task = URLSession.shared.dataTask(with: url) { (data, response, error) in DispatchQueue.main.async { if let error = error { - self.showAlert(withTitle: "Error!", message: "\(error)", viewController: self) print("Error: \(error)") self.stopLoadingIndicator() return } guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else { - self.showAlert(withTitle: "Invalid HTTP response", message: "Please wait, the api may be down.", viewController: self) print("Invalid HTTP response") self.stopLoadingIndicator() return @@ -53,25 +49,45 @@ extension ViewController { if let data = data { do { - if let jsonResponse = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any], + if let jsonResponse = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any], let requestResult = jsonResponse["RequestResult"] as? [String: Any], let imageUrlString = requestResult["url"] as? String, let imageUrl = URL(string: imageUrlString) { - - self.loadImage(from: imageUrl, withCategory: randomCategory) - + + if let imageData = try? Data(contentsOf: imageUrl) { + if imageUrlString.lowercased().hasSuffix(".gif") { + if let animatedImage = UIImage.animatedImage(with: UIImage.gifData(data: imageData) ?? [], duration: 1.0) { + self.imageView.image = animatedImage + self.animateImageChange(with: animatedImage) + self.addToHistory(image: animatedImage) + } else { + print("Failed to create animated image from GIF data.") + } + } else { + if let newImage = UIImage(data: imageData) { + self.imageView.image = newImage + self.animateImageChange(with: newImage) + self.addToHistory(image: newImage) + } else { + print("Failed to load image data.") + } + } + + self.currentImageURL = imageUrlString + self.tagsLabel.isHidden = false + self.updateUIWithTags([randomCategory]) + self.stopLoadingIndicator() + self.incrementCounter() + } else { + print("Failed to load image data.") + self.stopLoadingIndicator() + } } else { - self.showAlert(withTitle: "Error!", message: "Failed to parse JSON response or missing necessary data.", viewController: self) print("Failed to parse JSON response or missing necessary data.") self.stopLoadingIndicator() } - } catch { - self.showAlert(withTitle: "Error!", message: "Failed to parse JSON response.", viewController: self) - print("Failed to parse JSON response:", error) - self.stopLoadingIndicator() } } else { - self.showAlert(withTitle: "Error!", message: "No data received from server.", viewController: self) print("No data received from server.") self.stopLoadingIndicator() } @@ -81,57 +97,4 @@ extension ViewController { task.resume() } - func loadImage(from url: URL, withCategory category: String) { - URLSession.shared.dataTask(with: url) { [weak self] (data, response, error) in - guard let self = self else { return } - if let error = error { - self.showAlert(withTitle: "Error!", message: "\(error)", viewController: self) - print("Error loading image:", error) - self.stopLoadingIndicator() - return - } - - guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else { - self.showAlert(withTitle: "Invalid HTTP response", message: "Failed to load image.", viewController: self) - print("Invalid HTTP response") - self.stopLoadingIndicator() - return - } - - if let data = data { - DispatchQueue.main.async { - if let image = UIImage(data: data) { - if url.absoluteString.lowercased().hasSuffix(".gif") { - if let animatedImage = UIImage.animatedImage(with: UIImage.gifData(data: data) ?? [], duration: 1.0) { - self.imageView.image = animatedImage - self.addToHistory(image: animatedImage) - self.animateImageChange(with: animatedImage) - } else { - self.showAlert(withTitle: "Error!", message: "Failed to create animated image from GIF data.", viewController: self) - print("Failed to create animated image from GIF data.") - } - } else { - self.imageView.image = image - self.addToHistory(image: image) - self.animateImageChange(with: image) - } - - self.tagsLabel.isHidden = false - self.updateUIWithTags([category]) - self.currentImageURL = url.absoluteString - self.stopLoadingIndicator() - self.incrementCounter() - } else { - self.showAlert(withTitle: "Error!", message: "Failed to load image data.", viewController: self) - print("Failed to load image data.") - self.stopLoadingIndicator() - } - } - } else { - self.showAlert(withTitle: "Error!", message: "No image data received from server.", viewController: self) - print("No image data received from server.") - self.stopLoadingIndicator() - } - }.resume() - } } diff --git a/AnimeGen/APIs/nekos-best.swift b/AnimeGen/APIs/nekos-best.swift index 970e618a..9900ffd9 100644 --- a/AnimeGen/APIs/nekos-best.swift +++ b/AnimeGen/APIs/nekos-best.swift @@ -18,11 +18,6 @@ extension ViewController { let apiEndpoint = "https://nekos.best/api/v2/\(randomCategory)" guard let url = URL(string: apiEndpoint) else { - - if self.alert { - self.showAlert(withTitle: "Invalid URL", message: "Please wait, the api may be down.", viewController: self) - } - print("Invalid URL") stopLoadingIndicator() return @@ -34,33 +29,18 @@ extension ViewController { let task = URLSession.shared.dataTask(with: request) { (data, response, error) in DispatchQueue.main.async { if let error = error { - - if self.alert { - self.showAlert(withTitle: "Error!", message: "\(error)", viewController: self) - } - print("Error: \(error)") self.stopLoadingIndicator() return } guard let httpResponse = response as? HTTPURLResponse else { - - if self.alert { - self.showAlert(withTitle: "Invalid HTTP response", message: "Please wait, the api may be down.", viewController: self) - } - print("Invalid HTTP response") self.stopLoadingIndicator() return } guard httpResponse.statusCode == 200 else { - - if self.alert { - self.showAlert(withTitle: "Invalid status code", message: "\(httpResponse.statusCode)", viewController: self) - } - print("Invalid status code: \(httpResponse.statusCode)") self.stopLoadingIndicator() return @@ -86,23 +66,13 @@ extension ViewController { self.addToHistory(image: newImage) self.updateUIWithTags([], author: author, category: category) self.stopLoadingIndicator() - self.incrementCounter() } else { - - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to load image data.", viewController: self) - } - print("Failed to load image data.") self.stopLoadingIndicator() } } else { print("Failed to parse JSON response or missing necessary data.") self.stopLoadingIndicator() - - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to parse JSON response or missing data.", viewController: self) - } } } } diff --git a/AnimeGen/APIs/nekosapi.swift b/AnimeGen/APIs/nekosapi.swift index f9d504d9..97924ea5 100644 --- a/AnimeGen/APIs/nekosapi.swift +++ b/AnimeGen/APIs/nekosapi.swift @@ -23,11 +23,6 @@ extension ViewController { let apiEndpoint = "https://api.nekosapi.com/v3/images/random?limit=1&rating=\(randomRating)" guard let url = URL(string: apiEndpoint) else { - - if self.alert { - self.showAlert(withTitle: "Invalid URL", message: "Please wait, the api may be down.", viewController: self) - } - print("Invalid URL") stopLoadingIndicator() return @@ -39,33 +34,18 @@ extension ViewController { let task = URLSession.shared.dataTask(with: request) { (data, response, error) in DispatchQueue.main.async { if let error = error { - - if self.alert { - self.showAlert(withTitle: "Error!", message: "\(error)", viewController: self) - } - print("Error: \(error)") self.stopLoadingIndicator() return } guard let httpResponse = response as? HTTPURLResponse else { - - if self.alert { - self.showAlert(withTitle: "Invalid HTTP response", message: "Please wait, the api may be down.", viewController: self) - } - print("Invalid HTTP response") self.stopLoadingIndicator() return } guard httpResponse.statusCode == 200 else { - - if self.alert { - self.showAlert(withTitle: "Invalid status code", message: "\(httpResponse.statusCode)", viewController: self) - } - print("Invalid status code: \(httpResponse.statusCode)") self.stopLoadingIndicator() return @@ -87,31 +67,17 @@ extension ViewController { if let data = try? Data(contentsOf: imageUrl), let newImage = UIImage(data: data) { self.imageView.image = newImage self.animateImageChange(with: newImage) - self.addToHistory(image: newImage) - self.tagsLabel.isHidden = false - + self.addToHistory(image: newImage) self.updateUIWithTags(tags) - self.stopLoadingIndicator() - - self.incrementCounter() } else { print("Failed to load image data.") self.stopLoadingIndicator() - - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to load image data.", viewController: self) - } - } } else { print("Failed to parse JSON response or missing necessary data.") self.stopLoadingIndicator() - - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to parse JSON response or missing data.", viewController: self) - } } } } diff --git a/AnimeGen/APIs/nekosbot.swift b/AnimeGen/APIs/nekosbot.swift index c98c53e6..f45fb05f 100644 --- a/AnimeGen/APIs/nekosbot.swift +++ b/AnimeGen/APIs/nekosbot.swift @@ -12,18 +12,22 @@ extension ViewController { func loadImageFromNekoBot() { startLoadingIndicator() - let categoriesSFW: [String] = ["neko", "coffee", "food", "kemonomimi",] - let categoriesNSFW: [String] = ["hentai", "hkitsune", "hanal", "hthigh", "hboobs", "yaoi"] + let categories: [String] + let endpointPrefix: String - let isExplicitContentEnabled = UserDefaults.standard.bool(forKey: "enableExplictiCont") - let randomCategory = isExplicitContentEnabled ? categoriesNSFW.randomElement() ?? "hentai" : categoriesSFW.randomElement() ?? "hass" + if UserDefaults.standard.bool(forKey: "enableExplictiCont") { + categories = ["hentai", "hkitsune", "hanal", "hthigh", "hboobs", "yaoi"] + endpointPrefix = "https://nekobot.xyz/api/image?type=" + } else { + categories = ["neko", "coffee", "food", "kemonomimi"] + endpointPrefix = "https://nekobot.xyz/api/image?type=" + } + + let randomCategory = categories.randomElement() ?? "neko" - let apiEndpoint = "https://nekobot.xyz/api/image?type=\(randomCategory)" + let apiEndpoint = "\(endpointPrefix)\(randomCategory)" guard let url = URL(string: apiEndpoint) else { - if self.alert { - self.showAlert(withTitle: "Invalid URL", message: "Please wait, the API may be down.", viewController: self) - } print("Invalid URL") stopLoadingIndicator() return @@ -32,24 +36,19 @@ extension ViewController { let task = URLSession.shared.dataTask(with: url) { (data, response, error) in DispatchQueue.main.async { if let error = error { - if self.alert { - self.showAlert(withTitle: "Error!", message: "\(error)", viewController: self) - } print("Error: \(error)") self.stopLoadingIndicator() return } guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else { - if self.alert { - self.showAlert(withTitle: "Invalid HTTP response", message: "Please wait, the API may be down.", viewController: self) - } print("Invalid HTTP response") self.stopLoadingIndicator() return } if let data = data, let jsonResponse = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any], let imageUrlString = jsonResponse["message"] as? String, let imageUrl = URL(string: imageUrlString) { + if let imageData = try? Data(contentsOf: imageUrl) { if imageUrlString.lowercased().hasSuffix(".gif") { if let animatedImage = UIImage.animatedImage(with: UIImage.gifData(data: imageData) ?? [], duration: 1.0) { @@ -58,38 +57,25 @@ extension ViewController { self.addToHistory(image: animatedImage) } else { print("Failed to create animated image from GIF data.") - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to create animated image from GIF data.", viewController: self) - } } } else { if let newImage = UIImage(data: imageData) { self.imageView.image = newImage - self.addToHistory(image: newImage) self.animateImageChange(with: newImage) + self.addToHistory(image: newImage) } else { print("Failed to load image data.") - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to load image data.", viewController: self) - } } } self.currentImageURL = imageUrlString self.tagsLabel.isHidden = false self.updateUIWithTags([randomCategory]) self.stopLoadingIndicator() - self.incrementCounter() } else { print("Failed to load image data.") - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to load image data.", viewController: self) - } self.stopLoadingIndicator() } } else { - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to parse JSON response or missing data.", viewController: self) - } print("Failed to parse JSON response or missing necessary data.") self.stopLoadingIndicator() } diff --git a/AnimeGen/APIs/nekosmoe.swift b/AnimeGen/APIs/nekosmoe.swift index 16cdf00c..b366ba78 100644 --- a/AnimeGen/APIs/nekosmoe.swift +++ b/AnimeGen/APIs/nekosmoe.swift @@ -18,11 +18,6 @@ extension ViewController { let apiEndpoint = "https://nekos.moe/api/v1/random/image" guard var components = URLComponents(string: apiEndpoint) else { - - if self.alert { - self.showAlert(withTitle: "Invalid URL", message: "Please wait, the api may be down.", viewController: self) - } - print("Invalid URL") stopLoadingIndicator() return @@ -31,11 +26,6 @@ extension ViewController { components.queryItems = [URLQueryItem(name: "nsfw", value: isNSFW.description.lowercased())] guard let url = components.url else { - - if self.alert { - self.showAlert(withTitle: "Invalid URL", message: "Please wait, the api may be down.", viewController: self) - } - print("Invalid URL") stopLoadingIndicator() return @@ -54,11 +44,6 @@ extension ViewController { let images = jsonResponse["images"] as? [[String: Any]], let firstImage = images.first, let imageId = firstImage["id"] as? String else { - - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to get valid response.", viewController: self) - } - print("Failed to get valid response.") self.stopLoadingIndicator() return @@ -93,24 +78,13 @@ extension ViewController { let imageTask = URLSession.shared.dataTask(with: imageRequest) { (imageData, _, imageError) in DispatchQueue.main.async { if let imageError = imageError { - - if self.alert { - self.showAlert(withTitle: "Image loading error", message: "\(imageError)", viewController: self) - } - print("Image loading error: \(imageError)") } else if let imageData = imageData, let newImage = UIImage(data: imageData) { self.imageView.image = newImage - self.addToHistory(image: newImage) self.animateImageChange(with: newImage) - self.tagsLabel.isHidden = !self.moetags - self.incrementCounter() + self.addToHistory(image: newImage) + self.tagsLabel.isHidden = true } else { - - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to load image data.", viewController: self) - } - print("Failed to load image data.") } self.stopLoadingIndicator() diff --git a/AnimeGen/APIs/pic-re.swift b/AnimeGen/APIs/pic-re.swift index 64e8d087..34782d0a 100644 --- a/AnimeGen/APIs/pic-re.swift +++ b/AnimeGen/APIs/pic-re.swift @@ -11,102 +11,54 @@ extension ViewController { func loadImageFromPicRe() { startLoadingIndicator() - - let apiEndpoint = "https://pic.re/image" - - guard let url = URL(string: apiEndpoint) else { - - if self.alert { - self.showAlert(withTitle: "Invalid URL", message: "Please wait, the api may be down.", viewController: self) - } - - print("Invalid URL") - stopLoadingIndicator() - return - } - - var request = URLRequest(url: url) - request.httpMethod = "GET" - - let task = URLSession.shared.dataTask(with: request) { (data, response, error) in - if let error = error { - - if self.alert { - self.showAlert(withTitle: "Error!", message: "\(error)", viewController: self) - } - - print("Error: \(error)") + + DispatchQueue.global().async { + guard let url = URL(string: "https://pic.re/image") else { + print("Invalid URL") self.stopLoadingIndicator() return } - - guard let httpResponse = response as? HTTPURLResponse else { + + var request = URLRequest(url: url) + request.httpMethod = "GET" + + URLSession.shared.dataTask(with: request) { [weak self] (data, response, error) in + guard let self = self else { return } - if self.alert { - self.showAlert(withTitle: "Invalid HTTP response", message: "Please wait, the api may be down.", viewController: self) + if let error = error { + print("Error: \(error)") + self.stopLoadingIndicator() + return } - print("Invalid HTTP response") - self.stopLoadingIndicator() - return - } - - guard httpResponse.statusCode == 200 else { + guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else { + print("Invalid HTTP response") + self.stopLoadingIndicator() + return + } - if self.alert { - self.showAlert(withTitle: "Invalid status code", message: "\(httpResponse.statusCode)", viewController: self) + guard let data = data, + let imageTagsString = httpResponse.allHeaderFields["image_tags"] as? String, + let imageUrlString = httpResponse.allHeaderFields["image_source"] as? String, + let newImage = UIImage(data: data) else { + print("Invalid image data or missing response headers") + self.stopLoadingIndicator() + return } - print("Invalid status code: \(httpResponse.statusCode)") - self.stopLoadingIndicator() - return - } - - if let imageTagsString = httpResponse.allHeaderFields["image_tags"] as? String, - let imageUrlString = httpResponse.allHeaderFields["image_source"] as? String { let tags = imageTagsString.components(separatedBy: ",") - - self.currentImageURL = imageUrlString - + DispatchQueue.main.async { + self.currentImageURL = imageUrlString self.updateUIWithTags(tags) + self.addToHistory(image: newImage) + self.tagsLabel.isHidden = false + self.imageView.image = newImage + self.animateImageChange(with: newImage) + self.stopLoadingIndicator() } - } else { - print("No image tags found in response headers.") - - if self.alert { - self.showAlert(withTitle: "Error!", message: "No image tags found in response headers.", viewController: self) - } - - self.stopLoadingIndicator() - return - } - - guard let data = data, let newImage = UIImage(data: data) else { - print("Invalid image data") - - if self.alert { - self.showAlert(withTitle: "Error!", message: "Invalid image data.", viewController: self) - } - - self.stopLoadingIndicator() - return - } - - DispatchQueue.main.async { - - self.tagsLabel.isHidden = false - - self.addToHistory(image: newImage) - self.imageView.image = newImage - - self.animateImageChange(with: newImage) - self.stopLoadingIndicator() - - self.incrementCounter() - } + }.resume() } - - task.resume() } + } diff --git a/AnimeGen/APIs/purr.swift b/AnimeGen/APIs/purr.swift index 742aee17..5be4bccf 100644 --- a/AnimeGen/APIs/purr.swift +++ b/AnimeGen/APIs/purr.swift @@ -5,7 +5,6 @@ // Created by cranci on 16/03/24. // -import Foundation import UIKit extension ViewController { @@ -13,8 +12,8 @@ extension ViewController { func loadImageFromPurr() { startLoadingIndicator() - var categories: [String] - var endpointPrefix: String + let categories: [String] + let endpointPrefix: String if UserDefaults.standard.bool(forKey: "enableExplictiCont") { categories = ["anal/gif", "blowjob/gif", "cum/gif", "fuck/gif", "neko/gif", "pussylick/gif", "solo/gif", "solo_male/gif", "threesome_fff/gif", "threesome_ffm/gif", "threesome_mmf/gif", "yuri/gif", "neko/img"] @@ -31,11 +30,6 @@ extension ViewController { let apiEndpoint = "\(endpointPrefix)\(randomCategory)" guard let url = URL(string: apiEndpoint) else { - - if self.alert { - self.showAlert(withTitle: "Invalid URL", message: "Please wait, the api may be down.", viewController: self) - } - print("Invalid URL") stopLoadingIndicator() return @@ -44,95 +38,52 @@ extension ViewController { let task = URLSession.shared.dataTask(with: url) { (data, response, error) in DispatchQueue.main.async { if let error = error { - - if self.alert { - self.showAlert(withTitle: "Error!", message: "\(error)", viewController: self) - } - print("Error: \(error)") self.stopLoadingIndicator() return } guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else { - - if self.alert { - self.showAlert(withTitle: "Invalid HTTP response", message: "Please wait, the api may be down.", viewController: self) - } - print("Invalid HTTP response") self.stopLoadingIndicator() return } - if let data = data { - do { - if let jsonResponse = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any], - let imageUrlString = jsonResponse["link"] as? String, - let imageUrl = URL(string: imageUrlString) { - - if let imageData = try? Data(contentsOf: imageUrl) { - if imageUrlString.lowercased().hasSuffix(".gif") { - if let animatedImage = UIImage.animatedImage(with: UIImage.gifData(data: imageData) ?? [], duration: 1.0) { - self.imageView.image = animatedImage - self.addToHistory(image: animatedImage) - self.animateImageChange(with: animatedImage) - } else { - print("Failed to create animated image from GIF data.") - - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to create animated image from GIF data.", viewController: self) - } - - } - } else { - if let newImage = UIImage(data: imageData) { - self.imageView.image = newImage - self.animateImageChange(with: newImage) - self.addToHistory(image: newImage) - } else { - print("Failed to load image data.") - - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to load image data.", viewController: self) - } - } - } - - self.currentImageURL = imageUrlString - - self.tagsLabel.isHidden = false - - tag = tag.components(separatedBy: "/").first ?? "" - self.updateUIWithTags([tag]) - - self.stopLoadingIndicator() - - self.incrementCounter() + if let data = data, let jsonResponse = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any], let imageUrlString = jsonResponse["link"] as? String, let imageUrl = URL(string: imageUrlString) { + + if let imageData = try? Data(contentsOf: imageUrl) { + if imageUrlString.lowercased().hasSuffix(".gif") { + if let animatedImage = UIImage.animatedImage(with: UIImage.gifData(data: imageData) ?? [], duration: 1.0) { + self.imageView.image = animatedImage + self.animateImageChange(with: animatedImage) + self.addToHistory(image: animatedImage) } else { - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to load image data.", viewController: self) - } - print("Failed to load image data.") - self.stopLoadingIndicator() + print("Failed to create animated image from GIF data.") } } else { - - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to parse JSON response or missing data.", viewController: self) + if let newImage = UIImage(data: imageData) { + self.imageView.image = newImage + self.animateImageChange(with: newImage) + self.addToHistory(image: newImage) + } else { + print("Failed to load image data.") } - - print("Failed to parse JSON response or missing necessary data.") - self.stopLoadingIndicator() } + + self.currentImageURL = imageUrlString + + self.tagsLabel.isHidden = false + + tag = tag.components(separatedBy: "/").first ?? "" + self.updateUIWithTags([tag]) + + self.stopLoadingIndicator() + } else { + print("Failed to load image data.") + self.stopLoadingIndicator() } } else { - - if self.alert { - self.showAlert(withTitle: "Error!", message: "No data received from the server.", viewController: self) - } - - print("No data received from server.") + print("Failed to parse JSON response or missing necessary data.") self.stopLoadingIndicator() } } diff --git a/AnimeGen/APIs/waifu-im.swift b/AnimeGen/APIs/waifu-im.swift index 295786f8..49213cad 100644 --- a/AnimeGen/APIs/waifu-im.swift +++ b/AnimeGen/APIs/waifu-im.swift @@ -12,113 +12,74 @@ extension ViewController { func loadImageFromWaifuIm() { startLoadingIndicator() - let isNSFW = UserDefaults.standard.bool(forKey: "enableExplictiCont") - - let apiEndpoint = "https://api.waifu.im/search" - - var components = URLComponents(string: apiEndpoint) - components?.queryItems = [ - URLQueryItem(name: "is_nsfw", value: isNSFW ? "true" : "false") - ] - - guard let url = components?.url else { + DispatchQueue.global().async { + let isNSFW = UserDefaults.standard.bool(forKey: "enableExplictiCont") + let apiEndpoint = "https://api.waifu.im/search" - if self.alert { - self.showAlert(withTitle: "Invalid URL", message: "Please wait, the api may be down.", viewController: self) + var components = URLComponents(string: apiEndpoint) + components?.queryItems = [ + URLQueryItem(name: "is_nsfw", value: isNSFW ? "true" : "false") + ] + + guard let url = components?.url else { + print("Invalid URL") + self.stopLoadingIndicator() + return } - print("Invalid URL") - stopLoadingIndicator() - return - } - - var request = URLRequest(url: url) - request.httpMethod = "GET" - - let task = URLSession.shared.dataTask(with: request) { (data, response, error) in - DispatchQueue.main.async { - if let error = error { - - if self.alert { - self.showAlert(withTitle: "Error!", message: "\(error)", viewController: self) - } - - print("Error: \(error)") - self.stopLoadingIndicator() - return - } - - guard let httpResponse = response as? HTTPURLResponse else { - - if self.alert { - self.showAlert(withTitle: "Invalid HTTP response", message: "Please wait, the api may be down.", viewController: self) + var request = URLRequest(url: url) + request.httpMethod = "GET" + + URLSession.shared.dataTask(with: request) { [weak self] (data, response, error) in + guard let self = self else { return } + + DispatchQueue.main.async { + if let error = error { + print("Error: \(error)") + self.stopLoadingIndicator() + return } - print("Invalid HTTP response") - self.stopLoadingIndicator() - return - } - - guard httpResponse.statusCode == 200 else { - - if self.alert { - self.showAlert(withTitle: "Invalid status code", message: "\(httpResponse.statusCode)", viewController: self) + guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else { + print("Invalid HTTP response") + self.stopLoadingIndicator() + return } - print("Invalid status code: \(httpResponse.statusCode)") - self.stopLoadingIndicator() - return - } - - do { - if let jsonData = data, - let jsonResponse = try? JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any], - let images = jsonResponse["images"] as? [[String: Any]], - let firstImage = images.first, - let imageUrlString = firstImage["url"] as? String, - let imageUrl = URL(string: imageUrlString), - let tagsArray = firstImage["tags"] as? [[String: Any]] { - - self.currentImageURL = imageUrlString - - let tags = tagsArray.compactMap { $0["name"] as? String } - - if let data = try? Data(contentsOf: imageUrl), let newImage = UIImage(data: data) { - - self.imageView.image = newImage - self.animateImageChange(with: newImage) - self.addToHistory(image: newImage) + do { + if let jsonData = data, + let jsonResponse = try? JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any], + let images = jsonResponse["images"] as? [[String: Any]], + let firstImage = images.first, + let imageUrlString = firstImage["url"] as? String, + let imageUrl = URL(string: imageUrlString), + let tagsArray = firstImage["tags"] as? [[String: Any]] { - self.tagsLabel.isHidden = false - - self.updateUIWithTags(tags) + self.currentImageURL = imageUrlString - self.stopLoadingIndicator() + let tags = tagsArray.compactMap { $0["name"] as? String } - self.incrementCounter() - } else { - - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to load image data.", viewController: self) + if let data = try? Data(contentsOf: imageUrl), let newImage = UIImage(data: data) { + DispatchQueue.main.async { + self.imageView.image = newImage + self.animateImageChange(with: newImage) + self.tagsLabel.isHidden = false + self.addToHistory(image: newImage) + self.updateUIWithTags(tags) + self.stopLoadingIndicator() + } + } else { + print("Failed to load image data.") + self.stopLoadingIndicator() } - - print("Failed to load image data.") + } else { + print("Failed to parse JSON response or missing necessary data.") self.stopLoadingIndicator() } - } else { - - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to parse JSON response or missing data.", viewController: self) - } - - print("Failed to parse JSON response or missing necessary data.") - self.stopLoadingIndicator() } } - } + }.resume() } - - task.resume() } } diff --git a/AnimeGen/APIs/waifu-it.swift b/AnimeGen/APIs/waifu-it.swift index 73d3e832..d1c867f7 100644 --- a/AnimeGen/APIs/waifu-it.swift +++ b/AnimeGen/APIs/waifu-it.swift @@ -21,43 +21,28 @@ extension ViewController { categories = ["angry", "baka", "bite", "blush", "bonk", "bored", "bye", "chase", "cheer", "cringe", "cry", "cuddle", "dab", "dance", "disgust", "facepalm", "feed", "glomp", "happy", "hi", "highfive", "hold", "hug", "kick", "kiss", "laugh", "lurk", "nervous", "nom", "nope", "nuzzle", "panic", "pat", "peck", "poke", "pout", "run", "sad", "shrug", "sip", "slap", "sleepy", "smile", "smug", "stare", "tease", "think", "thumbsup", "tickle", "wag", "wave", "wink", "yes"] } - let randomCategory = categories.randomElement() ?? "pat" + let randomCategory = categories.randomElement() ?? "waifu" let apiEndpoint = "\(endpointPrefix)\(randomCategory)" guard let url = URL(string: apiEndpoint) else { - - if self.alert { - self.showAlert(withTitle: "Invalid URL", message: "Please wait, the api may be down.", viewController: self) - } - print("Invalid URL") stopLoadingIndicator() return } - + var request = URLRequest(url: url) request.setValue(Secrets.waifuItToken, forHTTPHeaderField: "Authorization") - + let task = URLSession.shared.dataTask(with: request) { (data, response, error) in DispatchQueue.main.async { if let error = error { - - if self.alert { - self.showAlert(withTitle: "Error!", message: "\(error)", viewController: self) - } - print("Error: \(error)") self.stopLoadingIndicator() return } guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else { - - if self.alert { - self.showAlert(withTitle: "Invalid HTTP response", message: "Please check your API Token.", viewController: self) - } - print("Invalid HTTP response") self.stopLoadingIndicator() return @@ -68,57 +53,32 @@ extension ViewController { if let imageData = try? Data(contentsOf: imageUrl) { if imageUrlString.lowercased().hasSuffix(".gif") { if let animatedImage = UIImage.animatedImage(with: UIImage.gifData(data: imageData) ?? [], duration: 1.0) { - self.imageView.image = animatedImage self.imageView.image = animatedImage self.animateImageChange(with: animatedImage) self.addToHistory(image: animatedImage) } else { print("Failed to create animated image from GIF data.") - - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to create animated image from GIF data.", viewController: self) - } - } } else { if let newImage = UIImage(data: imageData) { self.imageView.image = newImage - self.addToHistory(image: newImage) self.animateImageChange(with: newImage) + self.addToHistory(image: newImage) } else { print("Failed to load image data.") - - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to load image data.", viewController: self) - } - } } self.currentImageURL = imageUrlString - self.tagsLabel.isHidden = false - self.updateUIWithTags([randomCategory]) self.stopLoadingIndicator() - - self.incrementCounter() } else { print("Failed to load image data.") - - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to load image data.", viewController: self) - } - self.stopLoadingIndicator() } } else { - - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to parse JSON response or missing data.", viewController: self) - } - print("Failed to parse JSON response or missing necessary data.") self.stopLoadingIndicator() } @@ -127,5 +87,4 @@ extension ViewController { task.resume() } - } diff --git a/AnimeGen/APIs/waifu-pics.swift b/AnimeGen/APIs/waifu-pics.swift index e0c86281..01759f26 100644 --- a/AnimeGen/APIs/waifu-pics.swift +++ b/AnimeGen/APIs/waifu-pics.swift @@ -28,11 +28,6 @@ extension ViewController { let apiEndpoint = "\(endpointPrefix)\(randomCategory)" guard let url = URL(string: apiEndpoint) else { - - if self.alert { - self.showAlert(withTitle: "Invalid URL", message: "Please wait, the api may be down.", viewController: self) - } - print("Invalid URL") stopLoadingIndicator() return @@ -41,22 +36,12 @@ extension ViewController { let task = URLSession.shared.dataTask(with: url) { (data, response, error) in DispatchQueue.main.async { if let error = error { - - if self.alert { - self.showAlert(withTitle: "Error!", message: "\(error)", viewController: self) - } - print("Error: \(error)") self.stopLoadingIndicator() return } guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else { - - if self.alert { - self.showAlert(withTitle: "Invalid HTTP response", message: "Please wait, the api may be down.", viewController: self) - } - print("Invalid HTTP response") self.stopLoadingIndicator() return @@ -68,57 +53,31 @@ extension ViewController { if imageUrlString.lowercased().hasSuffix(".gif") { if let animatedImage = UIImage.animatedImage(with: UIImage.gifData(data: imageData) ?? [], duration: 1.0) { self.imageView.image = animatedImage - self.imageView.image = animatedImage - self.addToHistory(image: animatedImage) self.animateImageChange(with: animatedImage) + self.addToHistory(image: animatedImage) } else { print("Failed to create animated image from GIF data.") - - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to create animated image from GIF data.", viewController: self) - } - } } else { if let newImage = UIImage(data: imageData) { self.imageView.image = newImage - self.addToHistory(image: newImage) self.animateImageChange(with: newImage) + self.addToHistory(image: newImage) } else { print("Failed to load image data.") - - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to load image data.", viewController: self) - } - } } - self.currentImageURL = imageUrlString - self.tagsLabel.isHidden = false - self.updateUIWithTags([randomCategory]) - self.stopLoadingIndicator() - - self.incrementCounter() } else { print("Failed to load image data.") - - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to load image data.", viewController: self) - } - self.stopLoadingIndicator() } } else { print("Failed to parse JSON response or missing necessary data.") self.stopLoadingIndicator() - - if self.alert { - self.showAlert(withTitle: "Error!", message: "Failed to parse JSON response or missing data.", viewController: self) - } } } } diff --git a/AnimeGen/Buttons/Refresh-API-Button.swift b/AnimeGen/Buttons/Refresh-API-Button.swift index 9d58407c..a5782eed 100644 --- a/AnimeGen/Buttons/Refresh-API-Button.swift +++ b/AnimeGen/Buttons/Refresh-API-Button.swift @@ -64,6 +64,9 @@ extension ViewController { case "NekoBot": lastImage = imageView.image loadImageFromNekoBot() + case "Hmtai": + lastImage = imageView.image + startHmtaiLoader() default: break } @@ -71,8 +74,15 @@ extension ViewController { @objc func apiButtonTapped() { let alertController = UIAlertController(title: "Select API", message: nil, preferredStyle: .actionSheet) - - let apiOptions = ["Purr", "kyoko", "NekoBot", "nekos.moe", "Nekos api", "nekos.best", "waifu.it", "waifu.pics", "waifu.im", "pic.re"] + + var apiOptions: [String] + + if hmtaiON { + apiOptions = ["Purr", "kyoko", "NekoBot", "nekos.moe", "Nekos api", "nekos.best", "Hmtai", "waifu.it", "waifu.pics", "waifu.im", "pic.re"] + } else { + apiOptions = ["Purr", "kyoko", "NekoBot", "nekos.moe", "Nekos api", "nekos.best", "waifu.it", "waifu.pics", "waifu.im", "pic.re"] + } + for option in apiOptions { let action = UIAlertAction(title: option, style: .default) { _ in self.apiButton.setTitle(option, for: .normal) diff --git a/AnimeGen/Settings/App Settings/Developer.swift b/AnimeGen/Settings/App Settings/Developer.swift index 3d158b85..9f468439 100644 --- a/AnimeGen/Settings/App Settings/Developer.swift +++ b/AnimeGen/Settings/App Settings/Developer.swift @@ -12,6 +12,7 @@ struct DeveloperPref: View { // Devloper Mode @State private var developerMode = UserDefaults.standard.bool(forKey: "enableDeveloperMode") @State private var developerAlert = UserDefaults.standard.bool(forKey: "enableDeveloperAlert") + @State private var hmtaidev = UserDefaults.standard.bool(forKey: "enabledHmtaiAPI") var body: some View { NavigationView { @@ -50,6 +51,15 @@ struct DeveloperPref: View { } } + if UserDefaults.standard.bool(forKey: "enableDeveloperMode") { + Toggle("Display Hmtai API", isOn: Binding( + get: { UserDefaults.standard.bool(forKey: "enabledHmtaiAPI") }, + set: { newValue in + UserDefaults.standard.set(newValue, forKey: "enabledHmtaiAPI") + } + )) + } + } } .navigationBarHidden(true) diff --git a/AnimeGen/ViewController.swift b/AnimeGen/ViewController.swift index ebdcf680..a7ef44e4 100644 --- a/AnimeGen/ViewController.swift +++ b/AnimeGen/ViewController.swift @@ -45,6 +45,7 @@ class ViewController: UIViewController { var kyokobanner = UserDefaults.standard.bool(forKey: "enableKyokobanner") var alert = UserDefaults.standard.bool(forKey: "enableDeveloperAlert") + var hmtaiON = UserDefaults.standard.bool(forKey: "enabledHmtaiAPI") let choices = ["waifu.im", "pic.re", "waifu.pics", "waifu.it", "nekos.best", "Nekos api", "nekos.moe", "NekoBot", "kyoko", "Purr"] @@ -360,6 +361,8 @@ class ViewController: UIViewController { loadImageFromPurr() case "NekoBot": loadImageFromNekoBot() + case "Hmtai": + startHmtaiLoader() default: break diff --git a/README.md b/README.md index 77e5599f..46f384a5 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ Here, you can access the IPA file for installation via TrollStore, AltStore, or | [Hmtai](https://hmtai.hatsunia.cfd/endpoints) | SFW/NSFW | IMG/GIF | ⚠️ | | [Nekos api](https://nekosapi.com/docs) | SFW/NSFW | IMG | ✅ | | [Nekos.moe](https://docs.nekos.moe) | SFW/NSFW | IMG | ✅ | -| [Kyoko](https://api.rei.my.id/docs/ANIME/WAIFU-Generator/) | SFW/NSFW | IMG/GIF | ✅ | +| [Kyoko](https://api.rei.my.id/docs/ANIME/WAIFU-Generator/) | SFW/NSFW | IMG/GIF | :x: | | [Purr Bot](https://purrbot.site/) | SFW/NSFW | IMG/GIF | ✅ | | [Waifu.it](https://waifu.it/) | SFW/NSFW | IMG/GIF | ✅ | | [NekoBot](https://nekobot.xyz/) | SFW/NSFW | IMG/GIF | ✅ |