|
@@ -2,101 +2,6 @@ import Foundation
|
|
|
import MessageKit
|
|
|
import UIKit
|
|
|
|
|
|
-enum MessageViewType: CustomStringConvertible {
|
|
|
- case audio
|
|
|
- case file
|
|
|
- case gif
|
|
|
- case image
|
|
|
- case text
|
|
|
- case video
|
|
|
- case voice
|
|
|
-
|
|
|
- var description: String {
|
|
|
- switch self {
|
|
|
- // Use Internationalization, as appropriate.
|
|
|
- case .audio: return "Audio"
|
|
|
- case .file: return "File"
|
|
|
- case .gif: return "GIF"
|
|
|
- case .image: return "Image"
|
|
|
- case .text: return "Text"
|
|
|
- case .video: return "Video"
|
|
|
- case .voice: return "Voice"
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-class DCContact {
|
|
|
- private var contactPointer: OpaquePointer
|
|
|
-
|
|
|
- var nameNAddr: String {
|
|
|
- return String(cString: dc_contact_get_name_n_addr(contactPointer))
|
|
|
- }
|
|
|
-
|
|
|
- var name: String {
|
|
|
- return String(cString: dc_contact_get_name(contactPointer))
|
|
|
- }
|
|
|
-
|
|
|
- var email: String {
|
|
|
- return String(cString: dc_contact_get_addr(contactPointer))
|
|
|
- }
|
|
|
-
|
|
|
- var isVerified: Bool {
|
|
|
- return dc_contact_is_verified(contactPointer) > 0
|
|
|
- }
|
|
|
-
|
|
|
- var isBlocked: Bool {
|
|
|
- return dc_contact_is_blocked(contactPointer) == 1
|
|
|
- }
|
|
|
-
|
|
|
- lazy var profileImage: UIImage? = { [unowned self] in
|
|
|
- let file = dc_contact_get_profile_image(contactPointer)
|
|
|
- if let cFile = file {
|
|
|
- let filename = String(cString: cFile)
|
|
|
- let path: URL = URL(fileURLWithPath: filename, isDirectory: false)
|
|
|
- if path.isFileURL {
|
|
|
- do {
|
|
|
- let data = try Data(contentsOf: path)
|
|
|
- return UIImage(data: data)
|
|
|
- } catch {
|
|
|
- logger.warning("failed to load image: \(filename), \(error)")
|
|
|
- return nil
|
|
|
- }
|
|
|
- }
|
|
|
- return nil
|
|
|
- }
|
|
|
-
|
|
|
- return nil
|
|
|
- }()
|
|
|
-
|
|
|
- var color: UIColor {
|
|
|
- return UIColor(netHex: Int(dc_contact_get_color(contactPointer)))
|
|
|
- }
|
|
|
-
|
|
|
- var id: Int {
|
|
|
- return Int(dc_contact_get_id(contactPointer))
|
|
|
- }
|
|
|
-
|
|
|
- init(id: Int) {
|
|
|
- contactPointer = dc_get_contact(mailboxPointer, UInt32(id))
|
|
|
- }
|
|
|
-
|
|
|
- deinit {
|
|
|
- dc_contact_unref(contactPointer)
|
|
|
- }
|
|
|
-
|
|
|
- func block() {
|
|
|
- dc_block_contact(mailboxPointer, UInt32(id), 1)
|
|
|
- }
|
|
|
-
|
|
|
- func unblock() {
|
|
|
- dc_block_contact(mailboxPointer, UInt32(id), 0)
|
|
|
- }
|
|
|
-
|
|
|
- func marknoticed() {
|
|
|
- dc_marknoticed_contact(mailboxPointer, UInt32(id))
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
class DcContext {
|
|
|
let contextPointer: OpaquePointer
|
|
|
|
|
@@ -108,7 +13,6 @@ class DcContext {
|
|
|
dc_context_unref(contextPointer)
|
|
|
}
|
|
|
|
|
|
-
|
|
|
func getSecurejoinQr (chatId: Int) -> String? {
|
|
|
if let cString = dc_get_securejoin_qr(self.contextPointer, UInt32(chatId)) {
|
|
|
return String(cString: cString)
|
|
@@ -137,119 +41,435 @@ class DcContext {
|
|
|
|
|
|
}
|
|
|
|
|
|
-class DcLot {
|
|
|
- private var dcLotPointer: OpaquePointer
|
|
|
+class DcConfig {
|
|
|
+ private class func getOptStr(_ key: String) -> String? {
|
|
|
+ let p = dc_get_config(mailboxPointer, key)
|
|
|
|
|
|
- init(_ dcLotPointer: OpaquePointer) {
|
|
|
- self.dcLotPointer = dcLotPointer
|
|
|
+ if let pSafe = p {
|
|
|
+ let c = String(cString: pSafe)
|
|
|
+ if c.isEmpty {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ return c
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
}
|
|
|
|
|
|
- deinit {
|
|
|
- dc_lot_unref(dcLotPointer)
|
|
|
+ private class func setOptStr(_ key: String, _ value: String?) {
|
|
|
+ if let v = value {
|
|
|
+ dc_set_config(mailboxPointer, key, v)
|
|
|
+ } else {
|
|
|
+ dc_set_config(mailboxPointer, key, nil)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- var text1: String? {
|
|
|
- guard let result = dc_lot_get_text1(dcLotPointer) else { return nil }
|
|
|
- return String(cString: result)
|
|
|
+ private class func getBool(_ key: String) -> Bool {
|
|
|
+ return strToBool(getOptStr(key))
|
|
|
}
|
|
|
|
|
|
- var text1Meaning: Int {
|
|
|
- return Int(dc_lot_get_text1_meaning(dcLotPointer))
|
|
|
+ private class func setBool(_ key: String, _ value: Bool) {
|
|
|
+ let vStr = value ? "1" : "0"
|
|
|
+ setOptStr(key, vStr)
|
|
|
}
|
|
|
|
|
|
- var text2: String? {
|
|
|
- guard let result = dc_lot_get_text2(dcLotPointer) else { return nil }
|
|
|
- return String(cString: result)
|
|
|
+ private class func getInt(_ key: String) -> Int {
|
|
|
+ let vStr = getOptStr(key)
|
|
|
+ if vStr == nil {
|
|
|
+ return 0
|
|
|
+ }
|
|
|
+ let vInt = Int(vStr!)
|
|
|
+ if vInt == nil {
|
|
|
+ return 0
|
|
|
+ }
|
|
|
+ return vInt!
|
|
|
}
|
|
|
|
|
|
- var timestamp: Int {
|
|
|
- return Int(dc_lot_get_timestamp(dcLotPointer))
|
|
|
+ private class func setInt(_ key: String, _ value: Int) {
|
|
|
+ setOptStr(key, String(value))
|
|
|
}
|
|
|
|
|
|
- var state: Int {
|
|
|
- return Int(dc_lot_get_state(dcLotPointer))
|
|
|
+ class var displayname: String? {
|
|
|
+ set { setOptStr("displayname", newValue) }
|
|
|
+ get { return getOptStr("displayname") }
|
|
|
}
|
|
|
|
|
|
- var id: Int {
|
|
|
- return Int(dc_lot_get_id(dcLotPointer))
|
|
|
+ class var selfstatus: String? {
|
|
|
+ set { setOptStr("selfstatus", newValue) }
|
|
|
+ get { return getOptStr("selfstatus") }
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-class DCMessage: MessageType {
|
|
|
- private var messagePointer: OpaquePointer
|
|
|
+ class var selfavatar: String? {
|
|
|
+ set { setOptStr("selfavatar", newValue) }
|
|
|
+ get { return getOptStr("selfavatar") }
|
|
|
+ }
|
|
|
|
|
|
- lazy var sender: SenderType = {
|
|
|
- Sender(id: "\(fromContactId)", displayName: fromContact.name)
|
|
|
- }()
|
|
|
+ class var addr: String? {
|
|
|
+ set { setOptStr("addr", newValue) }
|
|
|
+ get { return getOptStr("addr") }
|
|
|
+ }
|
|
|
|
|
|
- lazy var sentDate: Date = {
|
|
|
- Date(timeIntervalSince1970: Double(timestamp))
|
|
|
- }()
|
|
|
+ class var mailServer: String? {
|
|
|
+ set { setOptStr("mail_server", newValue) }
|
|
|
+ get { return getOptStr("mail_server") }
|
|
|
+ }
|
|
|
|
|
|
- let localDateFormatter: DateFormatter = {
|
|
|
- let result = DateFormatter()
|
|
|
- result.dateStyle = .none
|
|
|
- result.timeStyle = .short
|
|
|
- return result
|
|
|
- }()
|
|
|
+ class var mailUser: String? {
|
|
|
+ set { setOptStr("mail_user", newValue) }
|
|
|
+ get { return getOptStr("mail_user") }
|
|
|
+ }
|
|
|
|
|
|
- func formattedSentDate() -> String {
|
|
|
- return localDateFormatter.string(from: sentDate)
|
|
|
+ class var mailPw: String? {
|
|
|
+ set { setOptStr("mail_pw", newValue) }
|
|
|
+ get { return getOptStr("mail_pw") }
|
|
|
}
|
|
|
|
|
|
- lazy var kind: MessageKind = {
|
|
|
- if isInfo {
|
|
|
- let text = NSAttributedString(string: self.text ?? "", attributes: [
|
|
|
- NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 12),
|
|
|
- NSAttributedString.Key.foregroundColor: UIColor.darkGray,
|
|
|
- ])
|
|
|
- return MessageKind.attributedText(text)
|
|
|
- }
|
|
|
+ class var mailPort: String? {
|
|
|
+ set { setOptStr("mail_port", newValue) }
|
|
|
+ get { return getOptStr("mail_port") }
|
|
|
+ }
|
|
|
|
|
|
- let text = self.text ?? ""
|
|
|
+ class var sendServer: String? {
|
|
|
+ set { setOptStr("send_server", newValue) }
|
|
|
+ get { return getOptStr("send_server") }
|
|
|
+ }
|
|
|
|
|
|
- if self.viewtype == nil {
|
|
|
- return MessageKind.text(text)
|
|
|
- }
|
|
|
+ class var sendUser: String? {
|
|
|
+ set { setOptStr("send_user", newValue) }
|
|
|
+ get { return getOptStr("send_user") }
|
|
|
+ }
|
|
|
|
|
|
- switch self.viewtype! {
|
|
|
- case .image:
|
|
|
- return MessageKind.photo(Media(image: image))
|
|
|
- case .video:
|
|
|
- return MessageKind.video(Media(url: fileURL))
|
|
|
- default:
|
|
|
- // TODO: custom views for audio, etc
|
|
|
- if let filename = self.filename {
|
|
|
- return MessageKind.text("File: \(self.filename ?? "") (\(self.filesize) bytes)")
|
|
|
+ class var sendPw: String? {
|
|
|
+ set { setOptStr("send_pw", newValue) }
|
|
|
+ get { return getOptStr("send_pw") }
|
|
|
+ }
|
|
|
+
|
|
|
+ class var sendPort: String? {
|
|
|
+ set { setOptStr("send_port", newValue) }
|
|
|
+ get { return getOptStr("send_port") }
|
|
|
+ }
|
|
|
+
|
|
|
+ private class var serverFlags: Int {
|
|
|
+ // IMAP-/SMTP-flags as a combination of DC_LP flags
|
|
|
+ set {
|
|
|
+ setOptStr("server_flags", "\(newValue)")
|
|
|
+ }
|
|
|
+ get {
|
|
|
+ if let str = getOptStr("server_flags") {
|
|
|
+ return Int(str) ?? 0
|
|
|
+ } else {
|
|
|
+ return 0
|
|
|
}
|
|
|
- return MessageKind.text(text)
|
|
|
}
|
|
|
- }()
|
|
|
-
|
|
|
- var messageId: String {
|
|
|
- return "\(id)"
|
|
|
}
|
|
|
|
|
|
- var id: Int {
|
|
|
- return Int(dc_msg_get_id(messagePointer))
|
|
|
+ class func setImapSecurity(imapFlags flags: Int) {
|
|
|
+ var sf = serverFlags
|
|
|
+ sf = sf & ~0x700 // DC_LP_IMAP_SOCKET_FLAGS
|
|
|
+ sf = sf | flags
|
|
|
+ serverFlags = sf
|
|
|
}
|
|
|
|
|
|
- var fromContactId: Int {
|
|
|
- return Int(dc_msg_get_from_id(messagePointer))
|
|
|
+ class func setSmtpSecurity(smptpFlags flags: Int) {
|
|
|
+ var sf = serverFlags
|
|
|
+ sf = sf & ~0x70000 // DC_LP_SMTP_SOCKET_FLAGS
|
|
|
+ sf = sf | flags
|
|
|
+ serverFlags = sf
|
|
|
}
|
|
|
|
|
|
- lazy var fromContact: DCContact = {
|
|
|
- DCContact(id: fromContactId)
|
|
|
- }()
|
|
|
+ class func setAuthFlags(flags: Int) {
|
|
|
+ var sf = serverFlags
|
|
|
+ sf = sf & ~0x6 // DC_LP_AUTH_FLAGS
|
|
|
+ sf = sf | flags
|
|
|
+ serverFlags = sf
|
|
|
+ }
|
|
|
|
|
|
- var chatId: Int {
|
|
|
- return Int(dc_msg_get_chat_id(messagePointer))
|
|
|
+ class func getImapSecurity() -> Int {
|
|
|
+ var sf = serverFlags
|
|
|
+ sf = sf & 0x700 // DC_LP_IMAP_SOCKET_FLAGS
|
|
|
+ return sf
|
|
|
}
|
|
|
|
|
|
- var text: String? {
|
|
|
- guard let result = dc_msg_get_text(messagePointer) else { return nil }
|
|
|
+ class func getSmtpSecurity() -> Int {
|
|
|
+ var sf = serverFlags
|
|
|
+ sf = sf & 0x70000 // DC_LP_SMTP_SOCKET_FLAGS
|
|
|
+ return sf
|
|
|
+ }
|
|
|
|
|
|
- return String(cString: result)
|
|
|
+ class func getAuthFlags() -> Int {
|
|
|
+ var sf = serverFlags
|
|
|
+ sf = sf & 0x6 // DC_LP_AUTH_FLAGS
|
|
|
+ serverFlags = sf
|
|
|
+ return sf
|
|
|
+ }
|
|
|
+
|
|
|
+ class var e2eeEnabled: Bool {
|
|
|
+ set { setBool("e2ee_enabled", newValue) }
|
|
|
+ get { return getBool("e2ee_enabled") }
|
|
|
+ }
|
|
|
+
|
|
|
+ class var mdnsEnabled: Bool {
|
|
|
+ set { setBool("mdns_enabled", newValue) }
|
|
|
+ get { return getBool("mdns_enabled") }
|
|
|
+ }
|
|
|
+
|
|
|
+ class var inboxWatch: Bool {
|
|
|
+ set { setBool("inbox_watch", newValue) }
|
|
|
+ get { return getBool("inbox_watch") }
|
|
|
+ }
|
|
|
+
|
|
|
+ class var sentboxWatch: Bool {
|
|
|
+ set { setBool("sentbox_watch", newValue) }
|
|
|
+ get { return getBool("sentbox_watch") }
|
|
|
+ }
|
|
|
+
|
|
|
+ class var mvboxWatch: Bool {
|
|
|
+ set { setBool("mvbox_watch", newValue) }
|
|
|
+ get { return getBool("mvbox_watch") }
|
|
|
+ }
|
|
|
+
|
|
|
+ class var mvboxMove: Bool {
|
|
|
+ set { setBool("mvbox_move", newValue) }
|
|
|
+ get { return getBool("mvbox_move") }
|
|
|
+ }
|
|
|
+
|
|
|
+ class var showEmails: Int {
|
|
|
+ // one of DC_SHOW_EMAILS_*
|
|
|
+ set { setInt("show_emails", newValue) }
|
|
|
+ get { return getInt("show_emails") }
|
|
|
+ }
|
|
|
+
|
|
|
+ class var saveMimeHeaders: Bool {
|
|
|
+ set { setBool("save_mime_headers", newValue) }
|
|
|
+ get { return getBool("save_mime_headers") }
|
|
|
+ }
|
|
|
+
|
|
|
+ class var configuredEmail: String {
|
|
|
+ return getOptStr("configured_addr") ?? ""
|
|
|
+ }
|
|
|
+
|
|
|
+ class var configuredMailServer: String {
|
|
|
+ return getOptStr("configured_mail_server") ?? ""
|
|
|
+ }
|
|
|
+
|
|
|
+ class var configuredMailUser: String {
|
|
|
+ return getOptStr("configured_mail_user") ?? ""
|
|
|
+ }
|
|
|
+
|
|
|
+ class var configuredMailPw: String {
|
|
|
+ return getOptStr("configured_mail_pw") ?? ""
|
|
|
+ }
|
|
|
+
|
|
|
+ class var configuredMailPort: String {
|
|
|
+ return getOptStr("configured_mail_port") ?? ""
|
|
|
+ }
|
|
|
+
|
|
|
+ class var configuredSendServer: String {
|
|
|
+ return getOptStr("configured_send_server") ?? ""
|
|
|
+ }
|
|
|
+
|
|
|
+ class var configuredSendUser: String {
|
|
|
+ return getOptStr("configured_send_user") ?? ""
|
|
|
+ }
|
|
|
+
|
|
|
+ class var configuredSendPw: String {
|
|
|
+ return getOptStr("configured_send_pw") ?? ""
|
|
|
+ }
|
|
|
+
|
|
|
+ class var configuredSendPort: String {
|
|
|
+ return getOptStr("configured_send_port") ?? ""
|
|
|
+ }
|
|
|
+
|
|
|
+ class var configuredServerFlags: String {
|
|
|
+ return getOptStr("configured_server_flags") ?? ""
|
|
|
+ }
|
|
|
+
|
|
|
+ class var configured: Bool {
|
|
|
+ return getBool("configured")
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class DcChatlist {
|
|
|
+ private var chatListPointer: OpaquePointer
|
|
|
+
|
|
|
+ var length: Int {
|
|
|
+ return dc_chatlist_get_cnt(chatListPointer)
|
|
|
+ // return Int(chatListPointer.pointee.m_cnt)
|
|
|
+ }
|
|
|
+
|
|
|
+ // takes ownership of specified pointer
|
|
|
+ init(chatListPointer: OpaquePointer) {
|
|
|
+ self.chatListPointer = chatListPointer
|
|
|
+ }
|
|
|
+
|
|
|
+ func getChatId(index: Int) -> Int {
|
|
|
+ return Int(dc_chatlist_get_chat_id(chatListPointer, index))
|
|
|
+ }
|
|
|
+
|
|
|
+ func getMessageId(index: Int) -> Int {
|
|
|
+ return Int(dc_chatlist_get_msg_id(chatListPointer, index))
|
|
|
+ }
|
|
|
+
|
|
|
+ func summary(index: Int) -> DcLot {
|
|
|
+ guard let lotPointer = dc_chatlist_get_summary(self.chatListPointer, index, nil) else {
|
|
|
+ fatalError("lot-pointer was nil")
|
|
|
+ }
|
|
|
+ return DcLot(lotPointer)
|
|
|
+ }
|
|
|
+
|
|
|
+ deinit {
|
|
|
+ dc_chatlist_unref(chatListPointer)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class DcChat {
|
|
|
+ var chatPointer: OpaquePointer
|
|
|
+
|
|
|
+ var id: Int {
|
|
|
+ return Int(dc_chat_get_id(chatPointer))
|
|
|
+ }
|
|
|
+
|
|
|
+ var name: String {
|
|
|
+ return String(cString: dc_chat_get_name(chatPointer))
|
|
|
+ }
|
|
|
+
|
|
|
+ var type: Int {
|
|
|
+ return Int(dc_chat_get_type(chatPointer))
|
|
|
+ }
|
|
|
+
|
|
|
+ var chatType: ChatType {
|
|
|
+ return ChatType(rawValue: type) ?? ChatType.GROUP // group as fallback - shouldn't get here
|
|
|
+ }
|
|
|
+
|
|
|
+ var color: UIColor {
|
|
|
+ return UIColor(netHex: Int(dc_chat_get_color(chatPointer)))
|
|
|
+ }
|
|
|
+
|
|
|
+ var isVerified: Bool {
|
|
|
+ return dc_chat_is_verified(chatPointer) > 0
|
|
|
+ }
|
|
|
+
|
|
|
+ var contactIds: [Int] {
|
|
|
+ return Utils.copyAndFreeArray(inputArray: dc_get_chat_contacts(mailboxPointer, UInt32(id)))
|
|
|
+ }
|
|
|
+
|
|
|
+ lazy var profileImage: UIImage? = { [unowned self] in
|
|
|
+ let file = dc_chat_get_profile_image(chatPointer)
|
|
|
+ if let cFile = file {
|
|
|
+ let filename = String(cString: cFile)
|
|
|
+ let path: URL = URL(fileURLWithPath: filename, isDirectory: false)
|
|
|
+ if path.isFileURL {
|
|
|
+ do {
|
|
|
+ let data = try Data(contentsOf: path)
|
|
|
+ let image = UIImage(data: data)
|
|
|
+ return image
|
|
|
+ } catch {
|
|
|
+ logger.warning("failed to load image: \(filename), \(error)")
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+ }()
|
|
|
+
|
|
|
+ var subtitle: String? {
|
|
|
+ if let cString = dc_chat_get_subtitle(chatPointer) {
|
|
|
+ let str = String(cString: cString)
|
|
|
+ return str.isEmpty ? nil : str
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ init(id: Int) {
|
|
|
+ if let p = dc_get_chat(mailboxPointer, UInt32(id)) {
|
|
|
+ chatPointer = p
|
|
|
+ } else {
|
|
|
+ fatalError("Invalid chatID opened \(id)")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ deinit {
|
|
|
+ dc_chat_unref(chatPointer)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class DcMsg: MessageType {
|
|
|
+ private var messagePointer: OpaquePointer
|
|
|
+
|
|
|
+ lazy var sender: SenderType = {
|
|
|
+ Sender(id: "\(fromContactId)", displayName: fromContact.name)
|
|
|
+ }()
|
|
|
+
|
|
|
+ lazy var sentDate: Date = {
|
|
|
+ Date(timeIntervalSince1970: Double(timestamp))
|
|
|
+ }()
|
|
|
+
|
|
|
+ let localDateFormatter: DateFormatter = {
|
|
|
+ let result = DateFormatter()
|
|
|
+ result.dateStyle = .none
|
|
|
+ result.timeStyle = .short
|
|
|
+ return result
|
|
|
+ }()
|
|
|
+
|
|
|
+ func formattedSentDate() -> String {
|
|
|
+ return localDateFormatter.string(from: sentDate)
|
|
|
+ }
|
|
|
+
|
|
|
+ lazy var kind: MessageKind = {
|
|
|
+ if isInfo {
|
|
|
+ let text = NSAttributedString(string: self.text ?? "", attributes: [
|
|
|
+ NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 12),
|
|
|
+ NSAttributedString.Key.foregroundColor: UIColor.darkGray,
|
|
|
+ ])
|
|
|
+ return MessageKind.attributedText(text)
|
|
|
+ }
|
|
|
+
|
|
|
+ let text = self.text ?? ""
|
|
|
+
|
|
|
+ if self.viewtype == nil {
|
|
|
+ return MessageKind.text(text)
|
|
|
+ }
|
|
|
+
|
|
|
+ switch self.viewtype! {
|
|
|
+ case .image:
|
|
|
+ return MessageKind.photo(Media(image: image))
|
|
|
+ case .video:
|
|
|
+ return MessageKind.video(Media(url: fileURL))
|
|
|
+ default:
|
|
|
+ // TODO: custom views for audio, etc
|
|
|
+ if let filename = self.filename {
|
|
|
+ return MessageKind.text("File: \(self.filename ?? "") (\(self.filesize) bytes)")
|
|
|
+ }
|
|
|
+ return MessageKind.text(text)
|
|
|
+ }
|
|
|
+ }()
|
|
|
+
|
|
|
+ var messageId: String {
|
|
|
+ return "\(id)"
|
|
|
+ }
|
|
|
+
|
|
|
+ var id: Int {
|
|
|
+ return Int(dc_msg_get_id(messagePointer))
|
|
|
+ }
|
|
|
+
|
|
|
+ var fromContactId: Int {
|
|
|
+ return Int(dc_msg_get_from_id(messagePointer))
|
|
|
+ }
|
|
|
+
|
|
|
+ lazy var fromContact: DcContact = {
|
|
|
+ DcContact(id: fromContactId)
|
|
|
+ }()
|
|
|
+
|
|
|
+ var chatId: Int {
|
|
|
+ return Int(dc_msg_get_chat_id(messagePointer))
|
|
|
+ }
|
|
|
+
|
|
|
+ var text: String? {
|
|
|
+ guard let result = dc_msg_get_text(messagePointer) else { return nil }
|
|
|
+
|
|
|
+ return String(cString: result)
|
|
|
}
|
|
|
|
|
|
var viewtype: MessageViewType? {
|
|
@@ -299,7 +519,7 @@ class DCMessage: MessageType {
|
|
|
} else {
|
|
|
return nil
|
|
|
}
|
|
|
- }()
|
|
|
+ }()
|
|
|
|
|
|
var file: String? {
|
|
|
if let cStr = dc_msg_get_file(messagePointer) {
|
|
@@ -386,9 +606,9 @@ class DCMessage: MessageType {
|
|
|
return String(cString: result)
|
|
|
}
|
|
|
|
|
|
- func createChat() -> DCChat {
|
|
|
+ func createChat() -> DcChat {
|
|
|
let chatId = dc_create_chat_by_msg_id(mailboxPointer, UInt32(id))
|
|
|
- return DCChat(id: Int(chatId))
|
|
|
+ return DcChat(id: Int(chatId))
|
|
|
}
|
|
|
|
|
|
deinit {
|
|
@@ -396,53 +616,38 @@ class DCMessage: MessageType {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-enum ChatType: Int {
|
|
|
- case SINGLE = 100
|
|
|
- case GROUP = 120
|
|
|
- case VERYFIEDGROUP = 130
|
|
|
-}
|
|
|
+class DcContact {
|
|
|
+ private var contactPointer: OpaquePointer
|
|
|
|
|
|
-class DCChat {
|
|
|
- var chatPointer: OpaquePointer
|
|
|
-
|
|
|
- var id: Int {
|
|
|
- return Int(dc_chat_get_id(chatPointer))
|
|
|
- }
|
|
|
+ var nameNAddr: String {
|
|
|
+ return String(cString: dc_contact_get_name_n_addr(contactPointer))
|
|
|
+ }
|
|
|
|
|
|
var name: String {
|
|
|
- return String(cString: dc_chat_get_name(chatPointer))
|
|
|
- }
|
|
|
-
|
|
|
- var type: Int {
|
|
|
- return Int(dc_chat_get_type(chatPointer))
|
|
|
- }
|
|
|
-
|
|
|
- var chatType: ChatType {
|
|
|
- return ChatType(rawValue: type) ?? ChatType.GROUP // group as fallback - shouldn't get here
|
|
|
+ return String(cString: dc_contact_get_name(contactPointer))
|
|
|
}
|
|
|
|
|
|
- var color: UIColor {
|
|
|
- return UIColor(netHex: Int(dc_chat_get_color(chatPointer)))
|
|
|
+ var email: String {
|
|
|
+ return String(cString: dc_contact_get_addr(contactPointer))
|
|
|
}
|
|
|
|
|
|
var isVerified: Bool {
|
|
|
- return dc_chat_is_verified(chatPointer) > 0
|
|
|
+ return dc_contact_is_verified(contactPointer) > 0
|
|
|
}
|
|
|
|
|
|
- var contactIds: [Int] {
|
|
|
- return Utils.copyAndFreeArray(inputArray: dc_get_chat_contacts(mailboxPointer, UInt32(id)))
|
|
|
+ var isBlocked: Bool {
|
|
|
+ return dc_contact_is_blocked(contactPointer) == 1
|
|
|
}
|
|
|
|
|
|
lazy var profileImage: UIImage? = { [unowned self] in
|
|
|
- let file = dc_chat_get_profile_image(chatPointer)
|
|
|
+ let file = dc_contact_get_profile_image(contactPointer)
|
|
|
if let cFile = file {
|
|
|
let filename = String(cString: cFile)
|
|
|
let path: URL = URL(fileURLWithPath: filename, isDirectory: false)
|
|
|
if path.isFileURL {
|
|
|
do {
|
|
|
let data = try Data(contentsOf: path)
|
|
|
- let image = UIImage(data: data)
|
|
|
- return image
|
|
|
+ return UIImage(data: data)
|
|
|
} catch {
|
|
|
logger.warning("failed to load image: \(filename), \(error)")
|
|
|
return nil
|
|
@@ -454,462 +659,109 @@ class DCChat {
|
|
|
return nil
|
|
|
}()
|
|
|
|
|
|
- var subtitle: String? {
|
|
|
- if let cString = dc_chat_get_subtitle(chatPointer) {
|
|
|
- let str = String(cString: cString)
|
|
|
- return str.isEmpty ? nil : str
|
|
|
- }
|
|
|
- return nil
|
|
|
- }
|
|
|
-
|
|
|
- init(id: Int) {
|
|
|
- if let p = dc_get_chat(mailboxPointer, UInt32(id)) {
|
|
|
- chatPointer = p
|
|
|
- } else {
|
|
|
- fatalError("Invalid chatID opened \(id)")
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- deinit {
|
|
|
- dc_chat_unref(chatPointer)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-class DCChatList {
|
|
|
- private var chatListPointer: OpaquePointer
|
|
|
-
|
|
|
- var length: Int {
|
|
|
- return dc_chatlist_get_cnt(chatListPointer)
|
|
|
- // return Int(chatListPointer.pointee.m_cnt)
|
|
|
- }
|
|
|
-
|
|
|
- // takes ownership of specified pointer
|
|
|
- init(chatListPointer: OpaquePointer) {
|
|
|
- self.chatListPointer = chatListPointer
|
|
|
- }
|
|
|
-
|
|
|
- func getChatId(index: Int) -> Int {
|
|
|
- return Int(dc_chatlist_get_chat_id(chatListPointer, index))
|
|
|
+ var color: UIColor {
|
|
|
+ return UIColor(netHex: Int(dc_contact_get_color(contactPointer)))
|
|
|
}
|
|
|
|
|
|
- func getMessageId(index: Int) -> Int {
|
|
|
- return Int(dc_chatlist_get_msg_id(chatListPointer, index))
|
|
|
+ var id: Int {
|
|
|
+ return Int(dc_contact_get_id(contactPointer))
|
|
|
}
|
|
|
|
|
|
- func summary(index: Int) -> DcLot {
|
|
|
- guard let lotPointer = dc_chatlist_get_summary(self.chatListPointer, index, nil) else {
|
|
|
- fatalError("lot-pointer was nil")
|
|
|
- }
|
|
|
- return DcLot(lotPointer)
|
|
|
+ init(id: Int) {
|
|
|
+ contactPointer = dc_get_contact(mailboxPointer, UInt32(id))
|
|
|
}
|
|
|
|
|
|
deinit {
|
|
|
- dc_chatlist_unref(chatListPointer)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func strToBool(_ value: String?) -> Bool {
|
|
|
- if let vStr = value {
|
|
|
- if let vInt = Int(vStr) {
|
|
|
- return vInt == 1
|
|
|
- }
|
|
|
- return false
|
|
|
- }
|
|
|
-
|
|
|
- return false
|
|
|
-}
|
|
|
-
|
|
|
-class DCConfig {
|
|
|
- private class func getOptStr(_ key: String) -> String? {
|
|
|
- let p = dc_get_config(mailboxPointer, key)
|
|
|
-
|
|
|
- if let pSafe = p {
|
|
|
- let c = String(cString: pSafe)
|
|
|
- if c.isEmpty {
|
|
|
- return nil
|
|
|
- }
|
|
|
- return c
|
|
|
- }
|
|
|
-
|
|
|
- return nil
|
|
|
- }
|
|
|
-
|
|
|
- private class func setOptStr(_ key: String, _ value: String?) {
|
|
|
- if let v = value {
|
|
|
- dc_set_config(mailboxPointer, key, v)
|
|
|
- } else {
|
|
|
- dc_set_config(mailboxPointer, key, nil)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private class func getBool(_ key: String) -> Bool {
|
|
|
- return strToBool(getOptStr(key))
|
|
|
- }
|
|
|
-
|
|
|
- private class func setBool(_ key: String, _ value: Bool) {
|
|
|
- let vStr = value ? "1" : "0"
|
|
|
- setOptStr(key, vStr)
|
|
|
- }
|
|
|
-
|
|
|
- private class func getInt(_ key: String) -> Int {
|
|
|
- let vStr = getOptStr(key)
|
|
|
- if vStr == nil {
|
|
|
- return 0
|
|
|
- }
|
|
|
- let vInt = Int(vStr!)
|
|
|
- if vInt == nil {
|
|
|
- return 0
|
|
|
- }
|
|
|
- return vInt!
|
|
|
- }
|
|
|
-
|
|
|
- private class func setInt(_ key: String, _ value: Int) {
|
|
|
- setOptStr(key, String(value))
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Address to display (always needed)
|
|
|
- */
|
|
|
- class var addr: String? {
|
|
|
- set {
|
|
|
- setOptStr("addr", newValue)
|
|
|
- }
|
|
|
- get {
|
|
|
- return getOptStr("addr")
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * IMAP-server, guessed if left out
|
|
|
- */
|
|
|
- class var mailServer: String? {
|
|
|
- set {
|
|
|
- setOptStr("mail_server", newValue)
|
|
|
- }
|
|
|
- get {
|
|
|
- return getOptStr("mail_server")
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * IMAP-username, guessed if left out
|
|
|
- */
|
|
|
- class var mailUser: String? {
|
|
|
- set {
|
|
|
- setOptStr("mail_user", newValue)
|
|
|
- }
|
|
|
- get {
|
|
|
- return getOptStr("mail_user")
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * IMAP-password (always needed)
|
|
|
- */
|
|
|
- class var mailPw: String? {
|
|
|
- set {
|
|
|
- setOptStr("mail_pw", newValue)
|
|
|
- }
|
|
|
- get {
|
|
|
- return getOptStr("mail_pw")
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * IMAP-port, guessed if left out
|
|
|
- */
|
|
|
- class var mailPort: String? {
|
|
|
- set {
|
|
|
- setOptStr("mail_port", newValue)
|
|
|
- }
|
|
|
- get {
|
|
|
- return getOptStr("mail_port")
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * SMTP-server, guessed if left out
|
|
|
- */
|
|
|
- class var sendServer: String? {
|
|
|
- set {
|
|
|
- setOptStr("send_server", newValue)
|
|
|
- }
|
|
|
- get {
|
|
|
- return getOptStr("send_server")
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * SMTP-user, guessed if left out
|
|
|
- */
|
|
|
- class var sendUser: String? {
|
|
|
- set {
|
|
|
- setOptStr("send_user", newValue)
|
|
|
- }
|
|
|
- get {
|
|
|
- return getOptStr("send_user")
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * SMTP-password, guessed if left out
|
|
|
- */
|
|
|
- class var sendPw: String? {
|
|
|
- set {
|
|
|
- setOptStr("send_pw", newValue)
|
|
|
- }
|
|
|
- get {
|
|
|
- return getOptStr("send_pw")
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * SMTP-port, guessed if left out
|
|
|
- */
|
|
|
- class var sendPort: String? {
|
|
|
- set {
|
|
|
- setOptStr("send_port", newValue)
|
|
|
- }
|
|
|
- get {
|
|
|
- return getOptStr("send_port")
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * IMAP-/SMTP-flags as a combination of DC_LP flags, guessed if left out
|
|
|
- */
|
|
|
-
|
|
|
- private class var serverFlags: Int {
|
|
|
- set {
|
|
|
- setOptStr("server_flags", "\(newValue)")
|
|
|
- }
|
|
|
- get {
|
|
|
- if let str = getOptStr("server_flags") {
|
|
|
- return Int(str) ?? 0
|
|
|
- } else {
|
|
|
- return 0
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- class func setImapSecurity(imapFlags flags: Int) {
|
|
|
- var sf = serverFlags
|
|
|
- sf = sf & ~0x700 // TODO: should be DC_LP_IMAP_SOCKET_FLAGS - could not be found
|
|
|
- sf = sf | flags
|
|
|
- serverFlags = sf
|
|
|
+ dc_contact_unref(contactPointer)
|
|
|
}
|
|
|
|
|
|
- class func setSmtpSecurity(smptpFlags flags: Int) {
|
|
|
- var sf = serverFlags
|
|
|
- sf = sf & ~0x70000 // TODO: should be DC_LP_SMTP_SOCKET_FLAGS - could not be found
|
|
|
- sf = sf | flags
|
|
|
- serverFlags = sf
|
|
|
+ func block() {
|
|
|
+ dc_block_contact(mailboxPointer, UInt32(id), 1)
|
|
|
}
|
|
|
|
|
|
- class func setAuthFlags(flags: Int) {
|
|
|
- var sf = serverFlags
|
|
|
- sf = sf & ~0x6 // TODO: should be DC_LP_AUTH_FLAGS - could not be found
|
|
|
- sf = sf | flags
|
|
|
- serverFlags = sf
|
|
|
+ func unblock() {
|
|
|
+ dc_block_contact(mailboxPointer, UInt32(id), 0)
|
|
|
}
|
|
|
|
|
|
- // returns one of DC_LP_IMAP_SOCKET_STARTTLS, DC_LP_IMAP_SOCKET_SSL,
|
|
|
- class func getImapSecurity() -> Int {
|
|
|
- var sf = serverFlags
|
|
|
- sf = sf & 0x700
|
|
|
- return sf
|
|
|
+ func marknoticed() {
|
|
|
+ dc_marknoticed_contact(mailboxPointer, UInt32(id))
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- // returns one of DC_LP_SMTP_SOCKET_STARTTLS, DC_LP_SMTP_SOCKET_SSL,
|
|
|
- class func getSmtpSecurity() -> Int {
|
|
|
- var sf = serverFlags
|
|
|
- sf = sf & 0x70000
|
|
|
- return sf
|
|
|
- }
|
|
|
+class DcLot {
|
|
|
+ private var dcLotPointer: OpaquePointer
|
|
|
|
|
|
- // returns on of DC_LP_AUTH_OAUTH2 or 0
|
|
|
- class func getAuthFlags() -> Int {
|
|
|
- var sf = serverFlags
|
|
|
- sf = sf & 0x6
|
|
|
- serverFlags = sf
|
|
|
- return sf
|
|
|
+ init(_ dcLotPointer: OpaquePointer) {
|
|
|
+ self.dcLotPointer = dcLotPointer
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Own name to use when sending messages. MUAs are allowed to spread this way eg. using CC, defaults to empty
|
|
|
- */
|
|
|
- class var displayname: String? {
|
|
|
- set {
|
|
|
- setOptStr("displayname", newValue)
|
|
|
- }
|
|
|
- get {
|
|
|
- return getOptStr("displayname")
|
|
|
- }
|
|
|
+ deinit {
|
|
|
+ dc_lot_unref(dcLotPointer)
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Own status to display eg. in email footers, defaults to a standard text
|
|
|
- */
|
|
|
- class var selfstatus: String? {
|
|
|
- set {
|
|
|
- setOptStr("selfstatus", newValue)
|
|
|
- }
|
|
|
- get {
|
|
|
- return getOptStr("selfstatus")
|
|
|
- }
|
|
|
+ var text1: String? {
|
|
|
+ guard let result = dc_lot_get_text1(dcLotPointer) else { return nil }
|
|
|
+ return String(cString: result)
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * File containing avatar. Will be copied to blob directory. NULL to remove the avatar. It is planned for future versions to send this image together with the next messages.
|
|
|
- */
|
|
|
- class var selfavatar: String? {
|
|
|
- set {
|
|
|
- setOptStr("selfavatar", newValue)
|
|
|
- }
|
|
|
- get {
|
|
|
- return getOptStr("selfavatar")
|
|
|
- }
|
|
|
+ var text1Meaning: Int {
|
|
|
+ return Int(dc_lot_get_text1_meaning(dcLotPointer))
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 0=no end-to-end-encryption, 1=prefer end-to-end-encryption (default)
|
|
|
- */
|
|
|
- class var e2eeEnabled: Bool {
|
|
|
- set {
|
|
|
- setBool("e2ee_enabled", newValue)
|
|
|
- }
|
|
|
- get {
|
|
|
- return getBool("e2ee_enabled")
|
|
|
- }
|
|
|
+ var text2: String? {
|
|
|
+ guard let result = dc_lot_get_text2(dcLotPointer) else { return nil }
|
|
|
+ return String(cString: result)
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 0=do not send or request read receipts, 1=send and request read receipts (default)
|
|
|
- */
|
|
|
- class var mdnsEnabled: Bool {
|
|
|
- set {
|
|
|
- setBool("mdns_enabled", newValue)
|
|
|
- }
|
|
|
- get {
|
|
|
- return getBool("mdns_enabled")
|
|
|
- }
|
|
|
+ var timestamp: Int {
|
|
|
+ return Int(dc_lot_get_timestamp(dcLotPointer))
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 1=watch INBOX-folder for changes (default), 0=do not watch the INBOX-folder
|
|
|
- */
|
|
|
- class var inboxWatch: Bool {
|
|
|
- set {
|
|
|
- setBool("inbox_watch", newValue)
|
|
|
- }
|
|
|
- get {
|
|
|
- return getBool("inbox_watch")
|
|
|
- }
|
|
|
+ var state: Int {
|
|
|
+ return Int(dc_lot_get_state(dcLotPointer))
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 1=watch Sent-folder for changes (default), 0=do not watch the Sent-folder
|
|
|
- */
|
|
|
- class var sentboxWatch: Bool {
|
|
|
- set {
|
|
|
- setBool("sentbox_watch", newValue)
|
|
|
- }
|
|
|
- get {
|
|
|
- return getBool("sentbox_watch")
|
|
|
- }
|
|
|
+ var id: Int {
|
|
|
+ return Int(dc_lot_get_id(dcLotPointer))
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- /**
|
|
|
- * 1=watch DeltaChat-folder for changes (default), 0=do not watch the DeltaChat-folder
|
|
|
- */
|
|
|
- class var mvboxWatch: Bool {
|
|
|
- set {
|
|
|
- setBool("mvbox_watch", newValue)
|
|
|
- }
|
|
|
- get {
|
|
|
- return getBool("mvbox_watch")
|
|
|
- }
|
|
|
- }
|
|
|
+enum ChatType: Int {
|
|
|
+ case SINGLE = 100
|
|
|
+ case GROUP = 120
|
|
|
+ case VERYFIEDGROUP = 130
|
|
|
+}
|
|
|
|
|
|
- /**
|
|
|
- * 1=heuristically detect chat-messages and move them to the DeltaChat-folder, 0=do not move chat-messages
|
|
|
- */
|
|
|
- class var mvboxMove: Bool {
|
|
|
- set {
|
|
|
- setBool("mvbox_move", newValue)
|
|
|
- }
|
|
|
- get {
|
|
|
- return getBool("mvbox_move")
|
|
|
- }
|
|
|
- }
|
|
|
+enum MessageViewType: CustomStringConvertible {
|
|
|
+ case audio
|
|
|
+ case file
|
|
|
+ case gif
|
|
|
+ case image
|
|
|
+ case text
|
|
|
+ case video
|
|
|
+ case voice
|
|
|
|
|
|
- /**
|
|
|
- * DC_SHOW_EMAILS_OFF (0)= show direct replies to chats only (default),
|
|
|
- * DC_SHOW_EMAILS_ACCEPTED_CONTACTS (1)= also show all mails of confirmed contacts,
|
|
|
- * DC_SHOW_EMAILS_ALL (2)= also show mails of unconfirmed contacts in the deaddrop.
|
|
|
- */
|
|
|
- class var showEmails: Bool {
|
|
|
- set {
|
|
|
- setBool("show_emails", newValue)
|
|
|
- }
|
|
|
- get {
|
|
|
- return getBool("show_emails")
|
|
|
+ var description: String {
|
|
|
+ switch self {
|
|
|
+ // Use Internationalization, as appropriate.
|
|
|
+ case .audio: return "Audio"
|
|
|
+ case .file: return "File"
|
|
|
+ case .gif: return "GIF"
|
|
|
+ case .image: return "Image"
|
|
|
+ case .text: return "Text"
|
|
|
+ case .video: return "Video"
|
|
|
+ case .voice: return "Voice"
|
|
|
}
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- /**
|
|
|
- * 1=save mime headers and make dc_get_mime_headers() work for subsequent calls, 0=do not save mime headers (default)
|
|
|
- */
|
|
|
- class var saveMimeHeaders: Bool {
|
|
|
- set {
|
|
|
- setBool("save_mime_headers", newValue)
|
|
|
- }
|
|
|
- get {
|
|
|
- return getBool("save_mime_headers")
|
|
|
+func strToBool(_ value: String?) -> Bool {
|
|
|
+ if let vStr = value {
|
|
|
+ if let vInt = Int(vStr) {
|
|
|
+ return vInt == 1
|
|
|
}
|
|
|
+ return false
|
|
|
}
|
|
|
|
|
|
- class var configuredEmail: String {
|
|
|
- return getOptStr("configured_addr") ?? ""
|
|
|
- }
|
|
|
-
|
|
|
- class var configuredMailServer: String {
|
|
|
- return getOptStr("configured_mail_server") ?? ""
|
|
|
- }
|
|
|
-
|
|
|
- class var configuredMailUser: String {
|
|
|
- return getOptStr("configured_mail_user") ?? ""
|
|
|
- }
|
|
|
-
|
|
|
- class var configuredMailPw: String {
|
|
|
- return getOptStr("configured_mail_pw") ?? ""
|
|
|
- }
|
|
|
-
|
|
|
- class var configuredMailPort: String {
|
|
|
- return getOptStr("configured_mail_port") ?? ""
|
|
|
- }
|
|
|
-
|
|
|
- class var configuredSendServer: String {
|
|
|
- return getOptStr("configured_send_server") ?? ""
|
|
|
- }
|
|
|
-
|
|
|
- class var configuredSendUser: String {
|
|
|
- return getOptStr("configured_send_user") ?? ""
|
|
|
- }
|
|
|
-
|
|
|
- class var configuredSendPw: String {
|
|
|
- return getOptStr("configured_send_pw") ?? ""
|
|
|
- }
|
|
|
-
|
|
|
- class var configuredSendPort: String {
|
|
|
- return getOptStr("configured_send_port") ?? ""
|
|
|
- }
|
|
|
-
|
|
|
- class var configuredServerFlags: String {
|
|
|
- return getOptStr("configured_server_flags") ?? ""
|
|
|
- }
|
|
|
-
|
|
|
- class var configured: Bool {
|
|
|
- return getBool("configured")
|
|
|
- }
|
|
|
+ return false
|
|
|
}
|