|
@@ -504,7 +504,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
|
|
])
|
|
])
|
|
let exblock = User.getDataCanNil(pin: self.dataPerson["f_pin"]!!)?.ex_block
|
|
let exblock = User.getDataCanNil(pin: self.dataPerson["f_pin"]!!)?.ex_block
|
|
blocking = exblock == nil ? "0" : exblock!.isEmpty ? "0" : exblock!
|
|
blocking = exblock == nil ? "0" : exblock!.isEmpty ? "0" : exblock!
|
|
- if blocking == "1" && self.dataPerson["f_pin"]!! != "-999" {
|
|
|
|
|
|
+ if blocking == "1" && self.dataPerson["f_pin"]!! != "-999" && self.dataPerson["isOfficial"]!! != "1" {
|
|
menu = UIMenu(title: "", children: [
|
|
menu = UIMenu(title: "", children: [
|
|
actionSearch,
|
|
actionSearch,
|
|
actionUnblock,
|
|
actionUnblock,
|
|
@@ -512,7 +512,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
|
|
])
|
|
])
|
|
blockedView(blocked: "1")
|
|
blockedView(blocked: "1")
|
|
} else if blocking == "0" {
|
|
} else if blocking == "0" {
|
|
- if self.dataPerson["f_pin"]!! != "-999" && complaintId.isEmpty {
|
|
|
|
|
|
+ if self.dataPerson["f_pin"]!! != "-999" && complaintId.isEmpty && self.dataPerson["isOfficial"]!! != "1" {
|
|
menu = UIMenu(title: "", children: [
|
|
menu = UIMenu(title: "", children: [
|
|
actionSearch,
|
|
actionSearch,
|
|
actionBlock,
|
|
actionBlock,
|
|
@@ -545,7 +545,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
|
|
let buttonVideoCall = UIBarButtonItem(image: UIImage(systemName: "video", withConfiguration: UIImage.SymbolConfiguration(pointSize: 18, weight: .regular, scale: .default)), style: .plain, target: self, action: #selector(audioVideoCall(sender:)))
|
|
let buttonVideoCall = UIBarButtonItem(image: UIImage(systemName: "video", withConfiguration: UIImage.SymbolConfiguration(pointSize: 18, weight: .regular, scale: .default)), style: .plain, target: self, action: #selector(audioVideoCall(sender:)))
|
|
buttonVideoCall.tag = 1
|
|
buttonVideoCall.tag = 1
|
|
let buttonAddRoom = UIBarButtonItem(image: UIImage(systemName: "plus.message", withConfiguration: UIImage.SymbolConfiguration(pointSize: 18, weight: .regular, scale: .default)), style: .plain, target: self, action: #selector(addRoom(sender:)))
|
|
let buttonAddRoom = UIBarButtonItem(image: UIImage(systemName: "plus.message", withConfiguration: UIImage.SymbolConfiguration(pointSize: 18, weight: .regular, scale: .default)), style: .plain, target: self, action: #selector(addRoom(sender:)))
|
|
- if dataPerson["f_pin"] != "-999" && !isContactCenter && blocking == "0" {
|
|
|
|
|
|
+ if dataPerson["f_pin"] != "-999" && !isContactCenter && blocking == "0" && self.dataPerson["isOfficial"]!! != "1" {
|
|
navigationItem.rightBarButtonItems = [moreIcon,buttonAudioCall,buttonVideoCall]
|
|
navigationItem.rightBarButtonItems = [moreIcon,buttonAudioCall,buttonVideoCall]
|
|
} else if !isContactCenter {
|
|
} else if !isContactCenter {
|
|
navigationItem.rightBarButtonItem = moreIcon
|
|
navigationItem.rightBarButtonItem = moreIcon
|
|
@@ -4362,12 +4362,20 @@ extension EditorPersonal: UITextViewDelegate, CustomTextViewPasteDelegate {
|
|
print("Access database error: \(error.localizedDescription)")
|
|
print("Access database error: \(error.localizedDescription)")
|
|
}
|
|
}
|
|
})
|
|
})
|
|
|
|
+ if !dataURL.isEmpty {
|
|
|
|
+ if let data = try! JSONSerialization.jsonObject(with: dataURL.data(using: String.Encoding.utf8)!, options: []) as? [String: Any] {
|
|
|
|
+ let imageUrl = data["imageUrl"] as? String
|
|
|
|
+ let link = data["link"] as? String ?? ""
|
|
|
|
+ if imageUrl == nil || (link.contains("youtube.com") && link.contains("watch?v=") && !imageUrl!.contains("img.youtube.com/vi/")) {
|
|
|
|
+ dataURL = ""
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
if !dataURL.isEmpty {
|
|
if !dataURL.isEmpty {
|
|
if let data = try! JSONSerialization.jsonObject(with: dataURL.data(using: String.Encoding.utf8)!, options: []) as? [String: Any] {
|
|
if let data = try! JSONSerialization.jsonObject(with: dataURL.data(using: String.Encoding.utf8)!, options: []) as? [String: Any] {
|
|
let title = data["title"] as? String ?? ""
|
|
let title = data["title"] as? String ?? ""
|
|
let description = data["description"] as? String ?? ""
|
|
let description = data["description"] as? String ?? ""
|
|
let imageUrl = data["imageUrl"] as? String
|
|
let imageUrl = data["imageUrl"] as? String
|
|
- let link = data["link"] as? String ?? ""
|
|
|
|
if self.showingLink != text {
|
|
if self.showingLink != text {
|
|
self.showingLink = text
|
|
self.showingLink = text
|
|
self.deleteLinkPreview()
|
|
self.deleteLinkPreview()
|
|
@@ -4386,9 +4394,24 @@ extension EditorPersonal: UITextViewDelegate, CustomTextViewPasteDelegate {
|
|
cache: DisabledCache.instance)
|
|
cache: DisabledCache.instance)
|
|
let preview = slp.preview(stringURl,
|
|
let preview = slp.preview(stringURl,
|
|
onSuccess: { result in
|
|
onSuccess: { result in
|
|
- let title = result.title ?? "No Title"
|
|
|
|
- let description = stringURl.contains("google.com") ? "" : result.description
|
|
|
|
- let imageUrl = result.icon
|
|
|
|
|
|
+ print("MASUK SINI KAH? :\(result)")
|
|
|
|
+ if result.title == nil {
|
|
|
|
+ self.checkLink(fullText: fullText)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ let title = result.title?.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
|
|
+ .nilIfEmpty ?? URL(string: text)?.host ?? "Untitled"
|
|
|
|
+ let description: String
|
|
|
|
+ if text.contains("google.com") {
|
|
|
|
+ description = "" // special rule for google
|
|
|
|
+ } else {
|
|
|
|
+ description = result.description?.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
|
|
+ .nilIfEmpty ?? ""
|
|
|
|
+ }
|
|
|
|
+ let imageUrl = self.youtubeThumbnail(from: text)
|
|
|
|
+ ?? result.image
|
|
|
|
+ ?? result.icon
|
|
|
|
+ ?? ""
|
|
Database.shared.database?.inTransaction({ (fmdb, rollback) in
|
|
Database.shared.database?.inTransaction({ (fmdb, rollback) in
|
|
do {
|
|
do {
|
|
var dataJson: [String: Any] = [:]
|
|
var dataJson: [String: Any] = [:]
|
|
@@ -4418,7 +4441,8 @@ extension EditorPersonal: UITextViewDelegate, CustomTextViewPasteDelegate {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
},
|
|
- onError: { error in
|
|
|
|
|
|
+ onError: { error in
|
|
|
|
+ print("onError? :\(error)")
|
|
self.deleteLinkPreview()
|
|
self.deleteLinkPreview()
|
|
})
|
|
})
|
|
}
|
|
}
|
|
@@ -4428,6 +4452,24 @@ extension EditorPersonal: UITextViewDelegate, CustomTextViewPasteDelegate {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ func youtubeThumbnail(from url: String) -> String? {
|
|
|
|
+ guard let url = URL(string: url) else { return nil }
|
|
|
|
+ let host = url.host ?? ""
|
|
|
|
+
|
|
|
|
+ if host.contains("youtube.com"),
|
|
|
|
+ let queryItems = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems,
|
|
|
|
+ let videoId = queryItems.first(where: { $0.name == "v" })?.value {
|
|
|
|
+ return "https://img.youtube.com/vi/\(videoId)/hqdefault.jpg"
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if host.contains("youtu.be") {
|
|
|
|
+ let videoId = url.lastPathComponent
|
|
|
|
+ return "https://img.youtube.com/vi/\(videoId)/hqdefault.jpg"
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return nil
|
|
|
|
+ }
|
|
|
|
+
|
|
private func buildPreviewLink(imageUrl: String?, title: String, description: String?, stringURl: String) {
|
|
private func buildPreviewLink(imageUrl: String?, title: String, description: String?, stringURl: String) {
|
|
if !self.viewTextfield.subviews.contains(self.containerLink){
|
|
if !self.viewTextfield.subviews.contains(self.containerLink){
|
|
UIView.animate(withDuration: 0.25, delay: 0.0, options: .curveEaseInOut, animations: {
|
|
UIView.animate(withDuration: 0.25, delay: 0.0, options: .curveEaseInOut, animations: {
|
|
@@ -4498,7 +4540,7 @@ extension EditorPersonal: UITextViewDelegate, CustomTextViewPasteDelegate {
|
|
} else {
|
|
} else {
|
|
linkPreview.leadingAnchor.constraint(equalTo: self.containerLink.leadingAnchor, constant: 5.0).isActive = true
|
|
linkPreview.leadingAnchor.constraint(equalTo: self.containerLink.leadingAnchor, constant: 5.0).isActive = true
|
|
}
|
|
}
|
|
- linkPreview.topAnchor.constraint(equalTo: descPreview.bottomAnchor, constant: 8.0).isActive = true
|
|
|
|
|
|
+ linkPreview.topAnchor.constraint(equalTo: descPreview.bottomAnchor).isActive = true
|
|
linkPreview.trailingAnchor.constraint(equalTo: self.containerLink.trailingAnchor, constant: -80.0).isActive = true
|
|
linkPreview.trailingAnchor.constraint(equalTo: self.containerLink.trailingAnchor, constant: -80.0).isActive = true
|
|
linkPreview.text = stringURl
|
|
linkPreview.text = stringURl
|
|
linkPreview.font = UIFont.systemFont(ofSize: 10.0 + offset())
|
|
linkPreview.font = UIFont.systemFont(ofSize: 10.0 + offset())
|
|
@@ -5096,14 +5138,14 @@ extension EditorPersonal: UIContextMenuInteractionDelegate {
|
|
} else if dataMessages[indexPath!.row]["attachment_flag"] as? String ?? "" == "11" {
|
|
} else if dataMessages[indexPath!.row]["attachment_flag"] as? String ?? "" == "11" {
|
|
children = [reply, delete]
|
|
children = [reply, delete]
|
|
}
|
|
}
|
|
- if ((Nexilis.checkingAccess(key: "secure_folder_forward") && dataMessages[indexPath!.row]["attachment_flag"] as? String ?? "" != "11") || (!(dataMessages[indexPath!.row][TypeDataMessage.message_text] as? String ?? "").isEmpty && (dataMessages[indexPath!.row]["image_id"] as? String ?? "").isEmpty && (dataMessages[indexPath!.row]["video_id"] as? String ?? "").isEmpty && (dataMessages[indexPath!.row]["file_id"] as? String ?? "").isEmpty && (dataMessages[indexPath!.row]["audio_id"] as? String ?? "").isEmpty) || (dataMessages[indexPath!.row][TypeDataMessage.spec_file] as? String ?? "").contains("forward")) && dataMessages[indexPath!.row]["read_receipts"] as? String != "8" {
|
|
|
|
|
|
+ if ((Nexilis.checkingAccess(key: "secure_folder_forward") && dataMessages[indexPath!.row]["attachment_flag"] as? String ?? "" != "11") || (!(dataMessages[indexPath!.row][TypeDataMessage.message_text] as? String ?? "").isEmpty && (dataMessages[indexPath!.row]["image_id"] as? String ?? "").isEmpty && (dataMessages[indexPath!.row]["video_id"] as? String ?? "").isEmpty && (dataMessages[indexPath!.row]["file_id"] as? String ?? "").isEmpty && (dataMessages[indexPath!.row]["audio_id"] as? String ?? "").isEmpty) || (dataMessages[indexPath!.row][TypeDataMessage.spec_file] as? String ?? "").contains("forward")) && dataMessages[indexPath!.row]["read_receipts"] as? String != "8" && dataMessages[indexPath!.row]["read_receipts"] as? String != "8" && dataMessages[indexPath!.row]["attachment_flag"] as? String ?? "" != "11" {
|
|
children.insert(forward, at: 2)
|
|
children.insert(forward, at: 2)
|
|
}
|
|
}
|
|
if (dataMessages[indexPath!.row]["f_pin"] as? String ?? "") == idMe {
|
|
if (dataMessages[indexPath!.row]["f_pin"] as? String ?? "") == idMe {
|
|
children.insert(info, at: children.count - 1)
|
|
children.insert(info, at: children.count - 1)
|
|
}
|
|
}
|
|
- if !(dataMessages[indexPath!.row][TypeDataMessage.message_text] as? String ?? "").isEmpty && (dataMessages[indexPath!.row][TypeDataMessage.attachment_flag] as? String ?? "") != "11" {
|
|
|
|
- if (dataMessages[indexPath!.row]["f_pin"] as? String ?? "") == idMe && ((dataMessages[indexPath!.row][TypeDataMessage.is_forwarded] as? Int) ?? 0) == 0 {
|
|
|
|
|
|
+ if !(dataMessages[indexPath!.row][TypeDataMessage.message_text] as? String ?? "").isEmpty {
|
|
|
|
+ if (dataMessages[indexPath!.row]["f_pin"] as? String ?? "") == idMe && ((dataMessages[indexPath!.row][TypeDataMessage.is_forwarded] as? Int) ?? 0) == 0 && (dataMessages[indexPath!.row][TypeDataMessage.attachment_flag] as? String ?? "") != "11" {
|
|
let date = Date(milliseconds: Int64(dataMessages[indexPath!.row][TypeDataMessage.server_date] as? String ?? "") ?? 0)
|
|
let date = Date(milliseconds: Int64(dataMessages[indexPath!.row][TypeDataMessage.server_date] as? String ?? "") ?? 0)
|
|
let pastDate = date.addingTimeInterval(-10 * 60)
|
|
let pastDate = date.addingTimeInterval(-10 * 60)
|
|
let differenceInSeconds = date.timeIntervalSince(pastDate)
|
|
let differenceInSeconds = date.timeIntervalSince(pastDate)
|
|
@@ -5111,7 +5153,9 @@ extension EditorPersonal: UIContextMenuInteractionDelegate {
|
|
children.insert(edit, at: children.count - 1)
|
|
children.insert(edit, at: children.count - 1)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- isMore = true
|
|
|
|
|
|
+ if (dataMessages[indexPath!.row][TypeDataMessage.attachment_flag] as? String ?? "") != "11" && (dataMessages[indexPath!.row]["image_id"] as? String ?? "").isEmpty && (dataMessages[indexPath!.row]["video_id"] as? String ?? "").isEmpty && (dataMessages[indexPath!.row]["file_id"] as? String ?? "").isEmpty && (dataMessages[indexPath!.row]["audio_id"] as? String ?? "").isEmpty{
|
|
|
|
+ isMore = true
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
let mainMenu = UIMenu(title: "", options: [.displayInline],
|
|
let mainMenu = UIMenu(title: "", options: [.displayInline],
|
|
@@ -7781,6 +7825,7 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource, AVAudioPla
|
|
}
|
|
}
|
|
if !text.isEmpty {
|
|
if !text.isEmpty {
|
|
isLoadingShowLink = true
|
|
isLoadingShowLink = true
|
|
|
|
+ var dataURL = ""
|
|
func showLink() {
|
|
func showLink() {
|
|
if let data = try! JSONSerialization.jsonObject(with: dataURL.data(using: String.Encoding.utf8)!, options: []) as? [String: Any] {
|
|
if let data = try! JSONSerialization.jsonObject(with: dataURL.data(using: String.Encoding.utf8)!, options: []) as? [String: Any] {
|
|
let title = data["title"] as? String ?? ""
|
|
let title = data["title"] as? String ?? ""
|
|
@@ -7807,7 +7852,8 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource, AVAudioPla
|
|
imagePreview.topAnchor.constraint(equalTo: containerLinkMessage.topAnchor).isActive = true
|
|
imagePreview.topAnchor.constraint(equalTo: containerLinkMessage.topAnchor).isActive = true
|
|
imagePreview.widthAnchor.constraint(equalToConstant: 80.0).isActive = true
|
|
imagePreview.widthAnchor.constraint(equalToConstant: 80.0).isActive = true
|
|
imagePreview.loadImageAsync(with: imageUrl)
|
|
imagePreview.loadImageAsync(with: imageUrl)
|
|
- imagePreview.contentMode = .scaleToFill
|
|
|
|
|
|
+ imagePreview.contentMode = .scaleAspectFill
|
|
|
|
+ imagePreview.clipsToBounds = true
|
|
}
|
|
}
|
|
|
|
|
|
let titlePreview = UILabel()
|
|
let titlePreview = UILabel()
|
|
@@ -7821,7 +7867,7 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource, AVAudioPla
|
|
titlePreview.topAnchor.constraint(equalTo: containerLinkMessage.topAnchor, constant: 10.0).isActive = true
|
|
titlePreview.topAnchor.constraint(equalTo: containerLinkMessage.topAnchor, constant: 10.0).isActive = true
|
|
titlePreview.trailingAnchor.constraint(equalTo: containerLinkMessage.trailingAnchor, constant: -5.0).isActive = true
|
|
titlePreview.trailingAnchor.constraint(equalTo: containerLinkMessage.trailingAnchor, constant: -5.0).isActive = true
|
|
titlePreview.text = title
|
|
titlePreview.text = title
|
|
- titlePreview.font = UIFont.systemFont(ofSize: 14.0 + offset(), weight: .bold)
|
|
|
|
|
|
+ titlePreview.font = UIFont.systemFont(ofSize: 12.0 + offset(), weight: .bold)
|
|
titlePreview.textColor = self.traitCollection.userInterfaceStyle == .dark ? .white : .black
|
|
titlePreview.textColor = self.traitCollection.userInterfaceStyle == .dark ? .white : .black
|
|
|
|
|
|
let descPreview = UILabel()
|
|
let descPreview = UILabel()
|
|
@@ -7865,7 +7911,6 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource, AVAudioPla
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- var dataURL = ""
|
|
|
|
Database.shared.database?.inTransaction({ (fmdb, rollback) in
|
|
Database.shared.database?.inTransaction({ (fmdb, rollback) in
|
|
do {
|
|
do {
|
|
if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "select data_link from LINK_PREVIEW where link='\(text)'"), cursor.next() {
|
|
if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "select data_link from LINK_PREVIEW where link='\(text)'"), cursor.next() {
|
|
@@ -7879,6 +7924,15 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource, AVAudioPla
|
|
print("Access database error: \(error.localizedDescription)")
|
|
print("Access database error: \(error.localizedDescription)")
|
|
}
|
|
}
|
|
})
|
|
})
|
|
|
|
+ if !dataURL.isEmpty {
|
|
|
|
+ if let data = try! JSONSerialization.jsonObject(with: dataURL.data(using: String.Encoding.utf8)!, options: []) as? [String: Any] {
|
|
|
|
+ let imageUrl = data["imageUrl"] as? String
|
|
|
|
+ let link = data["link"] as? String ?? ""
|
|
|
|
+ if imageUrl == nil || (link.contains("youtube.com") && link.contains("watch?v=") && !imageUrl!.contains("img.youtube.com/vi/")) {
|
|
|
|
+ dataURL = ""
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
if dataURL.isEmpty {
|
|
if dataURL.isEmpty {
|
|
let urlConfig = URLSessionConfiguration.default
|
|
let urlConfig = URLSessionConfiguration.default
|
|
let sessionDelegate = SelfSignedURLSessionDelegate()
|
|
let sessionDelegate = SelfSignedURLSessionDelegate()
|
|
@@ -7889,9 +7943,19 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource, AVAudioPla
|
|
cache: DisabledCache.instance)
|
|
cache: DisabledCache.instance)
|
|
let preview = slp.preview(text,
|
|
let preview = slp.preview(text,
|
|
onSuccess: { result in
|
|
onSuccess: { result in
|
|
- let title = result.title ?? "No Title"
|
|
|
|
- let description = text.contains("google.com") ? "" : result.description
|
|
|
|
- let imageUrl = result.icon
|
|
|
|
|
|
+ let title = result.title?.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
|
|
+ .nilIfEmpty ?? URL(string: text)?.host ?? "Untitled"
|
|
|
|
+ let description: String
|
|
|
|
+ if text.contains("google.com") {
|
|
|
|
+ description = "" // special rule for google
|
|
|
|
+ } else {
|
|
|
|
+ description = result.description?.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
|
|
+ .nilIfEmpty ?? ""
|
|
|
|
+ }
|
|
|
|
+ let imageUrl = self.youtubeThumbnail(from: text)
|
|
|
|
+ ?? result.image
|
|
|
|
+ ?? result.icon
|
|
|
|
+ ?? ""
|
|
Database.shared.database?.inTransaction({ (fmdb, rollback) in
|
|
Database.shared.database?.inTransaction({ (fmdb, rollback) in
|
|
do {
|
|
do {
|
|
var dataJson: [String: Any] = [:]
|
|
var dataJson: [String: Any] = [:]
|
|
@@ -9510,3 +9574,11 @@ public class TypeDataMessage {
|
|
public static let is_secret = "is_secret"
|
|
public static let is_secret = "is_secret"
|
|
public static let spec_file = "spec_file"
|
|
public static let spec_file = "spec_file"
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+extension String {
|
|
|
|
+ var nilIfEmpty: String? {
|
|
|
|
+ let v = self.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
|
|
+ return v.isEmpty ? nil : v
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|