@@ -1,2270 +0,0 @@
5−// Created by Ilya Kos on 12/12/16.
6−// Copyright © 2016 Ilya Kos. All rights reserved.
18−typealias Token = String
19−typealias UserID = Int
20−typealias MessageID = Int
21−typealias MultichatID = Int
23−class RealmPhoto: Object {
25− convenience init(surl: String, id: String) {
27− self.imageSURL = surl
31− @objc dynamic var id: String = ""
34− return imageSURL =>> {URL(string: $0)}
37− imageSURL = newValue?.absoluteString
40− @objc dynamic var imageSURL: String? {
42− if oldValue != imageSURL {
47− @objc private dynamic var localImageSURL: String? {
49− if oldValue != localImageSURL {
54− private var imageCache: UIImage?
56− convenience init(id: String, surl: String?) {
59− self.imageSURL = surl
62− class func by(_ id: String, surl: String?) -> RealmPhoto {
64− let realm = try Realm()
65− if let ob = realm.object(ofType: RealmPhoto.self, forPrimaryKey: id) {
66− if realm.isInWriteTransaction {
67− surl =>> {ob.imageSURL = $0}
70− surl =>> {ob.imageSURL = $0}
75− let ob = RealmPhoto(id: id, surl: surl)
76− if realm.isInWriteTransaction {
86− let ob = RealmPhoto(id: id, surl: surl)
91− override static func primaryKey() -> String? {
95− override static func ignoredProperties() -> [String] {
96− return ["imageURL", "imageCache", "completions", "request"]
99− var completions: [((() -> ()), RealmPhotoToken)] = []
100− var views: [(UIImageView?, RealmPhotoToken)] = []
101− var request: DataRequest?
103− @discardableResult func load(into view: UIImageView, completion: (() -> ())? = nil, error errorClosure: (() -> ())? = nil) -> RealmPhotoToken {
105− let token = RealmPhotoToken()
107− func getFromServer() {
109− let surl = "\(id).png"
110− if let url = imageURL {
111− print("getting from network")
112− request = Alamofire.request(url, method: .get).validate().responseData(queue: userQueue) { (responce) in
114− switch responce.result {
115− case .success(let data):
116− UIImage(data: data) >>> {image in
117− write(cache: UIImagePNGRepresentation(image), withName: surl) {
118− realmWrite({ (realm) in
119− realm.object(ofType: RealmPhoto.self, forPrimaryKey: self.id)?.localImageSURL = surl
122− self.imageCache = image
123− DispatchQueue.main.async {
125− self.views.map { if $0.1.isValid {$0.0?.image = image} }
126− self.completions.map { if $0.1.isValid { $0.0() } }
127− self.completions = []
131− case .failure(let error):
133− // TODO: Error handling
141− if let surl = localImageSURL, // TODO: Should probrably get thing from server ???
142− let url = url(forName: surl) {
143− Nuke.loadImage(with: url, into: view) { [weak view] (response, fromMemory) in
145− case .fulfilled(let image):
150− case .rejected(let error): // TODO: Handle error?
151− completion >>> {self.completions.append(($0, token))}
152− self.views.append((view, token))
157− completion >>> {self.completions.append(($0, token))}
158− self.views.append((view, token))
165− // func image(_ completion: @escaping ((UIImage?) -> ())) {
167− // let surl = "\(id).png"
168− // if imageCache != nil {
169− // print("we have caching!")
171− // imageCache = imageCache ?? (localImageSURL =>> getLocalImage) // TODO: imageCache always seems to be nil... ie always loading from disk for some reason
172− // if let sImage = imageCache {
173− // DispatchQueue.main.async { completion(sImage) }
174− // } else if let url = imageURL {
175− // print("getting from network")
176− // Alamofire.request(url, method: .get).validate().responseData(queue: userQueue) { (responce) in
177− // switch responce.result {
178− // case .success(let data):
179− // UIImage(data: data) >>> {image in
180− // write(cache: UIImagePNGRepresentation(image), withName: surl) {
181− // DispatchQueue.main.async {
183− // let realm = try Realm()
184− // if !realm.isInWriteTransaction {
185− // try realm.write {
186− // self.localImageSURL = surl
189− // self.localImageSURL = surl
194− // self.imageCache = image
195− // DispatchQueue.main.async {completion(image)}
197− // case .failure(let error):
198− // // TODO: Error handling
206−public class RealmPhotoToken {
207− public func cancel() {
210− fileprivate var isValid = true
215− @objc dynamic var id: UserID = 0
216− @objc dynamic var firstName: String?
217− @objc dynamic var lastName: String?
218− var deactivated: Deactivated? {
220− return deactivatedStr =>> {Deactivated.init(rawValue: $0)}
223− deactivatedStr = newValue >>> {$0.rawValue}
226− @objc private dynamic var deactivatedStr: String?
228− @objc dynamic var about: String?
229− @objc dynamic var birthday: Date?
230− let blacklisted = RealmOptional<Bool>()
231− let canSendFriendRequest = RealmOptional<Bool>()
232− let canSendPrivateMessage = RealmOptional<Bool>()
233− let mutualFriendCount = RealmOptional<Int>()
234− // TODO: var connections:
235− @objc dynamic var mobilePhone: String?
236− @objc dynamic var homePhone: String?
237− // TODO: var exports
238− var friendStatus: FriendStatus? {
240− return friendStatusInt.value =>> {FriendStatus(rawValue: $0)}
243− friendStatusInt.value = newValue >>> {$0.rawValue}
246− private let friendStatusInt = RealmOptional<Int>()
247− let online = RealmOptional<Bool>()
248− @objc dynamic var avatar: RealmPhoto?
249− var avatarID: String {
250− return "user\(id)avatar"
252− @objc dynamic var photo: RealmPhoto?
253− var photoID: String {
254− return "user\(id)photo"
258− return siteSURL =>> {URL.init(string: $0)}
261− siteSURL = newValue >>> {$0.absoluteString}
264− @objc dynamic var siteSURL: String?
265− @objc dynamic var status: String?
266− @objc dynamic var lastSeen: Date?
267− // dynamic var lastUpdated: Date = Date()
268− let friendCount = RealmOptional<Int>()
270− convenience init(id: UserID, firstName: String, lastName: String) {
273− self.firstName = firstName
274− self.lastName = lastName
275− // self.lastUpdated = Date()
277− class func by(id: UserID) -> User {
278− let realm = try! Realm()
279− if let us = realm.object(ofType: User.self, forPrimaryKey: id) {
284− if realm.isInWriteTransaction {
296−// func get(completion: ((User?) -> ())? = nil) {
297−// VK.API.Users.get([VK.Arg.userIDs: "\(id)"]).send(onSuccess: { (response) in
298−// if let json = response.array?.first {
299−// let us = VKData.processUser(json: json)
304−// }, onError: { (error) in
308− func get(completion: ((User?) -> ())? = nil) {
309− VKServer.get(user: self) { (data) in
310− if let json = JSON.init(data: data)["response"].array?.first {
311− let user = VKData.processUser(json: json)
318− override static func primaryKey() -> String? {
322− override static func ignoredProperties() -> [String] {
323− return ["site", "photoID", "avatarID"]
325− // func update() { lastUpdated = Date() }
327− // MARK: Hashable override
329− override var hashValue: Int {
334−class Geolocation: Object {
335− var geoCoordinates: CLLocation? {
337− if let long = long.value, let latt = latt.value {
338− return CLLocation(latitude: latt, longitude: long)
343− if let latt = newValue?.coordinate.latitude,
344− let long = newValue?.coordinate.longitude {
345− self.latt.value = latt
346− self.long.value = long
348− self.long.value = nil
349− self.latt.value = nil
353− private let latt = RealmOptional<Double>()
354− private let long = RealmOptional<Double>()
355− let id = RealmOptional<Int>()
356− @objc dynamic var title: String?
357− @objc dynamic var image: RealmPhoto?
358− var imageID: String {
359− return "geo_lat\(latt.value ?? 0)_long\(long.value ?? 0)image"
362− var country: String?
364− override static func ignoredProperties() -> [String] {
365− return ["geoCoordinates", "imageID"]
367− convenience init(long: Double, latt: Double) {
369− self.long.value = long
370− self.latt.value = latt
375−class GenericMessage: Object {
376− @objc dynamic var date = Date() //
377− @objc dynamic var body = "" //
378− @objc dynamic var user: User?
380− var outPhotos: [UIImage] = [] // TODO: ~
382− @objc dynamic var geolocation: Geolocation?
384− let attachments = List<RealmMedia>()
385− let forwardedMessages = List<RealmForwardedMessage>()
386− //let sentMessageId: MessageID? I DONT KNOW WHY I PUT THIS HERE
388− // convenience init(body: String) {
391− // self.out.value = true
393− // convenience init(image: UIImage) {
395− // self.outPhotos.append(image)
397− override static func ignoredProperties() -> [String] {
398− return ["outPhotos"]
402−class Message: GenericMessage, Comparable, SortedArrayItem {
403− @objc dynamic var id = 0
404− let randomID = RealmOptional<MessageID>()
405− @objc dynamic var read = false
406− @objc dynamic var replied = false
407− @objc dynamic var important = false
408− @objc dynamic var deleted = false
410− func equal(to message: Message) -> Bool {
411− // print("\(lhs.id.value) \(rhs.id.value) \(lhs.id.value == rhs.id.value)")
412− if let a = self.randomID.value,
413− let b = message.randomID.value {
418− return self.id == message.id
420− internal func greater(than message: Message) -> Bool {
421− return self.id < message.id
424− static func ==(lhs: Message, rhs: Message) -> Bool {
425− print("\(lhs.id) \(rhs.id) \(lhs.id == rhs.id)")
426− return lhs.id == rhs.id
429− @objc dynamic var out = false
433− @objc dynamic var photoSURL: String?
434− let chatID = RealmOptional<MultichatID>()
435− @objc private dynamic var serviceMessageString: String?
436− private var serviceMessageUser: User?
437− private let serviceMessage = RealmOptional<Int>()
439− var action: ServiceMessageAction? {
441− func getUser() -> ServiceMessageUser? {
442− if let user = self.serviceMessageUser {
444− } else if let email = self.serviceMessageString {
445− return .email(email)
451− return serviceMessage.value =>> { service in
458− return self.serviceMessageString >>> { .create($0) }
460− return self.serviceMessageString >>> { .titleUpdate($0) }
462− return getUser() >>> { .inviteUser($0) }
464− return getUser() >>> { .kickUser($0) }
471− func set(user: ServiceMessageUser) {
473− case .user(let use):
474− self.serviceMessageUser = use
475− case .email(let str):
476− self.serviceMessageString = str
480− serviceMessageString = nil
481− serviceMessageUser = nil
482− serviceMessage.value = newValue >>> { new in
488− case .create(let str):
489− self.serviceMessageString = str
491− case .titleUpdate(let str):
492− self.serviceMessageString = str
494− case .inviteUser(let user):
497− case .kickUser(let user):
505−// func get(completion: ((Message?) -> ())? = nil) {
506−// VK.API.Messages.getById([VK.Arg.messageIds: String(id)]).send(onSuccess: { (response) in
507−// if let json = response.array?.first {
508−// let mes = VKData.processMessage(response)
513−// }, onError: { (error) in
516−// // TODO: Implement propperly?
519− class func by(id: MessageID) -> Message {
520− let realm = try! Realm()
521− if let us = realm.object(ofType: Message.self, forPrimaryKey: id) {
533− override static func primaryKey() -> String? {
537−//func ==(lhs: Message, rhs: Message) -> Bool {
538−// print("\(lhs.id.value) \(rhs.id.value) \(lhs.id.value == rhs.id.value)")
539−// return lhs.id.value == rhs.id.value
541−func <(lhs: Message, rhs: Message) -> Bool {
542− return lhs.id < rhs.id
545−enum forwardedMessage {
546− case genericMessage(GenericMessage)
547− case message(Message)
550−class RealmForwardedMessage: Object {
551− var value: forwardedMessage? {
553− if let gm = genericMessage {
554− return .genericMessage(gm)
555− } else if let m = message {
563− if let fm = newValue {
565− case .genericMessage(let gm):
568− case .message(let m):
569− genericMessage = nil
574− genericMessage = nil
579− @objc private dynamic var genericMessage: GenericMessage?
580− @objc private dynamic var message: Message?
582− var id: MessageID? {
583− if let m = message {
590− convenience init(value: forwardedMessage) {
595− override static func ignoredProperties() -> [String] {
600−//struct Geolocation {
601−// var coordinates: CLLocation
602−// var title: String?
603−// var imageURL: URL? {
605−// return imageSURL =>> {URL.init(string: $0)}
608−// imageSURL = newValue?.absoluteString
611−// var imageSURL: String?
612−// // func image(completion: ((UIImage) -> ())) {
613−// // imageFunc =>> {$0(completion)}
615−// var image: (@escaping ((UIImage) -> ()) -> ())?
617−// var country: String?
618−// init(coordinates: CLLocation, title: String?, imageSURL: String?, image: (@escaping ((UIImage) -> ()) -> ()), city: String?, country: String?) {
619−// self.coordinates = coordinates
620−// self.title = title
621−// self.imageSURL = imageSURL
622−// self.image = image
624−// self.country = country
627−typealias GeolocationID = Int
629−enum Deactivated: String {
630− case banned = "banned"
631− case deleted = "deleted"
632− case normal = "normal"
635−enum FriendStatus: Int {
638− case requestRecieved
642−enum MessageReadState: Int {
646−enum MessageSendState: Int {
651−enum MultichatNotificationSetting {
656−enum ServiceMessageAction {
657− case photoUpdate // 0
658− case photoRemove // 1
659− case create(String) // 2
660− case titleUpdate(String) // 3
661− case inviteUser(ServiceMessageUser) // 4
662− case kickUser(ServiceMessageUser) // 5
665−enum ServiceMessageUser {
670−typealias MessageChunkID = String
671−class MessageChunk: Object { // message ids go down
672− subscript(index: Int) -> Message {
673− return messages[index]
676− @objc dynamic var id: MessageChunkID = ""
678− fileprivate let messages = List<Message>()
680− var firstMessage: Message? {
681− return messages.first
684− var lastMessage: Message? {
685− return messages.last
688− var firstID: MessageID? {
689− return firstMessage?.id
692− var lastID: MessageID? {
693− return lastMessage?.id
697− return messages.count
700− fileprivate func append(message: Message?) {
701− message >>> {messages.append($0)}
704− override static func primaryKey() -> String? {
708− override static func ignoredProperties() -> [String] {
709− return ["firstMessage", "lastMessage", "firstID", "lastID", "count"]
713−func +=(lhs: MessageChunk, rhs: MessageChunk) {
714− lhs.messages.append(objectsIn: rhs.messages)
717−/// Returns: true if added. false if was already in list
718−func <~(lhs: MessageChunk?, rhs: Message?) -> Bool {
719− var out: Bool = false
721− out = lhs?.messages <~ rhs
725−/// Returns: Indexes of added items
726−func <-(lhs: MessageChunk?, rhs: [Message?]?) -> [Int] {
729− out = lhs?.messages <- rhs
733−/// Returns: Indexes of added items
734−func <-(lhs: MessageChunk?, rhs: MessageChunk?) -> [Int] {
737− out = lhs?.messages <- rhs?.messages
743− case message(Message)
747−typealias MessagesID = Int
748−class Messages: Object {
749− subscript(ind: Int) -> MessageEntry? {
750− assert(ind >= 0, "index out of bounds")
751− if ind >= count || ind < 0 {
756− while messageChunks[i].count < index {
757− index -= messageChunks[i].count + 1
760− if index == messageChunks[i].count {
763− return .message(messageChunks[i][index])
767− @objc dynamic var id: MessagesID = 0
769− @objc fileprivate dynamic var lastChunkID = 0
772− return messageChunks.endIndex
775− var first: Message? {
776− return messageChunks.first?.firstMessage
779− func count(upToChunk index: Int) -> Int {
781− for i in 0..<index {
782− n += messageChunks[i].count + 1
787− public var count: Int {
788− var n = messageChunks.count - 1
789− for chunk in messageChunks {
795− fileprivate let messageChunks = List<MessageChunk>()
797− public var chunks: List<MessageChunk> {
798− return messageChunks
801− fileprivate enum ChunkIndex {
807− fileprivate func createChunk(at index: Int = 0) -> MessageChunk {
808− let chunk = MessageChunk()
809− realmWrite { (realm) in
810− chunk.id = "\(id)_\(lastChunkID)"
813− messageChunks.insert(chunk, at: index)
818− /// Return nil if there are no chunks
819− fileprivate func chunkIndex(of message: Message) -> ChunkIndex? {
820− if messageChunks.count == 0 {
823− if let first = messageChunks.first?.firstMessage {
824− if first.greater(than: message) {
828− for (i, chunk) in messageChunks.enumerated() {
829− if let lastMessage = chunk.lastMessage { // It should never be nil since a chunk is never empty
830− if !message.greater(than: lastMessage) { // [ ... | ()] [...] ...
834− if let firstMessage = chunk.firstMessage { // It should never be nil since a chunk is never empty
835− if message.greater(than: firstMessage) || message.equal(to: firstMessage) {
845− return .after(endIndex-1)
849− override static func primaryKey() -> String? {
853− override static func ignoredProperties() -> [String] {
857− class func by(id: MessagesID) -> Messages {
858− let realm = try! Realm()
859− if let us = realm.object(ofType: Messages.self, forPrimaryKey: id) {
869− // MARK: Messages obesrver
871− static let notificationName: Notification.Name = Notification.Name(rawValue: "MessagesWereModifiedNotificationName")
882−/// Returns: true if added. false if was already in list
883−func <~(lhs: Messages?, rhs: Message?) -> Bool {
884− var out: Bool = false
888− if let index = lhs.chunkIndex(of: rhs) {
891− lhs.messageChunks[i].append(message: rhs)
893− case .inside(let i):
894− out = lhs.messageChunks[i] <~ rhs
896− out = lhs.createChunk(at: 0) <~ rhs
899− out = lhs.createChunk() <~ rhs
905−/// Only accepts a list of SEQUENTIAL messages. Will silently break if not passed sequentially.
906−/// Returns: Indexes of added items
907−func <-(lhs: Messages?, rhs: [Message?]?) /*-> [Int]*/ {
911− let rhs = rhs?.flatMap({$0}),
912− let first = rhs.first,
913− let last = rhs.last {
915− var deleted: [Int] = []
916− var modified: [Int] = []
917− var added: [Int] = []
918− if let startI = lhs.chunkIndex(of: first),
919− let endI = lhs.chunkIndex(of: last) {
922− print("\t", startI, endI)
924− case .inside(let i):
934− case .inside(let i):
942− start = max(start, 0)
943− var spacerIndexes = (start+1...end).map({lhs.count(upToChunk: $0) - 1})
944− // deleted += spacerIndexes
945− let count = lhs.count(upToChunk: start)
947− for i in 0..<spacerIndexes.count {
948− spacerIndexes[i] -= dIndex
949− deleted.append(spacerIndexes[i])
950− spacerIndexes[i] -= count
954− realmWriteWithCompletion { realm, completion in
955− for x in start+1...end {
956− print(lhs.chunks.count, x)
957− lhs.chunks[start] += lhs.chunks[start+1]
958− realm.delete(lhs.chunks[start+1])
959− // lhs.chunks.remove(objectAtIndex: start+1)
961− let chunk = lhs.chunks[start]
962− addedMs = chunk <- rhs
964− addedMs.map {$0 + count}
968− print("after notification", lhs.chunks)
969− NotificationCenter.default.post(name: Messages.notificationName,
971− userInfo: [Messages.Changes.added: added,
972− Messages.Changes.modified: modified,
973− Messages.Changes.deleted: deleted])
976− } else { // within one
977− assert(start == end, "start index is larger than end index!")
978− realmWriteWithCompletion { _, completion in
980− added += lhs.createChunk(at: 0) <- rhs
981− added.append(0) // IDK o[]o[]o []o[]o
983− added += (lhs.messageChunks[start] <- rhs).map {$0 + lhs.count(upToChunk: start)}
986− NotificationCenter.default.post(name: Messages.notificationName,
988− userInfo: [Messages.Changes.added: added,
989− Messages.Changes.modified: modified,
990− Messages.Changes.deleted: deleted])
995− realmWriteWithCompletion { _, completion in
996− added += lhs.createChunk() <- rhs
998− NotificationCenter.default.post(name: Messages.notificationName,
1000− userInfo: [Messages.Changes.added: added,
1001− Messages.Changes.modified: modified,
1002− Messages.Changes.deleted: deleted])
1017− case wall(WallPost)
1018− case wallReply(WallPostReply)
1019− case sticker(Sticker)
1022− case market(Market)
1023− case marketAlbum(MarketAlbum)
1024− case graffiti(Document)
1027− case album(PhotoAlbum)
1028− var realm: RealmMedia {
1029− return RealmMedia(value: self)
1033−class RealmMedia: Object {
1034− @objc private dynamic var photo: Photo?
1035− @objc private dynamic var video: Video?
1036− @objc private dynamic var audio: Audio?
1037− @objc private dynamic var doc: Document?
1038− @objc private dynamic var wall: WallPost?
1039− @objc private dynamic var wallReply: WallPostReply?
1040− @objc private dynamic var sticker: Sticker?
1041− @objc private dynamic var link: Link?
1042− @objc private dynamic var gift: Gift?
1043− @objc private dynamic var market: Market?
1044− @objc private dynamic var marketAlbum: MarketAlbum?
1045− @objc private dynamic var graffiti: Document?
1046− @objc private dynamic var note: Note?
1047− @objc private dynamic var poll: Poll?
1048− @objc private dynamic var album: PhotoAlbum?
1050− var value: Media? {
1052− if let sureThing = self.photo { return .photo(sureThing) }
1053− if let sureThing = self.video { return .video(sureThing) }
1054− if let sureThing = self.audio { return .audio(sureThing) }
1055− if let sureThing = self.doc { return .doc(sureThing) }
1056− if let sureThing = self.wall { return .wall(sureThing) }
1057− if let sureThing = self.wallReply { return .wallReply(sureThing) }
1058− if let sureThing = self.sticker { return .sticker(sureThing) }
1059− if let sureThing = self.link { return .link(sureThing) }
1060− if let sureThing = self.gift { return .gift(sureThing) }
1061− if let sureThing = self.market { return .market(sureThing) }
1062− if let sureThing = self.marketAlbum { return .marketAlbum(sureThing) }
1063− if let sureThing = self.graffiti { return .graffiti(sureThing) }
1064− if let sureThing = self.note { return .note(sureThing) }
1065− if let sureThing = self.poll { return .poll(sureThing) }
1066− if let sureThing = self.album { return .album(sureThing) }
1087− if let val = newValue {
1089− case .photo(let foo): photo = foo
1090− case .video(let foo): video = foo
1091− case .audio(let foo): audio = foo
1092− case .doc(let foo): doc = foo
1093− case .wall(let foo): wall = foo
1094− case .wallReply(let foo): wallReply = foo
1095− case .sticker(let foo): sticker = foo
1096− case .link(let foo): link = foo
1097− case .gift(let foo): gift = foo
1098− case .market(let foo): market = foo
1099− case .marketAlbum(let foo): marketAlbum = foo
1100− case .graffiti(let foo): graffiti = foo
1101− case .note(let foo): note = foo
1102− case .poll(let foo): poll = foo
1103− case .album(let foo): album = foo
1108− convenience init(value: Media) {
1114−class Poll: Object {
1115− @objc dynamic var id: PollID = 0
1116− @objc dynamic var owner: User?
1117− @objc dynamic var date: Date?
1118− @objc dynamic var question: String?
1119− let votes = RealmOptional<Int>()
1120− let answerID = RealmOptional<PollAnswerID>()
1121− let answers = List<PollAnswer>()
1122− convenience init(id: PollID, owner: User, date: Date, question: String, votes: Int) {
1127− self.question = question
1128− self.votes.value = votes
1129− // self.answerID.value = answerID
1131− class func by(id: PollID) -> Poll {
1132− let realm = try! Realm()
1133− if let us = realm.object(ofType: Poll.self, forPrimaryKey: id) {
1143− override class func primaryKey() -> String? {
1147−typealias PollID = Int
1149−class PollAnswer: Object {
1150− @objc dynamic var id: PollAnswerID = 0
1151− @objc dynamic var body: String = ""
1152− @objc dynamic var votes: Int = 0
1153− @objc dynamic var rating: Int = 0
1155− convenience init(id: PollAnswerID, body: String, votes: Int, rating: Int) {
1160− self.rating = rating
1163−typealias PollAnswerID = Int
1165−class Note: Object {
1166− @objc dynamic var id: NoteID = 0
1167− @objc dynamic var owner: User?
1168− @objc dynamic var title: String?
1169− @objc dynamic var body: String?
1170− @objc dynamic var date: Date?
1173− return surl =>> {URL(string: $0)}
1176− surl = newValue >>> {$0.absoluteString}
1179− @objc dynamic var surl: String?
1180− let commentCount = RealmOptional<Int>()
1181− convenience init(id: NoteID, owner: User, title: String, body: String, date: Date, url: URL, commentCount: Int) {
1189− self.commentCount.value = commentCount
1191− class func by(id: NoteID) -> Note {
1192− let realm = try! Realm()
1193− if let us = realm.object(ofType: Note.self, forPrimaryKey: id) {
1202− override class func ignoredProperties() -> [String] {
1206− override class func primaryKey() -> String? {
1210−typealias NoteID = Int
1212−typealias GraffitiID = Int
1213−class Graffiti: Document {
1214−} // Use document.image ?
1216−class Photo: Object {
1217− @objc dynamic var id: PhotoID = 0
1218− @objc dynamic var owner: User?
1219− @objc dynamic var date: Date?
1220− @objc dynamic var thumbnail: RealmPhoto?
1221− var thumbnailID: String {
1222− return "photo\(id)thumbnail"
1224− @objc dynamic var image: RealmPhoto?
1225− var imageID: String {
1226− return "photo\(id)image"
1228− let width = RealmOptional<Int>()
1229− let height = RealmOptional<Int>()
1230− @objc dynamic var accessKey: Key?
1232− convenience init(id: PhotoID, owner: User, date: Date){
1239− class func by(id: PhotoID) -> Photo {
1240− let realm = try! Realm()
1241− if let us = realm.object(ofType: Photo.self, forPrimaryKey: id) {
1251−// func get(completion: ((Photo?) -> ())? = nil) {
1252−// if let ownerID = owner?.id {
1253−// var ph = "\(ownerID)_\(id)"
1254−// if let key = accessKey {
1255−// ph.append("_\(key)")
1257−// VK.API.Photos.getById([VK.Arg.photos: ph]).send(onSuccess: { (response) in
1258−// if let json = response.array?.first {
1259−// let photo = VKData.processPhoto(json)
1260−// completion?(photo)
1264−// }, onError: { (error) in
1271− func get(completion: ((Photo?) -> ())? = nil) {
1272− VKServer.get(photo: self) { data in
1273− if let json = JSON.init(data: data)["response"].array?.first {
1274− let photo = VKData.processPhoto(json)
1280− override class func primaryKey() -> String? {
1284− override static func ignoredProperties() -> [String] {
1285− return ["thumbnailID", "imageID"]
1289−class PhotoAlbum: Object {
1290− @objc dynamic var id: PhotoAlbumID = 0
1291− @objc dynamic var thumb: Photo?
1292− @objc dynamic var owner: User?
1293− @objc dynamic var title: String?
1294− @objc dynamic var albumDescription: String?
1295− @objc dynamic var dateCreated: Date?
1296− @objc dynamic var dateUpdated: Date?
1297− let count = RealmOptional<Int>()
1298− let photos = List<Photo>()
1299− convenience init(id: PhotoAlbumID) {
1304− override class func primaryKey() -> String? {
1307− class func by(id: PhotoAlbumID) -> PhotoAlbum {
1308− let realm = try! Realm()
1309− if let us = realm.object(ofType: PhotoAlbum.self, forPrimaryKey: id) {
1312− let us = PhotoAlbum()
1320− // init(id: PhotoAlbumID, thumbID: PhotoID, ownerID: UserID, title: String, dateCreated: Date, dateUpdated: Date, count: Int) {
1322− // self.thumbID = thumbID
1323− // self.ownerID = ownerID
1324− // self.title = title
1325− // self.dateCreated = dateCreated
1326− // self.dateUpdated = dateUpdated
1327− // self.count = count
1331−typealias PhotoID = Int
1332−typealias PhotoAlbumID = Int
1333−typealias Key = String
1335−class WallPost: Object {
1336− @objc dynamic var id: Int = 0
1337− @objc dynamic var owner: User?
1338− @objc dynamic var creator: User?
1339− @objc dynamic var date: Date?
1340− @objc dynamic var body: String?
1341− let commentCount = RealmOptional<Int>()
1342− let canPostComment = RealmOptional<Bool>()
1343− let likeCount = RealmOptional<Int>()
1344− @objc dynamic var liked: Bool = false
1345− let canLike = RealmOptional<Bool>()
1346− let repostCount = RealmOptional<Int>()
1347− let canDelete = RealmOptional<Bool>()
1348− let didRepost = RealmOptional<Bool>()
1350− let attachments = List<RealmMedia>()
1351− @objc dynamic var geo: Geolocation?
1352− // TODO: let postSource
1353− @objc dynamic var signed: User?
1354− @objc dynamic var ownerOfCopy: User?
1355− @objc dynamic var original: WallPost?
1356− let historyOfCopy = List<WallPost>()
1357− let canPin = RealmOptional<Bool>()
1358− let canEdit = RealmOptional<Bool>()
1359− let isPinned = RealmOptional<Bool>()
1361− // convenience init(id: WallPostID, ownerID: UserID, creatorID: UserID, date: Date, body: String, commentCount: Int, canPostComment: Bool, likeCount: Int, liked: Bool, canLike: Bool, repostCount: Int, didRepost: Bool, attachments: [Media], geo: Geolocation?, signed: UserID?, copyID: WallPostID?, canDelete: Bool, canPin: Bool?, canEdit: Bool?, isPinned: Bool?, copyHistory: [WallPostID], copyOwnerID: UserID?) {
1363− // self.ownerID = ownerID
1364− // self.creatorID = creatorID
1365− // self.date = date
1366− // self.body = body
1367− // self.commentCount = commentCount
1368− // self.canPostComment = canPostComment
1369− // self.likeCount = likeCount
1370− // self.liked = liked
1371− // self.canLike = canLike
1372− // self.repostCount = repostCount
1373− // self.didRepost = didRepost
1374− // self.attachments = attachments
1376− // self.signed = signed
1377− // self.copyID = copyID
1378− // self.canDelete = canDelete
1379− // self.canPin = canPin
1380− // self.canEdit = canEdit
1381− // self.isPinned = isPinned
1382− // self.copyHistory = copyHistory
1383− // self.copyOwnerID = copyOwnerID
1386−// func get(completion: ((WallPost?) -> ())? = nil) {
1387−// if let ownerID = owner?.id {
1388−// var ph = "\(ownerID)_\(id)"
1389−// // if let key = accessKey {
1390−// // ph.append("_\(key)")
1392−// VK.API.Wall.getById([VK.Arg.posts: ph]).send(onSuccess: { (response) in
1393−// if let json = response.array?.first {
1394−// let photo = VKData.processWallPost(json)
1395−// completion?(photo)
1399−// }, onError: { (error) in
1406− func get(completion: ((WallPost?) -> ())? = nil) {
1407− VKServer.get(wallPost: self) { (data) in
1408− if let json = JSON.init(data: data)["response"].array?.first {
1409− let post = VKData.processWallPost(json)
1417− override class func primaryKey() -> String? {
1421− class func by(id: WallPostID) -> WallPost {
1422− let realm = try! Realm()
1423− if let us = realm.object(ofType: WallPost.self, forPrimaryKey: id) {
1426− let us = WallPost()
1434−typealias WallPostID = Int
1436−class WallPostReply: Object {
1437− @objc dynamic var id: WallPostReplyID = 0
1438− @objc dynamic var author: User?
1439− @objc dynamic var wallPost: WallPost?
1440− @objc dynamic var wallOwner: User?
1441− @objc dynamic var date: Date?
1442− @objc dynamic var body: String?
1443− let likeCount = RealmOptional<Int>()
1444− let didLike = RealmOptional<Bool>()
1445− let canLike = RealmOptional<Bool>()
1446− @objc dynamic var inReplyToUser: User?
1447− let attachments = List<RealmMedia>()
1448− @objc dynamic var inReplyToComment: WallPostReply?
1449− class func by(id: WallPostReplyID) -> WallPostReply {
1450− let realm = try! Realm()
1451− if let us = realm.object(ofType: WallPostReply.self, forPrimaryKey: id) {
1454− let us = WallPostReply()
1461− func get(completion: (() -> ())) {
1462− // TODO: Get wallPostReply
1465− override class func primaryKey() -> String? {
1469−typealias WallPostReplyID = Int
1471−class Sticker: Object {
1472− @objc dynamic var id: StickerID = 0
1473− @objc dynamic var packID: StickerPackID = 0
1474− @objc dynamic var image: RealmPhoto?
1475− var imageID: String {
1476− return "sticker\(id)image"
1478− let width = RealmOptional<Int>()
1479− let height = RealmOptional<Int>()
1481− convenience init(id: StickerID, packID: StickerPackID, width: Int, height: Int) {
1484− self.packID = packID
1485− self.width.value = width
1486− self.height.value = height
1488− class func by(id: StickerID) -> Sticker {
1489− let realm = try! Realm()
1490− if let us = realm.object(ofType: Sticker.self, forPrimaryKey: id) {
1500− override class func primaryKey() -> String? {
1503− override static func ignoredProperties() -> [String] {
1507−typealias StickerID = Int
1508−typealias StickerPackID = Int
1510−class Gift: Object {
1511− @objc dynamic var id: GiftID = 0
1512− @objc dynamic var image: RealmPhoto?
1513− var imageID: String {
1514− return "gift\(id)image"
1516− convenience init(id: GiftID, surl: String) {
1519− self.image = RealmPhoto.by(imageID, surl: surl)
1521− class func by(id: GiftID) -> Gift {
1522− let realm = try! Realm()
1523− if let us = realm.object(ofType: Gift.self, forPrimaryKey: id) {
1533− override class func primaryKey() -> String? {
1536− override static func ignoredProperties() -> [String] {
1540−typealias GiftID = Int
1542−class Link: Object {
1545− return surl =>> {URL(string: $0)}
1548− @objc dynamic var surl: String = ""
1549− @objc dynamic var title: String?
1550− @objc dynamic var caption: String?
1551− @objc dynamic var linkDescription: String?
1552− @objc dynamic var photo: Photo?
1553− let isExternal = RealmOptional<Bool>()
1554− //var product: Market?
1555− var rating: Rating? {
1557− if let stars = ratingStars.value,
1558− let count = ratingReviewCount.value {
1559− return Rating(stars: stars, reviewCount: count)
1564− ratingStars.value = newValue?.stars
1565− ratingReviewCount.value = newValue?.reviewCount
1568− private let ratingStars = RealmOptional<Int>()
1569− private let ratingReviewCount = RealmOptional<Int>()
1570− //let application: Application?
1571− var button: LinkButton? {
1573− if let title = buttonTitle,
1574− let url = buttonURL {
1575− return LinkButton(title: title, url: url)
1580− buttonURL = newValue?.url
1581− buttonTitle = newValue?.title
1584− @objc private dynamic var buttonTitle: String?
1585− private var buttonURL: URL? {
1587− return buttonSURL =>> {URL(string: $0)}
1590− buttonSURL = newValue?.absoluteString
1593− private var buttonSURL: String?
1594− //let previewURL: URL
1596− class func by(surl: String) -> Link {
1597− let realm = try! Realm()
1598− if let us = realm.object(ofType: Link.self, forPrimaryKey: surl) {
1607− override class func primaryKey() -> String? {
1610− override static func ignoredProperties() -> [String] {
1611− return ["url", "rating", "button", "buttonURL"]
1618− let reviewCount: Int
1626−class Market: Object {
1627− @objc dynamic var id: MarketID = 0
1628− @objc dynamic var owner: User?
1629− @objc dynamic var title: String?
1630− @objc dynamic var marketDescription: String?
1631− let amount = RealmOptional<Int>()
1632− let price = RealmOptional<Int>()
1633− let currencyID = RealmOptional<CurrencyID>()
1634− @objc dynamic var currencyName: String?
1635− @objc dynamic var priceString: String?
1636− let categoryID = RealmOptional<MarketCategoryID>()
1637− @objc dynamic var categoryName: String?
1638− let sectionID = RealmOptional<MarketSectionID>()
1639− @objc dynamic var sectionName: String?
1640− @objc dynamic var image: RealmPhoto?
1641− var imageID: String {
1642− return "market\(id)image"
1644− @objc dynamic var creationDate: Date?
1645− var availability: MarketAvailability? {
1647− availabilityInt.value = newValue?.rawValue
1650− return availabilityInt.value =>> {MarketAvailability(rawValue: $0)}
1653− private let availabilityInt = RealmOptional<Int>()
1654− let photos = List<Photo>()
1655− let canComment = RealmOptional<Bool>()
1656− let canRepost = RealmOptional<Bool>()
1657− let likesCount = RealmOptional<Int>()
1658− let liked = RealmOptional<Bool>()
1660− class func by(id: MarketID) -> Market {
1661− let realm = try! Realm()
1662− if let us = realm.object(ofType: Market.self, forPrimaryKey: id) {
1672− override class func primaryKey() -> String? {
1675− override static func ignoredProperties() -> [String] {
1679−typealias CurrencyID = Int
1680−typealias MarketCategoryID = Int
1681−typealias MarketSectionID = Int
1682−enum MarketAvailability: Int {
1683− case availability = 0
1685− case notAvailability
1687−typealias MarketID = Int
1689−class MarketAlbum: Object {
1690− @objc dynamic var id: MarketAlbumID = 0
1691− @objc dynamic var owner: User?
1692− @objc dynamic var title: String?
1693− @objc dynamic var photo: Photo?
1694− let count = RealmOptional<Int>()
1695− @objc dynamic var updateTime: Date?
1696− override class func primaryKey() -> String? {
1700−typealias MarketAlbumID = Int
1702−class Video: Object {
1703− @objc dynamic var id: VideoID = 0
1704− @objc dynamic var owner: User?
1705− @objc dynamic var title: String?
1706− @objc dynamic var videoDescription: String?
1707− let duration = RealmOptional<TimeInterval>()
1708− @objc dynamic var thumbnail: RealmPhoto?
1709− var thumbnailID: String {
1710− return "video\(id)thumbnail"
1714− return playerSURL =>> {URL(string: $0)}
1717− playerSURL = newValue?.absoluteString
1720− @objc dynamic var playerSURL: String?
1721− @objc dynamic var accessKey: String?
1722− @objc dynamic var isProcessing: Bool = false
1723− @objc dynamic var isLive: Bool = false
1724− convenience init(id: VideoID, owner: User, title: String, description: String, duration: TimeInterval) {
1729− self.videoDescription = description
1730− self.duration.value = duration
1733− class func by(id: VideoID) -> Video {
1734− let realm = try! Realm()
1735− if let us = realm.object(ofType: Video.self, forPrimaryKey: id) {
1745−// func get(completion: ((Video?) -> ())? = nil) {
1746−// if let peerID = owner?.id {
1747−// var vi = "\(peerID)_\(id)"
1748−// if let key = accessKey {
1749−// vi.append("_\(key)")
1751−// VK.API.Video.get([VK.Arg.videos: vi]).send(onSuccess: { (response) in
1752−// if let json = response["items"].array?.first {
1753−// let video = VKData.processVideo(json)
1754−// completion?(video)
1758−// }, onError: { (error) in
1765− func get(completion: ((Video?) -> ())? = nil) {
1766− VKServer.get(video: self) { (data) in
1767− if let json = JSON.init(data: data)["response"].array?.first {
1768− let video = VKData.processVideo(json)
1774− override class func primaryKey() -> String? {
1777− override static func ignoredProperties() -> [String] {
1778− return ["player", "thumbnailID"]
1781−typealias VideoID = Int
1783−class Audio: Object {
1784− @objc dynamic var id: AudioID = 0
1785− @objc dynamic var owner: User?
1786− @objc dynamic var artist: String?
1787− @objc dynamic var title: String?
1788− let duration = RealmOptional<TimeInterval>()
1791− return surl =>> {URL(string: $0)}
1794− surl = newValue?.absoluteString
1797− @objc dynamic var surl: String?
1799− convenience init(id: AudioID) {
1803− class func by(id: AudioID) -> Audio {
1804− let realm = try! Realm()
1805− if let us = realm.object(ofType: Audio.self, forPrimaryKey: id) {
1815− override class func primaryKey() -> String? {
1818− override static func ignoredProperties() -> [String] {
1822−typealias AudioID = Int
1823−typealias LyricID = Int
1824−typealias AudioAlbumID = Int
1825−typealias GenreID = Int
1827−class Document: Object {
1828− @objc dynamic var id: DocumentID = 0
1829− @objc dynamic var owner: User?
1830− @objc dynamic var title: String?
1831− let size = RealmOptional<Int>()
1832− @objc dynamic var fileExtension: String?
1835− return surl =>> {URL(string: $0)}
1838− surl = newValue?.absoluteString
1841− @objc dynamic var surl: String?
1842− @objc dynamic var image: RealmPhoto?
1843− var imageID: String {
1844− return "doc\(id)image"
1846− var type: DocumentType? {
1848− return typeInt.value =>> {DocumentType(rawValue: $0)}
1851− typeInt.value = newValue?.rawValue
1854− private let typeInt = RealmOptional<Int>()
1855− convenience init(id: DocumentID, owner: User, title: String, size: Int, ext: String, url: URL, type: DocumentType) {
1860− self.size.value = size
1861− self.fileExtension = ext
1865− class func by(id: DocumentID) -> Document {
1866− let realm = try! Realm()
1867− if let us = realm.object(ofType: Document.self, forPrimaryKey: id) {
1870− let us = Document()
1877−// func get(completion: ((Document?) -> ())? = nil) {
1878−// if let ownerID = owner?.id {
1879−// var doc = "\(ownerID)_\(id)"
1880−// // if let key = accessKey {
1881−// // doc.append("_\(key)")
1883−// VK.API.Docs.getById([VK.Arg.docs: doc]).send(onSuccess: { response in
1884−// if let json = response.array?.first {
1885−// let document = VKData.processDocument(json)
1886−// completion?(document)
1890−// }, onError: { (error) in
1897− func get(completion: ((Document?) -> ())? = nil) {
1898− VKServer.get(doc: self) { (data) in
1899− if let json = JSON.init(data: data)["response"].array?.first {
1900− let doc = VKData.processDocument(json)
1906− override class func primaryKey() -> String? {
1909− override static func ignoredProperties() -> [String] {
1910− return ["url", "imageID"]
1913−typealias DocumentID = Int
1914−enum DocumentType: Int {
1926− var firstMessage: Message? { get }
1927− var important: Bool { get set }
1928− var name: String? { get }
1929− func loadImage(into view: UIImageView, completion: (() -> ())?) -> RealmPhotoToken?
1930− var messages: Messages? { get }
1931− var id: Int { get }
1932− var lastReadMessageID: Int { get set }
1933− var count: RealmOptional<Int> { get }
1934− var notificationSettings: RealmNotificatonSettings? { get set }
1935− var peerID: Int { get }
1938−func dialog(for id: DialogID) -> Dialog {
1939− if id > multichatchatId { // multichat
1940− let chat = Multichat.by(id: id - multichatchatId)
1943− //} else if id < 0 { // Pablic
1945− } else { // Normal user
1946− let chat = Chat.by(user: User.by(id: id))
1951−// For name conflicts
1952−func dialogFor(_ id: DialogID) -> Dialog {
1953− return dialog(for: id)
1956−class RealmDialog: Object, Comparable {
1958− // TODO: Remove these two
1959− @objc dynamic var dateLastSent: Date?
1960− /// Number of times a message has been sent in the dateLastSent second
1961− @objc dynamic var dateSentNumber = 0
1963− var value: Dialog? {
1965− return dialog(for: id)
1970− return value?.peerID
1973− @objc dynamic var id: DialogID = 0
1975− @objc dynamic var date: Date?
1977− class func by(dialog: Dialog) -> RealmDialog {
1978− return RealmDialog.by(peerID: dialog.peerID)
1981− class func by(peerID: Int) -> RealmDialog {
1982− if let dialog = (try? Realm())?.object(ofType: RealmDialog.self, forPrimaryKey: peerID) {
1985− let dialog = RealmDialog()
1987− realmWrite({ (realm) in
1994− override class func primaryKey() -> String? {
1997− override static func ignoredProperties() -> [String] {
1998− return ["value", "peerID"]
2001−func ==(lhs: RealmDialog, rhs: RealmDialog) -> Bool {
2002− return lhs.date == rhs.date
2004−func <(lhs: RealmDialog, rhs: RealmDialog) -> Bool {
2005− if let l = lhs.date,
2012−typealias DialogID = Int
2014−//func ==(lhs: Dialog, rhs: Dialog) -> Bool {
2015−// return lhs.date == rhs.date
2017−//func <(lhs: Dialog, rhs: Dialog) -> Bool {
2018−// return lhs.date < rhs.date
2021−class RealmNotificatonSettings: Object {
2022− var value: ChatNotificationSettings? {
2024− if let sound = notiSound.value,
2025− let never = notiDateNever.value {
2027− return ChatNotificationSettings(sound: sound, disabledUntil: .never)
2029− return notiDate >>> {ChatNotificationSettings(sound: sound, disabledUntil: .date($0))}
2035− notiSound.value = newValue?.sound
2036− if let newV = newValue {
2037− switch newV.disabledUntil {
2038− case .date(let date):
2040− notiDateNever.value = false
2042− notiDateNever.value = true
2048− private let notiSound = RealmOptional<Bool>()
2049− private let notiDateNever = RealmOptional<Bool>()
2050− @objc private dynamic var notiDate: Date?
2051− convenience init(value: ChatNotificationSettings?) {
2057−class Multichat: Object {
2058− @objc dynamic var id: MultichatID = 0
2059− @objc dynamic var admin: User?
2060− var timers: [UserID: Timer] = [:]
2061− var typingUsers: Set<User> = []
2062− @objc dynamic var title: String?
2063− let users = List<MultiChatUser>()
2064− @objc dynamic var messages: Messages?
2065− // let messages = List<Message>()
2066− @objc dynamic var lastReadMessageID = 0
2067− @objc dynamic var important = false
2068− @objc dynamic var answered = false
2069− @objc dynamic var date = Date()
2070− let count = RealmOptional<Int>()
2071− @objc dynamic var image: RealmPhoto?
2072− var imageID: String {
2073− return "mchat\(id)image"
2075− let attachments = List<RealmMedia>()
2077− @objc dynamic var notificationSettings: RealmNotificatonSettings?
2079− var participationStatus: MultichatStatus? {
2081− return participationStatusInt.value =>> {MultichatStatus(rawValue: $0)}
2084− participationStatusInt.value = newValue?.rawValue
2087− private let participationStatusInt = RealmOptional<Int>()
2089− // convenience init(id: MultichatID, adminID: UserID, title: String, userIDs: [(user: UserID, invitedBy: UserID)]?, notificationSettings: MultichatNotificationSettings?, participationStatus: MultichatStatus?) {
2091− // self.adminID = adminID
2092− // self.title = title
2093− // self.userIDs = userIDs
2094− // self.notificationSetting = notificationSettings
2095− // self.participationStatus = participationStatus
2097− class func by(id: MultichatID) -> Multichat {
2098− let realm = try! Realm()
2099− if let us = realm.object(ofType: Multichat.self, forPrimaryKey: id) {
2102−// VkServices.getMultichat(for: id)
2103− let us = Multichat()
2104− realmWrite { realm in
2106− us.messages = Messages.by(id: us.peerID)
2113− override class func primaryKey() -> String? {
2116− override static func ignoredProperties() -> [String] {
2117− return ["imageID", "typingUsers", "timers"]
2121−extension Multichat: Dialog {
2122− var firstMessage: Message? {
2123− return messages?.first
2126− var name: String? {
2130− func loadImage(into view: UIImageView, completion: (() -> ())? = nil) -> RealmPhotoToken? {
2131− return image?.load(into: view, completion: completion)
2133− // func image(completion: @escaping ((UIImage?) -> ())) {
2134− // if let im = image?.image {
2142− return id + multichatchatId
2146−class MultiChatUser: Object {
2147− @objc dynamic var user: User?
2148− @objc dynamic var invitedBy: User?
2149− convenience init(_ user: User, invitedBy: User) {
2152− self.invitedBy = invitedBy
2156−enum MultichatStatus: Int {
2162−class Chat: Object {
2163− @objc dynamic var user: User? {
2165− user >>> {userID = $0.id}
2169− @objc dynamic var date = Date()
2170− @objc dynamic var userID = 0
2171− @objc dynamic var isTyping = false
2172− @objc dynamic var lastReadMessageID = 0
2173− let count = RealmOptional<Int>()
2174− @objc dynamic var messages: Messages?
2175− // let messages = List<Message>()
2176− @objc dynamic var important = false
2177− @objc dynamic var answered = false
2178− let attachments = List<RealmMedia>()
2179− @objc dynamic var notificationSettings: RealmNotificatonSettings?
2180− class func by(user: User) -> Chat {
2181− let realm = try! Realm()
2182− if let us = realm.object(ofType: Chat.self, forPrimaryKey: user.id) {
2186− realmWrite { realm in
2188− us.messages = Messages.by(id: us.peerID)
2195− convenience init(user: User) {
2199− override static func ignoredProperties() -> [String] {
2202− override class func primaryKey() -> String? {
2207−extension Chat: Dialog {
2208− var firstMessage: Message? {
2209− return messages?.first
2212− var name: String? {
2213− if let firstName = user?.firstName,
2214− let lastName = user?.lastName {
2215− return "\(firstName) \(lastName)"
2221− func loadImage(into view: UIImageView, completion: (() -> ())? = nil) -> RealmPhotoToken? {
2222− return user?.avatar?.load(into: view, completion: completion)
2225− // func image(completion: @escaping ((UIImage?) -> ())) {
2226− // if let im = user?.avatar?.image {
2242−struct ChatNotificationSettings {
2244− var disabledUntil: disableDate
2250− init?(value: Int) {
2257− self = .date(Date(timeIntervalSince1970: TimeInterval(value)))
2262−func isPhoneNumber(_ phone: String) -> Bool {
2263− let nums = "1234567890".characters
2264− let f002 = phone.characters.map{nums.contains($0) ? 1 : 0}
2265− let foo1 = Double(sum(acc: 0, arr: f002))
2266− let foo = foo1/Double(phone.characters.count)
2267− return foo >= 0.4 ? true : false