|
@@ -13,7 +13,7 @@
|
|
// (at your option) any later version.
|
|
// (at your option) any later version.
|
|
//
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// This program is distributed in the hope that it will be useful,
|
|
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
|
+// but WITHOUT ANY WARRANTY without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
// GNU General Public License for more details.
|
|
//
|
|
//
|
|
@@ -27,6 +27,7 @@ import PDFKit
|
|
import Accelerate
|
|
import Accelerate
|
|
import CoreMedia
|
|
import CoreMedia
|
|
import Photos
|
|
import Photos
|
|
|
|
+import Alamofire
|
|
|
|
|
|
#if !EXTENSION
|
|
#if !EXTENSION
|
|
import SVGKit
|
|
import SVGKit
|
|
@@ -40,37 +41,37 @@ class NCUtility: NSObject {
|
|
|
|
|
|
#if !EXTENSION
|
|
#if !EXTENSION
|
|
func convertSVGtoPNGWriteToUserData(svgUrlString: String, fileName: String? = nil, width: CGFloat? = nil, rewrite: Bool, account: String, id: Int? = nil, completion: @escaping (_ imageNamePath: String?, _ id: Int?) -> Void) {
|
|
func convertSVGtoPNGWriteToUserData(svgUrlString: String, fileName: String? = nil, width: CGFloat? = nil, rewrite: Bool, account: String, id: Int? = nil, completion: @escaping (_ imageNamePath: String?, _ id: Int?) -> Void) {
|
|
-
|
|
|
|
|
|
+
|
|
var fileNamePNG = ""
|
|
var fileNamePNG = ""
|
|
-
|
|
|
|
|
|
+
|
|
guard let svgUrlString = svgUrlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
|
|
guard let svgUrlString = svgUrlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
|
|
let iconURL = URL(string: svgUrlString) else {
|
|
let iconURL = URL(string: svgUrlString) else {
|
|
return completion(nil, id)
|
|
return completion(nil, id)
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
if let fileName = fileName {
|
|
if let fileName = fileName {
|
|
fileNamePNG = fileName
|
|
fileNamePNG = fileName
|
|
} else {
|
|
} else {
|
|
fileNamePNG = iconURL.deletingPathExtension().lastPathComponent + ".png"
|
|
fileNamePNG = iconURL.deletingPathExtension().lastPathComponent + ".png"
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
let imageNamePath = CCUtility.getDirectoryUserData() + "/" + fileNamePNG
|
|
let imageNamePath = CCUtility.getDirectoryUserData() + "/" + fileNamePNG
|
|
-
|
|
|
|
|
|
+
|
|
if !FileManager.default.fileExists(atPath: imageNamePath) || rewrite == true {
|
|
if !FileManager.default.fileExists(atPath: imageNamePath) || rewrite == true {
|
|
-
|
|
|
|
|
|
+
|
|
NextcloudKit.shared.downloadContent(serverUrl: iconURL.absoluteString) { _, data, error in
|
|
NextcloudKit.shared.downloadContent(serverUrl: iconURL.absoluteString) { _, data, error in
|
|
-
|
|
|
|
|
|
+
|
|
if error == .success && data != nil {
|
|
if error == .success && data != nil {
|
|
-
|
|
|
|
|
|
+
|
|
if let image = UIImage(data: data!) {
|
|
if let image = UIImage(data: data!) {
|
|
-
|
|
|
|
|
|
+
|
|
var newImage: UIImage = image
|
|
var newImage: UIImage = image
|
|
-
|
|
|
|
|
|
+
|
|
if width != nil {
|
|
if width != nil {
|
|
-
|
|
|
|
|
|
+
|
|
let ratio = image.size.height / image.size.width
|
|
let ratio = image.size.height / image.size.width
|
|
let newSize = CGSize(width: width!, height: width! * ratio)
|
|
let newSize = CGSize(width: width!, height: width! * ratio)
|
|
-
|
|
|
|
|
|
+
|
|
let renderFormat = UIGraphicsImageRendererFormat.default()
|
|
let renderFormat = UIGraphicsImageRendererFormat.default()
|
|
renderFormat.opaque = false
|
|
renderFormat.opaque = false
|
|
let renderer = UIGraphicsImageRenderer(size: CGSize(width: newSize.width, height: newSize.height), format: renderFormat)
|
|
let renderer = UIGraphicsImageRenderer(size: CGSize(width: newSize.width, height: newSize.height), format: renderFormat)
|
|
@@ -79,108 +80,108 @@ class NCUtility: NSObject {
|
|
image.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
|
|
image.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
guard let pngImageData = newImage.pngData() else {
|
|
guard let pngImageData = newImage.pngData() else {
|
|
return completion(nil, id)
|
|
return completion(nil, id)
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
try? pngImageData.write(to: URL(fileURLWithPath: imageNamePath))
|
|
try? pngImageData.write(to: URL(fileURLWithPath: imageNamePath))
|
|
-
|
|
|
|
|
|
+
|
|
return completion(imageNamePath, id)
|
|
return completion(imageNamePath, id)
|
|
-
|
|
|
|
|
|
+
|
|
} else {
|
|
} else {
|
|
-
|
|
|
|
|
|
+
|
|
guard let svgImage: SVGKImage = SVGKImage(data: data) else {
|
|
guard let svgImage: SVGKImage = SVGKImage(data: data) else {
|
|
return completion(nil, id)
|
|
return completion(nil, id)
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
if width != nil {
|
|
if width != nil {
|
|
let scale = svgImage.size.height / svgImage.size.width
|
|
let scale = svgImage.size.height / svgImage.size.width
|
|
svgImage.size = CGSize(width: width!, height: width! * scale)
|
|
svgImage.size = CGSize(width: width!, height: width! * scale)
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
guard let image: UIImage = svgImage.uiImage else {
|
|
guard let image: UIImage = svgImage.uiImage else {
|
|
return completion(nil, id)
|
|
return completion(nil, id)
|
|
}
|
|
}
|
|
guard let pngImageData = image.pngData() else {
|
|
guard let pngImageData = image.pngData() else {
|
|
return completion(nil, id)
|
|
return completion(nil, id)
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
try? pngImageData.write(to: URL(fileURLWithPath: imageNamePath))
|
|
try? pngImageData.write(to: URL(fileURLWithPath: imageNamePath))
|
|
-
|
|
|
|
|
|
+
|
|
return completion(imageNamePath, id)
|
|
return completion(imageNamePath, id)
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
return completion(nil, id)
|
|
return completion(nil, id)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
} else {
|
|
} else {
|
|
return completion(imageNamePath, id)
|
|
return completion(imageNamePath, id)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
-
|
|
|
|
|
|
+
|
|
@objc func isSimulatorOrTestFlight() -> Bool {
|
|
@objc func isSimulatorOrTestFlight() -> Bool {
|
|
guard let path = Bundle.main.appStoreReceiptURL?.path else {
|
|
guard let path = Bundle.main.appStoreReceiptURL?.path else {
|
|
return false
|
|
return false
|
|
}
|
|
}
|
|
return path.contains("CoreSimulator") || path.contains("sandboxReceipt")
|
|
return path.contains("CoreSimulator") || path.contains("sandboxReceipt")
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
@objc func isSimulator() -> Bool {
|
|
@objc func isSimulator() -> Bool {
|
|
guard let path = Bundle.main.appStoreReceiptURL?.path else {
|
|
guard let path = Bundle.main.appStoreReceiptURL?.path else {
|
|
return false
|
|
return false
|
|
}
|
|
}
|
|
return path.contains("CoreSimulator")
|
|
return path.contains("CoreSimulator")
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
@objc func isRichDocument(_ metadata: tableMetadata) -> Bool {
|
|
@objc func isRichDocument(_ metadata: tableMetadata) -> Bool {
|
|
-
|
|
|
|
|
|
+
|
|
guard let mimeType = CCUtility.getMimeType(metadata.fileNameView) else {
|
|
guard let mimeType = CCUtility.getMimeType(metadata.fileNameView) else {
|
|
return false
|
|
return false
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
// contentype
|
|
// contentype
|
|
for richdocumentMimetype: String in NCGlobal.shared.capabilityRichdocumentsMimetypes {
|
|
for richdocumentMimetype: String in NCGlobal.shared.capabilityRichdocumentsMimetypes {
|
|
if richdocumentMimetype.contains(metadata.contentType) || metadata.contentType == "text/plain" {
|
|
if richdocumentMimetype.contains(metadata.contentType) || metadata.contentType == "text/plain" {
|
|
return true
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
// mimetype
|
|
// mimetype
|
|
if NCGlobal.shared.capabilityRichdocumentsMimetypes.count > 0 && mimeType.components(separatedBy: ".").count > 2 {
|
|
if NCGlobal.shared.capabilityRichdocumentsMimetypes.count > 0 && mimeType.components(separatedBy: ".").count > 2 {
|
|
-
|
|
|
|
|
|
+
|
|
let mimeTypeArray = mimeType.components(separatedBy: ".")
|
|
let mimeTypeArray = mimeType.components(separatedBy: ".")
|
|
let mimeType = mimeTypeArray[mimeTypeArray.count - 2] + "." + mimeTypeArray[mimeTypeArray.count - 1]
|
|
let mimeType = mimeTypeArray[mimeTypeArray.count - 2] + "." + mimeTypeArray[mimeTypeArray.count - 1]
|
|
-
|
|
|
|
|
|
+
|
|
for richdocumentMimetype: String in NCGlobal.shared.capabilityRichdocumentsMimetypes {
|
|
for richdocumentMimetype: String in NCGlobal.shared.capabilityRichdocumentsMimetypes {
|
|
if richdocumentMimetype.contains(mimeType) {
|
|
if richdocumentMimetype.contains(mimeType) {
|
|
return true
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
return false
|
|
return false
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
@objc func isDirectEditing(account: String, contentType: String) -> [String] {
|
|
@objc func isDirectEditing(account: String, contentType: String) -> [String] {
|
|
-
|
|
|
|
|
|
+
|
|
var editor: [String] = []
|
|
var editor: [String] = []
|
|
-
|
|
|
|
|
|
+
|
|
guard let results = NCManageDatabase.shared.getDirectEditingEditors(account: account) else {
|
|
guard let results = NCManageDatabase.shared.getDirectEditingEditors(account: account) else {
|
|
return editor
|
|
return editor
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
for result: tableDirectEditingEditors in results {
|
|
for result: tableDirectEditingEditors in results {
|
|
for mimetype in result.mimetypes {
|
|
for mimetype in result.mimetypes {
|
|
if mimetype == contentType {
|
|
if mimetype == contentType {
|
|
editor.append(result.editor)
|
|
editor.append(result.editor)
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
// HARDCODE
|
|
// HARDCODE
|
|
// https://github.com/nextcloud/text/issues/913
|
|
// https://github.com/nextcloud/text/issues/913
|
|
-
|
|
|
|
|
|
+
|
|
if mimetype == "text/markdown" && contentType == "text/x-markdown" {
|
|
if mimetype == "text/markdown" && contentType == "text/x-markdown" {
|
|
editor.append(result.editor)
|
|
editor.append(result.editor)
|
|
}
|
|
}
|
|
@@ -194,37 +195,37 @@ class NCUtility: NSObject {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
// HARDCODE
|
|
// HARDCODE
|
|
// if editor.count == 0 {
|
|
// if editor.count == 0 {
|
|
// editor.append(NCGlobal.shared.editorText)
|
|
// editor.append(NCGlobal.shared.editorText)
|
|
// }
|
|
// }
|
|
-
|
|
|
|
|
|
+
|
|
return Array(Set(editor))
|
|
return Array(Set(editor))
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
#if !EXTENSION
|
|
#if !EXTENSION
|
|
@objc func removeAllSettings() {
|
|
@objc func removeAllSettings() {
|
|
-
|
|
|
|
|
|
+
|
|
URLCache.shared.memoryCapacity = 0
|
|
URLCache.shared.memoryCapacity = 0
|
|
URLCache.shared.diskCapacity = 0
|
|
URLCache.shared.diskCapacity = 0
|
|
-
|
|
|
|
|
|
+
|
|
NCManageDatabase.shared.clearDatabase(account: nil, removeAccount: true)
|
|
NCManageDatabase.shared.clearDatabase(account: nil, removeAccount: true)
|
|
-
|
|
|
|
|
|
+
|
|
CCUtility.removeGroupDirectoryProviderStorage()
|
|
CCUtility.removeGroupDirectoryProviderStorage()
|
|
CCUtility.removeGroupLibraryDirectory()
|
|
CCUtility.removeGroupLibraryDirectory()
|
|
-
|
|
|
|
|
|
+
|
|
CCUtility.removeDocumentsDirectory()
|
|
CCUtility.removeDocumentsDirectory()
|
|
CCUtility.removeTemporaryDirectory()
|
|
CCUtility.removeTemporaryDirectory()
|
|
-
|
|
|
|
|
|
+
|
|
CCUtility.createDirectoryStandard()
|
|
CCUtility.createDirectoryStandard()
|
|
-
|
|
|
|
|
|
+
|
|
CCUtility.deleteAllChainStore()
|
|
CCUtility.deleteAllChainStore()
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
-
|
|
|
|
|
|
+
|
|
@objc func permissionsContainsString(_ metadataPermissions: String, permissions: String) -> Bool {
|
|
@objc func permissionsContainsString(_ metadataPermissions: String, permissions: String) -> Bool {
|
|
-
|
|
|
|
|
|
+
|
|
for char in permissions {
|
|
for char in permissions {
|
|
if metadataPermissions.contains(char) == false {
|
|
if metadataPermissions.contains(char) == false {
|
|
return false
|
|
return false
|
|
@@ -232,12 +233,12 @@ class NCUtility: NSObject {
|
|
}
|
|
}
|
|
return true
|
|
return true
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
@objc func getCustomUserAgentNCText() -> String {
|
|
@objc func getCustomUserAgentNCText() -> String {
|
|
let userAgent: String = CCUtility.getUserAgent()
|
|
let userAgent: String = CCUtility.getUserAgent()
|
|
if UIDevice.current.userInterfaceIdiom == .phone {
|
|
if UIDevice.current.userInterfaceIdiom == .phone {
|
|
// NOTE: Hardcoded (May 2022)
|
|
// NOTE: Hardcoded (May 2022)
|
|
- // Tested for iPhone SE (1st), iOS 12; iPhone Pro Max, iOS 15.4
|
|
|
|
|
|
+ // Tested for iPhone SE (1st), iOS 12 iPhone Pro Max, iOS 15.4
|
|
// 605.1.15 = WebKit build version
|
|
// 605.1.15 = WebKit build version
|
|
// 15E148 = frozen iOS build number according to: https://chromestatus.com/feature/4558585463832576
|
|
// 15E148 = frozen iOS build number according to: https://chromestatus.com/feature/4558585463832576
|
|
return userAgent + " " + "AppleWebKit/605.1.15 Mobile/15E148"
|
|
return userAgent + " " + "AppleWebKit/605.1.15 Mobile/15E148"
|
|
@@ -245,9 +246,9 @@ class NCUtility: NSObject {
|
|
return userAgent
|
|
return userAgent
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
@objc func getCustomUserAgentOnlyOffice() -> String {
|
|
@objc func getCustomUserAgentOnlyOffice() -> String {
|
|
-
|
|
|
|
|
|
+
|
|
let appVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString")!
|
|
let appVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString")!
|
|
if UIDevice.current.userInterfaceIdiom == .pad {
|
|
if UIDevice.current.userInterfaceIdiom == .pad {
|
|
return "Mozilla/5.0 (iPad) Nextcloud-iOS/\(appVersion)"
|
|
return "Mozilla/5.0 (iPad) Nextcloud-iOS/\(appVersion)"
|
|
@@ -255,44 +256,44 @@ class NCUtility: NSObject {
|
|
return "Mozilla/5.0 (iPhone) Mobile Nextcloud-iOS/\(appVersion)"
|
|
return "Mozilla/5.0 (iPhone) Mobile Nextcloud-iOS/\(appVersion)"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
@objc func pdfThumbnail(url: URL, width: CGFloat = 240) -> UIImage? {
|
|
@objc func pdfThumbnail(url: URL, width: CGFloat = 240) -> UIImage? {
|
|
-
|
|
|
|
|
|
+
|
|
guard let data = try? Data(contentsOf: url), let page = PDFDocument(data: data)?.page(at: 0) else {
|
|
guard let data = try? Data(contentsOf: url), let page = PDFDocument(data: data)?.page(at: 0) else {
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
let pageSize = page.bounds(for: .mediaBox)
|
|
let pageSize = page.bounds(for: .mediaBox)
|
|
let pdfScale = width / pageSize.width
|
|
let pdfScale = width / pageSize.width
|
|
-
|
|
|
|
|
|
+
|
|
// Apply if you're displaying the thumbnail on screen
|
|
// Apply if you're displaying the thumbnail on screen
|
|
let scale = UIScreen.main.scale * pdfScale
|
|
let scale = UIScreen.main.scale * pdfScale
|
|
let screenSize = CGSize(width: pageSize.width * scale, height: pageSize.height * scale)
|
|
let screenSize = CGSize(width: pageSize.width * scale, height: pageSize.height * scale)
|
|
-
|
|
|
|
|
|
+
|
|
return page.thumbnail(of: screenSize, for: .mediaBox)
|
|
return page.thumbnail(of: screenSize, for: .mediaBox)
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
@objc func isQuickLookDisplayable(metadata: tableMetadata) -> Bool {
|
|
@objc func isQuickLookDisplayable(metadata: tableMetadata) -> Bool {
|
|
return true
|
|
return true
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
@objc func ocIdToFileId(ocId: String?) -> String? {
|
|
@objc func ocIdToFileId(ocId: String?) -> String? {
|
|
-
|
|
|
|
|
|
+
|
|
guard let ocId = ocId else { return nil }
|
|
guard let ocId = ocId else { return nil }
|
|
-
|
|
|
|
|
|
+
|
|
let items = ocId.components(separatedBy: "oc")
|
|
let items = ocId.components(separatedBy: "oc")
|
|
if items.count < 2 { return nil }
|
|
if items.count < 2 { return nil }
|
|
guard let intFileId = Int(items[0]) else { return nil }
|
|
guard let intFileId = Int(items[0]) else { return nil }
|
|
return String(intFileId)
|
|
return String(intFileId)
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
func getUserStatus(userIcon: String?, userStatus: String?, userMessage: String?) -> (onlineStatus: UIImage?, statusMessage: String, descriptionMessage: String) {
|
|
func getUserStatus(userIcon: String?, userStatus: String?, userMessage: String?) -> (onlineStatus: UIImage?, statusMessage: String, descriptionMessage: String) {
|
|
-
|
|
|
|
|
|
+
|
|
var onlineStatus: UIImage?
|
|
var onlineStatus: UIImage?
|
|
var statusMessage: String = ""
|
|
var statusMessage: String = ""
|
|
var descriptionMessage: String = ""
|
|
var descriptionMessage: String = ""
|
|
var messageUserDefined: String = ""
|
|
var messageUserDefined: String = ""
|
|
-
|
|
|
|
|
|
+
|
|
if userStatus?.lowercased() == "online" {
|
|
if userStatus?.lowercased() == "online" {
|
|
onlineStatus = UIImage(named: "circle_fill")!.image(color: UIColor(red: 103.0/255.0, green: 176.0/255.0, blue: 134.0/255.0, alpha: 1.0), size: 50)
|
|
onlineStatus = UIImage(named: "circle_fill")!.image(color: UIColor(red: 103.0/255.0, green: 176.0/255.0, blue: 134.0/255.0, alpha: 1.0), size: 50)
|
|
messageUserDefined = NSLocalizedString("_online_", comment: "")
|
|
messageUserDefined = NSLocalizedString("_online_", comment: "")
|
|
@@ -311,7 +312,7 @@ class NCUtility: NSObject {
|
|
messageUserDefined = NSLocalizedString("_invisible_", comment: "")
|
|
messageUserDefined = NSLocalizedString("_invisible_", comment: "")
|
|
descriptionMessage = NSLocalizedString("_invisible_description_", comment: "")
|
|
descriptionMessage = NSLocalizedString("_invisible_description_", comment: "")
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
if let userIcon = userIcon {
|
|
if let userIcon = userIcon {
|
|
statusMessage = userIcon + " "
|
|
statusMessage = userIcon + " "
|
|
}
|
|
}
|
|
@@ -322,18 +323,18 @@ class NCUtility: NSObject {
|
|
if statusMessage == "" {
|
|
if statusMessage == "" {
|
|
statusMessage = messageUserDefined
|
|
statusMessage = messageUserDefined
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
return(onlineStatus, statusMessage, descriptionMessage)
|
|
return(onlineStatus, statusMessage, descriptionMessage)
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
func imageFromVideo(url: URL, at time: TimeInterval) -> UIImage? {
|
|
func imageFromVideo(url: URL, at time: TimeInterval) -> UIImage? {
|
|
-
|
|
|
|
|
|
+
|
|
let asset = AVURLAsset(url: url)
|
|
let asset = AVURLAsset(url: url)
|
|
let assetIG = AVAssetImageGenerator(asset: asset)
|
|
let assetIG = AVAssetImageGenerator(asset: asset)
|
|
-
|
|
|
|
|
|
+
|
|
assetIG.appliesPreferredTrackTransform = true
|
|
assetIG.appliesPreferredTrackTransform = true
|
|
assetIG.apertureMode = AVAssetImageGenerator.ApertureMode.encodedPixels
|
|
assetIG.apertureMode = AVAssetImageGenerator.ApertureMode.encodedPixels
|
|
-
|
|
|
|
|
|
+
|
|
let cmTime = CMTime(seconds: time, preferredTimescale: 60)
|
|
let cmTime = CMTime(seconds: time, preferredTimescale: 60)
|
|
let thumbnailImageRef: CGImage
|
|
let thumbnailImageRef: CGImage
|
|
do {
|
|
do {
|
|
@@ -342,19 +343,19 @@ class NCUtility: NSObject {
|
|
print("Error: \(error)")
|
|
print("Error: \(error)")
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
return UIImage(cgImage: thumbnailImageRef)
|
|
return UIImage(cgImage: thumbnailImageRef)
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
func imageFromVideo(url: URL, at time: TimeInterval, completion: @escaping (UIImage?) -> Void) {
|
|
func imageFromVideo(url: URL, at time: TimeInterval, completion: @escaping (UIImage?) -> Void) {
|
|
DispatchQueue.global().async {
|
|
DispatchQueue.global().async {
|
|
-
|
|
|
|
|
|
+
|
|
let asset = AVURLAsset(url: url)
|
|
let asset = AVURLAsset(url: url)
|
|
let assetIG = AVAssetImageGenerator(asset: asset)
|
|
let assetIG = AVAssetImageGenerator(asset: asset)
|
|
-
|
|
|
|
|
|
+
|
|
assetIG.appliesPreferredTrackTransform = true
|
|
assetIG.appliesPreferredTrackTransform = true
|
|
assetIG.apertureMode = AVAssetImageGenerator.ApertureMode.encodedPixels
|
|
assetIG.apertureMode = AVAssetImageGenerator.ApertureMode.encodedPixels
|
|
-
|
|
|
|
|
|
+
|
|
let cmTime = CMTime(seconds: time, preferredTimescale: 60)
|
|
let cmTime = CMTime(seconds: time, preferredTimescale: 60)
|
|
let thumbnailImageRef: CGImage
|
|
let thumbnailImageRef: CGImage
|
|
do {
|
|
do {
|
|
@@ -363,46 +364,46 @@ class NCUtility: NSObject {
|
|
print("Error: \(error)")
|
|
print("Error: \(error)")
|
|
return completion(nil)
|
|
return completion(nil)
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
DispatchQueue.main.async {
|
|
DispatchQueue.main.async {
|
|
completion(UIImage(cgImage: thumbnailImageRef))
|
|
completion(UIImage(cgImage: thumbnailImageRef))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
func createImageFrom(fileNameView: String, ocId: String, etag: String, classFile: String) {
|
|
func createImageFrom(fileNameView: String, ocId: String, etag: String, classFile: String) {
|
|
-
|
|
|
|
|
|
+
|
|
var originalImage, scaleImagePreview, scaleImageIcon: UIImage?
|
|
var originalImage, scaleImagePreview, scaleImageIcon: UIImage?
|
|
-
|
|
|
|
|
|
+
|
|
let fileNamePath = CCUtility.getDirectoryProviderStorageOcId(ocId, fileNameView: fileNameView)!
|
|
let fileNamePath = CCUtility.getDirectoryProviderStorageOcId(ocId, fileNameView: fileNameView)!
|
|
let fileNamePathPreview = CCUtility.getDirectoryProviderStoragePreviewOcId(ocId, etag: etag)!
|
|
let fileNamePathPreview = CCUtility.getDirectoryProviderStoragePreviewOcId(ocId, etag: etag)!
|
|
let fileNamePathIcon = CCUtility.getDirectoryProviderStorageIconOcId(ocId, etag: etag)!
|
|
let fileNamePathIcon = CCUtility.getDirectoryProviderStorageIconOcId(ocId, etag: etag)!
|
|
-
|
|
|
|
|
|
+
|
|
if CCUtility.fileProviderStorageSize(ocId, fileNameView: fileNameView) > 0 && FileManager().fileExists(atPath: fileNamePathPreview) && FileManager().fileExists(atPath: fileNamePathIcon) { return }
|
|
if CCUtility.fileProviderStorageSize(ocId, fileNameView: fileNameView) > 0 && FileManager().fileExists(atPath: fileNamePathPreview) && FileManager().fileExists(atPath: fileNamePathIcon) { return }
|
|
if classFile != NKCommon.TypeClassFile.image.rawValue && classFile != NKCommon.TypeClassFile.video.rawValue { return }
|
|
if classFile != NKCommon.TypeClassFile.image.rawValue && classFile != NKCommon.TypeClassFile.video.rawValue { return }
|
|
-
|
|
|
|
|
|
+
|
|
if classFile == NKCommon.TypeClassFile.image.rawValue {
|
|
if classFile == NKCommon.TypeClassFile.image.rawValue {
|
|
-
|
|
|
|
|
|
+
|
|
originalImage = UIImage(contentsOfFile: fileNamePath)
|
|
originalImage = UIImage(contentsOfFile: fileNamePath)
|
|
-
|
|
|
|
|
|
+
|
|
scaleImagePreview = originalImage?.resizeImage(size: CGSize(width: NCGlobal.shared.sizePreview, height: NCGlobal.shared.sizePreview))
|
|
scaleImagePreview = originalImage?.resizeImage(size: CGSize(width: NCGlobal.shared.sizePreview, height: NCGlobal.shared.sizePreview))
|
|
scaleImageIcon = originalImage?.resizeImage(size: CGSize(width: NCGlobal.shared.sizeIcon, height: NCGlobal.shared.sizeIcon))
|
|
scaleImageIcon = originalImage?.resizeImage(size: CGSize(width: NCGlobal.shared.sizeIcon, height: NCGlobal.shared.sizeIcon))
|
|
-
|
|
|
|
|
|
+
|
|
try? scaleImagePreview?.jpegData(compressionQuality: 0.7)?.write(to: URL(fileURLWithPath: fileNamePathPreview))
|
|
try? scaleImagePreview?.jpegData(compressionQuality: 0.7)?.write(to: URL(fileURLWithPath: fileNamePathPreview))
|
|
try? scaleImageIcon?.jpegData(compressionQuality: 0.7)?.write(to: URL(fileURLWithPath: fileNamePathIcon))
|
|
try? scaleImageIcon?.jpegData(compressionQuality: 0.7)?.write(to: URL(fileURLWithPath: fileNamePathIcon))
|
|
-
|
|
|
|
|
|
+
|
|
} else if classFile == NKCommon.TypeClassFile.video.rawValue {
|
|
} else if classFile == NKCommon.TypeClassFile.video.rawValue {
|
|
-
|
|
|
|
|
|
+
|
|
let videoPath = NSTemporaryDirectory()+"tempvideo.mp4"
|
|
let videoPath = NSTemporaryDirectory()+"tempvideo.mp4"
|
|
NCUtilityFileSystem.shared.linkItem(atPath: fileNamePath, toPath: videoPath)
|
|
NCUtilityFileSystem.shared.linkItem(atPath: fileNamePath, toPath: videoPath)
|
|
-
|
|
|
|
|
|
+
|
|
originalImage = imageFromVideo(url: URL(fileURLWithPath: videoPath), at: 0)
|
|
originalImage = imageFromVideo(url: URL(fileURLWithPath: videoPath), at: 0)
|
|
-
|
|
|
|
|
|
+
|
|
try? originalImage?.jpegData(compressionQuality: 0.7)?.write(to: URL(fileURLWithPath: fileNamePathPreview))
|
|
try? originalImage?.jpegData(compressionQuality: 0.7)?.write(to: URL(fileURLWithPath: fileNamePathPreview))
|
|
try? originalImage?.jpegData(compressionQuality: 0.7)?.write(to: URL(fileURLWithPath: fileNamePathIcon))
|
|
try? originalImage?.jpegData(compressionQuality: 0.7)?.write(to: URL(fileURLWithPath: fileNamePathIcon))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
@objc func getVersionApp(withBuild: Bool = true) -> String {
|
|
@objc func getVersionApp(withBuild: Bool = true) -> String {
|
|
if let dictionary = Bundle.main.infoDictionary {
|
|
if let dictionary = Bundle.main.infoDictionary {
|
|
if let version = dictionary["CFBundleShortVersionString"], let build = dictionary["CFBundleVersion"] {
|
|
if let version = dictionary["CFBundleShortVersionString"], let build = dictionary["CFBundleVersion"] {
|
|
@@ -415,11 +416,11 @@ class NCUtility: NSObject {
|
|
}
|
|
}
|
|
return ""
|
|
return ""
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
func loadImage(named imageName: String, color: UIColor = UIColor.systemGray, size: CGFloat = 50, symbolConfiguration: Any? = nil, renderingMode: UIImage.RenderingMode = .alwaysOriginal) -> UIImage {
|
|
func loadImage(named imageName: String, color: UIColor = UIColor.systemGray, size: CGFloat = 50, symbolConfiguration: Any? = nil, renderingMode: UIImage.RenderingMode = .alwaysOriginal) -> UIImage {
|
|
-
|
|
|
|
|
|
+
|
|
var image: UIImage?
|
|
var image: UIImage?
|
|
-
|
|
|
|
|
|
+
|
|
// see https://stackoverflow.com/questions/71764255
|
|
// see https://stackoverflow.com/questions/71764255
|
|
let sfSymbolName = imageName.replacingOccurrences(of: "_", with: ".")
|
|
let sfSymbolName = imageName.replacingOccurrences(of: "_", with: ".")
|
|
if let symbolConfiguration = symbolConfiguration {
|
|
if let symbolConfiguration = symbolConfiguration {
|
|
@@ -433,15 +434,15 @@ class NCUtility: NSObject {
|
|
if let image = image {
|
|
if let image = image {
|
|
return image
|
|
return image
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
return UIImage(named: "file")!.image(color: color, size: size)
|
|
return UIImage(named: "file")!.image(color: color, size: size)
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
@objc func loadUserImage(for user: String, displayName: String?, userBaseUrl: NCUserBaseUrl) -> UIImage {
|
|
@objc func loadUserImage(for user: String, displayName: String?, userBaseUrl: NCUserBaseUrl) -> UIImage {
|
|
-
|
|
|
|
|
|
+
|
|
let fileName = userBaseUrl.userBaseUrl + "-" + user + ".png"
|
|
let fileName = userBaseUrl.userBaseUrl + "-" + user + ".png"
|
|
let localFilePath = String(CCUtility.getDirectoryUserData()) + "/" + fileName
|
|
let localFilePath = String(CCUtility.getDirectoryUserData()) + "/" + fileName
|
|
-
|
|
|
|
|
|
+
|
|
if let localImage = UIImage(contentsOfFile: localFilePath) {
|
|
if let localImage = UIImage(contentsOfFile: localFilePath) {
|
|
return createAvatar(image: localImage, size: 30)
|
|
return createAvatar(image: localImage, size: 30)
|
|
} else if let loadedAvatar = NCManageDatabase.shared.getImageAvatarLoaded(fileName: fileName) {
|
|
} else if let loadedAvatar = NCManageDatabase.shared.getImageAvatarLoaded(fileName: fileName) {
|
|
@@ -450,27 +451,27 @@ class NCUtility: NSObject {
|
|
return avatarImg
|
|
return avatarImg
|
|
} else { return getDefaultUserIcon() }
|
|
} else { return getDefaultUserIcon() }
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
func getDefaultUserIcon() -> UIImage {
|
|
func getDefaultUserIcon() -> UIImage {
|
|
-
|
|
|
|
|
|
+
|
|
let config = UIImage.SymbolConfiguration(pointSize: 30)
|
|
let config = UIImage.SymbolConfiguration(pointSize: 30)
|
|
return NCUtility.shared.loadImage(named: "person.crop.circle", symbolConfiguration: config)
|
|
return NCUtility.shared.loadImage(named: "person.crop.circle", symbolConfiguration: config)
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
@objc func createAvatar(image: UIImage, size: CGFloat) -> UIImage {
|
|
@objc func createAvatar(image: UIImage, size: CGFloat) -> UIImage {
|
|
-
|
|
|
|
|
|
+
|
|
var avatarImage = image
|
|
var avatarImage = image
|
|
let rect = CGRect(x: 0, y: 0, width: size, height: size)
|
|
let rect = CGRect(x: 0, y: 0, width: size, height: size)
|
|
-
|
|
|
|
|
|
+
|
|
UIGraphicsBeginImageContextWithOptions(rect.size, false, 3.0)
|
|
UIGraphicsBeginImageContextWithOptions(rect.size, false, 3.0)
|
|
UIBezierPath(roundedRect: rect, cornerRadius: rect.size.height).addClip()
|
|
UIBezierPath(roundedRect: rect, cornerRadius: rect.size.height).addClip()
|
|
avatarImage.draw(in: rect)
|
|
avatarImage.draw(in: rect)
|
|
avatarImage = UIGraphicsGetImageFromCurrentImageContext() ?? image
|
|
avatarImage = UIGraphicsGetImageFromCurrentImageContext() ?? image
|
|
UIGraphicsEndImageContext()
|
|
UIGraphicsEndImageContext()
|
|
-
|
|
|
|
|
|
+
|
|
return avatarImage
|
|
return avatarImage
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
func createAvatar(displayName: String, size: CGFloat) -> UIImage? {
|
|
func createAvatar(displayName: String, size: CGFloat) -> UIImage? {
|
|
guard let initials = displayName.uppercaseInitials else {
|
|
guard let initials = displayName.uppercaseInitials else {
|
|
return nil
|
|
return nil
|
|
@@ -478,7 +479,7 @@ class NCUtility: NSObject {
|
|
let userColor = NCGlobal.shared.usernameToColor(displayName)
|
|
let userColor = NCGlobal.shared.usernameToColor(displayName)
|
|
let rect = CGRect(x: 0, y: 0, width: size, height: size)
|
|
let rect = CGRect(x: 0, y: 0, width: size, height: size)
|
|
var avatarImage: UIImage?
|
|
var avatarImage: UIImage?
|
|
-
|
|
|
|
|
|
+
|
|
UIGraphicsBeginImageContextWithOptions(rect.size, false, 3.0)
|
|
UIGraphicsBeginImageContextWithOptions(rect.size, false, 3.0)
|
|
let context = UIGraphicsGetCurrentContext()
|
|
let context = UIGraphicsGetCurrentContext()
|
|
UIBezierPath(roundedRect: rect, cornerRadius: rect.size.height).addClip()
|
|
UIBezierPath(roundedRect: rect, cornerRadius: rect.size.height).addClip()
|
|
@@ -493,16 +494,16 @@ class NCUtility: NSObject {
|
|
withAttributes: [NSAttributedString.Key.paragraphStyle: textStyle])
|
|
withAttributes: [NSAttributedString.Key.paragraphStyle: textStyle])
|
|
avatarImage = UIGraphicsGetImageFromCurrentImageContext()
|
|
avatarImage = UIGraphicsGetImageFromCurrentImageContext()
|
|
UIGraphicsEndImageContext()
|
|
UIGraphicsEndImageContext()
|
|
-
|
|
|
|
|
|
+
|
|
return avatarImage
|
|
return avatarImage
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
/*
|
|
/*
|
|
- Facebook's comparison algorithm:
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
|
|
+ Facebook's comparison algorithm:
|
|
|
|
+ */
|
|
|
|
+
|
|
func compare(tolerance: Float, expected: Data, observed: Data) throws -> Bool {
|
|
func compare(tolerance: Float, expected: Data, observed: Data) throws -> Bool {
|
|
-
|
|
|
|
|
|
+
|
|
enum customError: Error {
|
|
enum customError: Error {
|
|
case unableToGetUIImageFromData
|
|
case unableToGetUIImageFromData
|
|
case unableToGetCGImageFromData
|
|
case unableToGetCGImageFromData
|
|
@@ -510,7 +511,7 @@ class NCUtility: NSObject {
|
|
case imagesHasDifferentSizes
|
|
case imagesHasDifferentSizes
|
|
case unableToInitializeContext
|
|
case unableToInitializeContext
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
guard let expectedUIImage = UIImage(data: expected), let observedUIImage = UIImage(data: observed) else {
|
|
guard let expectedUIImage = UIImage(data: expected), let observedUIImage = UIImage(data: observed) else {
|
|
throw customError.unableToGetUIImageFromData
|
|
throw customError.unableToGetUIImageFromData
|
|
}
|
|
}
|
|
@@ -525,17 +526,17 @@ class NCUtility: NSObject {
|
|
}
|
|
}
|
|
let imageSize = CGSize(width: expectedCGImage.width, height: expectedCGImage.height)
|
|
let imageSize = CGSize(width: expectedCGImage.width, height: expectedCGImage.height)
|
|
let numberOfPixels = Int(imageSize.width * imageSize.height)
|
|
let numberOfPixels = Int(imageSize.width * imageSize.height)
|
|
-
|
|
|
|
|
|
+
|
|
// Checking that our `UInt32` buffer has same number of bytes as image has.
|
|
// Checking that our `UInt32` buffer has same number of bytes as image has.
|
|
let bytesPerRow = min(expectedCGImage.bytesPerRow, observedCGImage.bytesPerRow)
|
|
let bytesPerRow = min(expectedCGImage.bytesPerRow, observedCGImage.bytesPerRow)
|
|
assert(MemoryLayout<UInt32>.stride == bytesPerRow / Int(imageSize.width))
|
|
assert(MemoryLayout<UInt32>.stride == bytesPerRow / Int(imageSize.width))
|
|
-
|
|
|
|
|
|
+
|
|
let expectedPixels = UnsafeMutablePointer<UInt32>.allocate(capacity: numberOfPixels)
|
|
let expectedPixels = UnsafeMutablePointer<UInt32>.allocate(capacity: numberOfPixels)
|
|
let observedPixels = UnsafeMutablePointer<UInt32>.allocate(capacity: numberOfPixels)
|
|
let observedPixels = UnsafeMutablePointer<UInt32>.allocate(capacity: numberOfPixels)
|
|
-
|
|
|
|
|
|
+
|
|
let expectedPixelsRaw = UnsafeMutableRawPointer(expectedPixels)
|
|
let expectedPixelsRaw = UnsafeMutableRawPointer(expectedPixels)
|
|
let observedPixelsRaw = UnsafeMutableRawPointer(observedPixels)
|
|
let observedPixelsRaw = UnsafeMutableRawPointer(observedPixels)
|
|
-
|
|
|
|
|
|
+
|
|
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
|
|
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
|
|
guard let expectedContext = CGContext(data: expectedPixelsRaw, width: Int(imageSize.width), height: Int(imageSize.height),
|
|
guard let expectedContext = CGContext(data: expectedPixelsRaw, width: Int(imageSize.width), height: Int(imageSize.height),
|
|
bitsPerComponent: expectedCGImage.bitsPerComponent, bytesPerRow: bytesPerRow,
|
|
bitsPerComponent: expectedCGImage.bitsPerComponent, bytesPerRow: bytesPerRow,
|
|
@@ -551,13 +552,13 @@ class NCUtility: NSObject {
|
|
observedPixels.deallocate()
|
|
observedPixels.deallocate()
|
|
throw customError.unableToInitializeContext
|
|
throw customError.unableToInitializeContext
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
expectedContext.draw(expectedCGImage, in: CGRect(origin: .zero, size: imageSize))
|
|
expectedContext.draw(expectedCGImage, in: CGRect(origin: .zero, size: imageSize))
|
|
observedContext.draw(observedCGImage, in: CGRect(origin: .zero, size: imageSize))
|
|
observedContext.draw(observedCGImage, in: CGRect(origin: .zero, size: imageSize))
|
|
-
|
|
|
|
|
|
+
|
|
let expectedBuffer = UnsafeBufferPointer(start: expectedPixels, count: numberOfPixels)
|
|
let expectedBuffer = UnsafeBufferPointer(start: expectedPixels, count: numberOfPixels)
|
|
let observedBuffer = UnsafeBufferPointer(start: observedPixels, count: numberOfPixels)
|
|
let observedBuffer = UnsafeBufferPointer(start: observedPixels, count: numberOfPixels)
|
|
-
|
|
|
|
|
|
+
|
|
var isEqual = true
|
|
var isEqual = true
|
|
if tolerance == 0 {
|
|
if tolerance == 0 {
|
|
isEqual = expectedBuffer.elementsEqual(observedBuffer)
|
|
isEqual = expectedBuffer.elementsEqual(observedBuffer)
|
|
@@ -574,50 +575,50 @@ class NCUtility: NSObject {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
expectedPixels.deallocate()
|
|
expectedPixels.deallocate()
|
|
observedPixels.deallocate()
|
|
observedPixels.deallocate()
|
|
-
|
|
|
|
|
|
+
|
|
return isEqual
|
|
return isEqual
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
func stringFromTime(_ time: CMTime) -> String {
|
|
func stringFromTime(_ time: CMTime) -> String {
|
|
-
|
|
|
|
|
|
+
|
|
let interval = Int(CMTimeGetSeconds(time))
|
|
let interval = Int(CMTimeGetSeconds(time))
|
|
-
|
|
|
|
|
|
+
|
|
let seconds = interval % 60
|
|
let seconds = interval % 60
|
|
let minutes = (interval / 60) % 60
|
|
let minutes = (interval / 60) % 60
|
|
let hours = (interval / 3600)
|
|
let hours = (interval / 3600)
|
|
-
|
|
|
|
|
|
+
|
|
if hours > 0 {
|
|
if hours > 0 {
|
|
return String(format: "%02d:%02d:%02d", hours, minutes, seconds)
|
|
return String(format: "%02d:%02d:%02d", hours, minutes, seconds)
|
|
} else {
|
|
} else {
|
|
return String(format: "%02d:%02d", minutes, seconds)
|
|
return String(format: "%02d:%02d", minutes, seconds)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
func colorNavigationController(_ navigationController: UINavigationController?, backgroundColor: UIColor, titleColor: UIColor, tintColor: UIColor?, withoutShadow: Bool) {
|
|
func colorNavigationController(_ navigationController: UINavigationController?, backgroundColor: UIColor, titleColor: UIColor, tintColor: UIColor?, withoutShadow: Bool) {
|
|
-
|
|
|
|
|
|
+
|
|
let appearance = UINavigationBarAppearance()
|
|
let appearance = UINavigationBarAppearance()
|
|
appearance.titleTextAttributes = [.foregroundColor: titleColor]
|
|
appearance.titleTextAttributes = [.foregroundColor: titleColor]
|
|
appearance.largeTitleTextAttributes = [.foregroundColor: titleColor]
|
|
appearance.largeTitleTextAttributes = [.foregroundColor: titleColor]
|
|
-
|
|
|
|
|
|
+
|
|
if withoutShadow {
|
|
if withoutShadow {
|
|
appearance.shadowColor = .clear
|
|
appearance.shadowColor = .clear
|
|
appearance.shadowImage = UIImage()
|
|
appearance.shadowImage = UIImage()
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
if let tintColor = tintColor {
|
|
if let tintColor = tintColor {
|
|
navigationController?.navigationBar.tintColor = tintColor
|
|
navigationController?.navigationBar.tintColor = tintColor
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
navigationController?.view.backgroundColor = backgroundColor
|
|
navigationController?.view.backgroundColor = backgroundColor
|
|
navigationController?.navigationBar.barTintColor = titleColor
|
|
navigationController?.navigationBar.barTintColor = titleColor
|
|
navigationController?.navigationBar.standardAppearance = appearance
|
|
navigationController?.navigationBar.standardAppearance = appearance
|
|
navigationController?.navigationBar.compactAppearance = appearance
|
|
navigationController?.navigationBar.compactAppearance = appearance
|
|
navigationController?.navigationBar.scrollEdgeAppearance = appearance
|
|
navigationController?.navigationBar.scrollEdgeAppearance = appearance
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
func getEncondingDataType(data: Data) -> String.Encoding? {
|
|
func getEncondingDataType(data: Data) -> String.Encoding? {
|
|
if let _ = String(data: data, encoding: .utf8) {
|
|
if let _ = String(data: data, encoding: .utf8) {
|
|
return .utf8
|
|
return .utf8
|
|
@@ -687,14 +688,14 @@ class NCUtility: NSObject {
|
|
}
|
|
}
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
func SYSTEM_VERSION_LESS_THAN(version: String) -> Bool {
|
|
func SYSTEM_VERSION_LESS_THAN(version: String) -> Bool {
|
|
return UIDevice.current.systemVersion.compare(version,
|
|
return UIDevice.current.systemVersion.compare(version,
|
|
- options: NSString.CompareOptions.numeric) == ComparisonResult.orderedAscending
|
|
|
|
|
|
+ options: NSString.CompareOptions.numeric) == ComparisonResult.orderedAscending
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
func getAvatarFromIconUrl(metadata: tableMetadata) -> String? {
|
|
func getAvatarFromIconUrl(metadata: tableMetadata) -> String? {
|
|
-
|
|
|
|
|
|
+
|
|
var ownerId: String?
|
|
var ownerId: String?
|
|
if metadata.iconUrl.contains("http") && metadata.iconUrl.contains("avatar") {
|
|
if metadata.iconUrl.contains("http") && metadata.iconUrl.contains("avatar") {
|
|
let splitIconUrl = metadata.iconUrl.components(separatedBy: "/")
|
|
let splitIconUrl = metadata.iconUrl.components(separatedBy: "/")
|
|
@@ -709,7 +710,7 @@ class NCUtility: NSObject {
|
|
}
|
|
}
|
|
return ownerId
|
|
return ownerId
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
// https://stackoverflow.com/questions/25471114/how-to-validate-an-e-mail-address-in-swift
|
|
// https://stackoverflow.com/questions/25471114/how-to-validate-an-e-mail-address-in-swift
|
|
func isValidEmail(_ email: String) -> Bool {
|
|
func isValidEmail(_ email: String) -> Bool {
|
|
|
|
|
|
@@ -719,11 +720,11 @@ class NCUtility: NSObject {
|
|
}
|
|
}
|
|
|
|
|
|
func createFilePreviewImage(ocId: String, etag: String, fileNameView: String, classFile: String, status: Int, createPreviewMedia: Bool) -> UIImage? {
|
|
func createFilePreviewImage(ocId: String, etag: String, fileNameView: String, classFile: String, status: Int, createPreviewMedia: Bool) -> UIImage? {
|
|
-
|
|
|
|
|
|
+
|
|
var imagePreview: UIImage?
|
|
var imagePreview: UIImage?
|
|
let filePath = CCUtility.getDirectoryProviderStorageOcId(ocId, fileNameView: fileNameView)!
|
|
let filePath = CCUtility.getDirectoryProviderStorageOcId(ocId, fileNameView: fileNameView)!
|
|
let iconImagePath = CCUtility.getDirectoryProviderStorageIconOcId(ocId, etag: etag)!
|
|
let iconImagePath = CCUtility.getDirectoryProviderStorageIconOcId(ocId, etag: etag)!
|
|
-
|
|
|
|
|
|
+
|
|
if FileManager().fileExists(atPath: iconImagePath) {
|
|
if FileManager().fileExists(atPath: iconImagePath) {
|
|
imagePreview = UIImage(contentsOfFile: iconImagePath)
|
|
imagePreview = UIImage(contentsOfFile: iconImagePath)
|
|
} else if !createPreviewMedia {
|
|
} else if !createPreviewMedia {
|
|
@@ -743,10 +744,10 @@ class NCUtility: NSObject {
|
|
} catch { }
|
|
} catch { }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
return imagePreview
|
|
return imagePreview
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
func isDirectoryE2EE(serverUrl: String, userBase: NCUserBaseUrl) -> Bool {
|
|
func isDirectoryE2EE(serverUrl: String, userBase: NCUserBaseUrl) -> Bool {
|
|
return isDirectoryE2EE(account: userBase.account, urlBase: userBase.urlBase, userId: userBase.userId, serverUrl: serverUrl)
|
|
return isDirectoryE2EE(account: userBase.account, urlBase: userBase.urlBase, userId: userBase.userId, serverUrl: serverUrl)
|
|
}
|
|
}
|
|
@@ -794,11 +795,11 @@ class NCUtility: NSObject {
|
|
}
|
|
}
|
|
|
|
|
|
func createViewImageAndText(image: UIImage, title: String? = nil) -> UIView {
|
|
func createViewImageAndText(image: UIImage, title: String? = nil) -> UIView {
|
|
-
|
|
|
|
|
|
+
|
|
let imageView = UIImageView()
|
|
let imageView = UIImageView()
|
|
let titleView = UIView()
|
|
let titleView = UIView()
|
|
let label = UILabel()
|
|
let label = UILabel()
|
|
-
|
|
|
|
|
|
+
|
|
if let title = title {
|
|
if let title = title {
|
|
label.text = title + " "
|
|
label.text = title + " "
|
|
} else {
|
|
} else {
|
|
@@ -807,15 +808,15 @@ class NCUtility: NSObject {
|
|
label.sizeToFit()
|
|
label.sizeToFit()
|
|
label.center = titleView.center
|
|
label.center = titleView.center
|
|
label.textAlignment = NSTextAlignment.center
|
|
label.textAlignment = NSTextAlignment.center
|
|
-
|
|
|
|
|
|
+
|
|
imageView.image = image
|
|
imageView.image = image
|
|
-
|
|
|
|
|
|
+
|
|
let imageAspect = (imageView.image?.size.width ?? 0) / (imageView.image?.size.height ?? 0)
|
|
let imageAspect = (imageView.image?.size.width ?? 0) / (imageView.image?.size.height ?? 0)
|
|
let imageX = label.frame.origin.x - label.frame.size.height * imageAspect
|
|
let imageX = label.frame.origin.x - label.frame.size.height * imageAspect
|
|
let imageY = label.frame.origin.y
|
|
let imageY = label.frame.origin.y
|
|
let imageWidth = label.frame.size.height * imageAspect
|
|
let imageWidth = label.frame.size.height * imageAspect
|
|
let imageHeight = label.frame.size.height
|
|
let imageHeight = label.frame.size.height
|
|
-
|
|
|
|
|
|
+
|
|
if title != nil {
|
|
if title != nil {
|
|
imageView.frame = CGRect(x: imageX, y: imageY, width: imageWidth, height: imageHeight)
|
|
imageView.frame = CGRect(x: imageX, y: imageY, width: imageWidth, height: imageHeight)
|
|
titleView.addSubview(label)
|
|
titleView.addSubview(label)
|
|
@@ -823,12 +824,26 @@ class NCUtility: NSObject {
|
|
imageView.frame = CGRect(x: imageX / 2, y: imageY, width: imageWidth, height: imageHeight)
|
|
imageView.frame = CGRect(x: imageX / 2, y: imageY, width: imageWidth, height: imageHeight)
|
|
}
|
|
}
|
|
imageView.contentMode = UIView.ContentMode.scaleAspectFit
|
|
imageView.contentMode = UIView.ContentMode.scaleAspectFit
|
|
-
|
|
|
|
|
|
+
|
|
titleView.addSubview(imageView)
|
|
titleView.addSubview(imageView)
|
|
titleView.sizeToFit()
|
|
titleView.sizeToFit()
|
|
-
|
|
|
|
|
|
+
|
|
return titleView
|
|
return titleView
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ func getLocation(latitude: Double, longitude: Double, completion: @escaping (String?) -> Void) {
|
|
|
|
+ let geocoder = CLGeocoder()
|
|
|
|
+ let llocation = CLLocation(latitude: latitude, longitude: longitude)
|
|
|
|
+
|
|
|
|
+ geocoder.reverseGeocodeLocation(llocation) { placemarks, error in
|
|
|
|
+ if error == nil, let placemark = placemarks?.first {
|
|
|
|
+ let locationComponents: [String] = [placemark.name, placemark.locality, placemark.country]
|
|
|
|
+ .compactMap{$0}
|
|
|
|
+
|
|
|
|
+ completion(locationComponents.joined(separator: ", "))
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|