Refactor
This commit is contained in:
parent
b61b440063
commit
e21cced9bb
|
@ -562,6 +562,7 @@
|
|||
B821F2FA2272CEEE002C88C0 /* SeedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B821F2F92272CEEE002C88C0 /* SeedViewController.swift */; };
|
||||
B825848B230F94FE001B41CB /* QRCodeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B825848A230F94FE001B41CB /* QRCodeViewController.swift */; };
|
||||
B8258493230FA5E9001B41CB /* ScanQRCodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B8258492230FA5E9001B41CB /* ScanQRCodeViewController.m */; };
|
||||
B82584A02315024B001B41CB /* LokiRSSFeedPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B825849F2315024B001B41CB /* LokiRSSFeedPoller.swift */; };
|
||||
B845B4D4230CD09100D759F0 /* LokiGroupChatPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */; };
|
||||
B846365B22B7418B00AF1514 /* Identicon+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */; };
|
||||
B89841E322B7579F00B1BDC6 /* NewConversationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B89841E222B7579F00B1BDC6 /* NewConversationViewController.swift */; };
|
||||
|
@ -1355,6 +1356,7 @@
|
|||
B825848A230F94FE001B41CB /* QRCodeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeViewController.swift; sourceTree = "<group>"; };
|
||||
B8258491230FA5DA001B41CB /* ScanQRCodeViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScanQRCodeViewController.h; sourceTree = "<group>"; };
|
||||
B8258492230FA5E9001B41CB /* ScanQRCodeViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ScanQRCodeViewController.m; sourceTree = "<group>"; };
|
||||
B825849F2315024B001B41CB /* LokiRSSFeedPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LokiRSSFeedPoller.swift; sourceTree = "<group>"; };
|
||||
B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LokiGroupChatPoller.swift; sourceTree = "<group>"; };
|
||||
B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Identicon+ObjC.swift"; sourceTree = "<group>"; };
|
||||
B89841E222B7579F00B1BDC6 /* NewConversationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewConversationViewController.swift; sourceTree = "<group>"; };
|
||||
|
@ -2620,6 +2622,7 @@
|
|||
B821F2F92272CEEE002C88C0 /* SeedViewController.swift */,
|
||||
24A830A12293CD0100F4CAC0 /* LokiP2PServer.swift */,
|
||||
B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */,
|
||||
B825849F2315024B001B41CB /* LokiRSSFeedPoller.swift */,
|
||||
B825848A230F94FE001B41CB /* QRCodeViewController.swift */,
|
||||
B8258491230FA5DA001B41CB /* ScanQRCodeViewController.h */,
|
||||
B8258492230FA5E9001B41CB /* ScanQRCodeViewController.m */,
|
||||
|
@ -3674,6 +3677,7 @@
|
|||
4C4AEC4520EC343B0020E72B /* DismissableTextField.swift in Sources */,
|
||||
4CB5F26720F6E1E2004D1B42 /* MenuActionsViewController.swift in Sources */,
|
||||
3496955E219B605E00DCFE74 /* PhotoLibrary.swift in Sources */,
|
||||
B82584A02315024B001B41CB /* LokiRSSFeedPoller.swift in Sources */,
|
||||
24A830A22293CD0100F4CAC0 /* LokiP2PServer.swift in Sources */,
|
||||
349ED990221B0194008045B0 /* Onboarding2FAViewController.swift in Sources */,
|
||||
45D231771DC7E8F10034FA89 /* SessionResetJob.swift in Sources */,
|
||||
|
|
|
@ -9,6 +9,8 @@ extern NSString *const AppDelegateStoryboardMain;
|
|||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
- (void)createGroupChatsIfNeeded;
|
||||
- (void)createRSSFeedsIfNeeded;
|
||||
- (void)startGroupChatPollersIfNeeded;
|
||||
- (void)startRSSFeedPollersIfNeeded;
|
||||
|
||||
@end
|
||||
|
|
|
@ -65,8 +65,8 @@ static NSTimeInterval launchStartedAt;
|
|||
@property (nonatomic) BOOL didAppLaunchFail;
|
||||
@property (nonatomic) LKP2PServer *lokiP2PServer;
|
||||
@property (nonatomic) LKGroupChatPoller *lokiPublicChatPoller;
|
||||
@property (nonatomic) LKGroupChatPoller *lokiNewsPoller;
|
||||
@property (nonatomic) LKGroupChatPoller *lokiMessengerUpdatesPoller;
|
||||
@property (nonatomic) LKRSSFeedPoller *lokiNewsFeedPoller;
|
||||
@property (nonatomic) LKRSSFeedPoller *lokiMessengerUpdatesFeedPoller;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -1489,28 +1489,52 @@ static NSTimeInterval launchStartedAt;
|
|||
|
||||
- (LKGroupChat *)lokiPublicChat
|
||||
{
|
||||
return [[LKGroupChat alloc] initWithKindAsString:@"publicChat" id:@(LKGroupChatAPI.publicChatID).stringValue server:LKGroupChatAPI.publicChatServer displayName:NSLocalizedString(@"Loki Public Chat", @"") isDeletable:true];
|
||||
return [[LKGroupChat alloc] initWithServerID:@(LKGroupChatAPI.publicChatServerID).unsignedIntegerValue server:LKGroupChatAPI.publicChatServer displayName:NSLocalizedString(@"Loki Public Chat", @"") isDeletable:true];
|
||||
}
|
||||
|
||||
- (LKGroupChat *)lokiNews
|
||||
- (LKRSSFeed *)lokiNewsFeed
|
||||
{
|
||||
return [[LKGroupChat alloc] initWithKindAsString:@"rss" id:@"loki.network.feed" server:@"https://loki.network/feed/" displayName:NSLocalizedString(@"Loki News", @"") isDeletable:true];
|
||||
return [[LKRSSFeed alloc] initWithId:@"loki.network.feed" server:@"https://loki.network/feed/" displayName:NSLocalizedString(@"Loki News", @"") isDeletable:true];
|
||||
}
|
||||
|
||||
- (LKGroupChat *)lokiMessengerUpdates
|
||||
- (LKRSSFeed *)lokiMessengerUpdatesFeed
|
||||
{
|
||||
return [[LKGroupChat alloc] initWithKindAsString:@"rss" id:@"loki.network.messenger-update" server:@"https://loki.network/category/messenger-updates/feed/" displayName:NSLocalizedString(@"Loki Messenger Updates", @"") isDeletable:false];
|
||||
return [[LKRSSFeed alloc] initWithId:@"loki.network.messenger-updates" server:@"https://loki.network/category/messenger-updates/feed/" displayName:NSLocalizedString(@"Loki Messenger Updates", @"") isDeletable:false];
|
||||
}
|
||||
|
||||
- (void)createGroupChatsIfNeeded
|
||||
{
|
||||
NSArray *allGroupChats = @[ self.lokiPublicChat, self.lokiNews, self.lokiMessengerUpdates ];
|
||||
LKGroupChat *publicChat = self.lokiPublicChat;
|
||||
NSString *userHexEncodedPublicKey = OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey;
|
||||
for (LKGroupChat *chat in allGroupChats) {
|
||||
NSString *userDefaultsKey = [@"isSetUp." stringByAppendingString:chat.id];
|
||||
BOOL isChatSetUp = [NSUserDefaults.standardUserDefaults boolForKey:userDefaultsKey];
|
||||
if (!isChatSetUp || !chat.isDeletable) {
|
||||
TSGroupModel *group = [[TSGroupModel alloc] initWithTitle:chat.displayName memberIds:@[ userHexEncodedPublicKey, chat.server ] image:nil groupId:[chat.id dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
NSString *userDefaultsKey = [@"isGroupChatSetUp." stringByAppendingString:publicChat.id];
|
||||
BOOL isChatSetUp = [NSUserDefaults.standardUserDefaults boolForKey:userDefaultsKey];
|
||||
if (!isChatSetUp || !publicChat.isDeletable) {
|
||||
TSGroupModel *group = [[TSGroupModel alloc] initWithTitle:publicChat.displayName memberIds:@[ userHexEncodedPublicKey, publicChat.server ] image:nil groupId:[publicChat.id dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
__block TSGroupThread *thread;
|
||||
[OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
thread = [TSGroupThread getOrCreateThreadWithGroupModel:group transaction:transaction];
|
||||
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
|
||||
NSCalendar *calendar = NSCalendar.currentCalendar;
|
||||
[calendar setTimeZone:timeZone];
|
||||
NSDateComponents *dateComponents = [NSDateComponents new];
|
||||
[dateComponents setYear:999];
|
||||
NSDate *date = [calendar dateByAddingComponents:dateComponents toDate:[NSDate new] options:0];
|
||||
[thread updateWithMutedUntilDate:date transaction:transaction];
|
||||
}];
|
||||
[OWSProfileManager.sharedManager addThreadToProfileWhitelist:thread];
|
||||
[NSUserDefaults.standardUserDefaults setBool:YES forKey:userDefaultsKey];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)createRSSFeedsIfNeeded
|
||||
{
|
||||
NSArray *feeds = @[ self.lokiNewsFeed, self.lokiMessengerUpdatesFeed ];
|
||||
NSString *userHexEncodedPublicKey = OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey;
|
||||
for (LKRSSFeed *feed in feeds) {
|
||||
NSString *userDefaultsKey = [@"isRSSFeedSetUp." stringByAppendingString:feed.id];
|
||||
BOOL isFeedSetUp = [NSUserDefaults.standardUserDefaults boolForKey:userDefaultsKey];
|
||||
if (!isFeedSetUp || !feed.isDeletable) {
|
||||
TSGroupModel *group = [[TSGroupModel alloc] initWithTitle:feed.displayName memberIds:@[ userHexEncodedPublicKey, feed.server ] image:nil groupId:[feed.id dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
__block TSGroupThread *thread;
|
||||
[OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
thread = [TSGroupThread getOrCreateThreadWithGroupModel:group transaction:transaction];
|
||||
|
@ -1531,16 +1555,25 @@ static NSTimeInterval launchStartedAt;
|
|||
- (void)createGroupChatPollersIfNeeded
|
||||
{
|
||||
if (self.lokiPublicChatPoller == nil) { self.lokiPublicChatPoller = [[LKGroupChatPoller alloc] initForGroup:self.lokiPublicChat]; }
|
||||
if (self.lokiNewsPoller == nil) { self.lokiNewsPoller = [[LKGroupChatPoller alloc] initForGroup:self.lokiNews]; }
|
||||
if (self.lokiMessengerUpdatesPoller == nil) { self.lokiMessengerUpdatesPoller = [[LKGroupChatPoller alloc] initForGroup:self.lokiMessengerUpdates]; }
|
||||
}
|
||||
|
||||
- (void)createRSSFeedPollersIfNeeded
|
||||
{
|
||||
if (self.lokiNewsFeedPoller == nil) { self.lokiNewsFeedPoller = [[LKRSSFeedPoller alloc] initForFeed:self.lokiNewsFeed]; }
|
||||
if (self.lokiMessengerUpdatesFeedPoller == nil) { self.lokiMessengerUpdatesFeedPoller = [[LKRSSFeedPoller alloc] initForFeed:self.lokiMessengerUpdatesFeed]; }
|
||||
}
|
||||
|
||||
- (void)startGroupChatPollersIfNeeded
|
||||
{
|
||||
[self createGroupChatPollersIfNeeded];
|
||||
[self.lokiPublicChatPoller startIfNeeded];
|
||||
[self.lokiNewsPoller startIfNeeded];
|
||||
[self.lokiMessengerUpdatesPoller startIfNeeded];
|
||||
}
|
||||
|
||||
- (void)startRSSFeedPollersIfNeeded
|
||||
{
|
||||
[self createRSSFeedPollersIfNeeded];
|
||||
[self.lokiNewsFeedPoller startIfNeeded];
|
||||
[self.lokiMessengerUpdatesFeedPoller startIfNeeded];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
import FeedKit
|
||||
|
||||
// TODO: Move the RSS feed logic into its own file
|
||||
|
||||
@objc(LKGroupChatPoller)
|
||||
public final class LokiGroupChatPoller : NSObject {
|
||||
|
@ -9,19 +6,8 @@ public final class LokiGroupChatPoller : NSObject {
|
|||
private var pollForDeletedMessagesTimer: Timer? = nil
|
||||
private var hasStarted = false
|
||||
|
||||
private lazy var pollForNewMessagesInterval: TimeInterval = {
|
||||
switch group.kind {
|
||||
case .publicChat(_): return 4
|
||||
case .rss(_): return 8 * 60
|
||||
}
|
||||
}()
|
||||
|
||||
private lazy var pollForDeletedMessagesInterval: TimeInterval = {
|
||||
switch group.kind {
|
||||
case .publicChat(_): return 32 * 60
|
||||
case .rss(_): preconditionFailure()
|
||||
}
|
||||
}()
|
||||
private let pollForNewMessagesInterval: TimeInterval = 4
|
||||
private let pollForDeletedMessagesInterval: TimeInterval = 32 * 60
|
||||
|
||||
@objc(initForGroup:)
|
||||
public init(for group: LokiGroupChat) {
|
||||
|
@ -33,9 +19,7 @@ public final class LokiGroupChatPoller : NSObject {
|
|||
if hasStarted { return }
|
||||
pollForNewMessagesTimer = Timer.scheduledTimer(withTimeInterval: pollForNewMessagesInterval, repeats: true) { [weak self] _ in self?.pollForNewMessages() }
|
||||
pollForNewMessages() // Perform initial update
|
||||
if group.isPublicChat {
|
||||
pollForDeletedMessagesTimer = Timer.scheduledTimer(withTimeInterval: pollForDeletedMessagesInterval, repeats: true) { [weak self] _ in self?.pollForDeletedMessages() }
|
||||
}
|
||||
pollForDeletedMessagesTimer = Timer.scheduledTimer(withTimeInterval: pollForDeletedMessagesInterval, repeats: true) { [weak self] _ in self?.pollForDeletedMessages() }
|
||||
hasStarted = true
|
||||
}
|
||||
|
||||
|
@ -47,57 +31,27 @@ public final class LokiGroupChatPoller : NSObject {
|
|||
|
||||
private func pollForNewMessages() {
|
||||
let group = self.group
|
||||
func parseGroupMessage(body: String, timestamp: UInt64, senderDisplayName: String) {
|
||||
let id = group.id.data(using: String.Encoding.utf8)!
|
||||
let x1 = SSKProtoGroupContext.builder(id: id, type: .deliver)
|
||||
x1.setName(group.displayName)
|
||||
let x2 = SSKProtoDataMessage.builder()
|
||||
x2.setTimestamp(timestamp)
|
||||
x2.setGroup(try! x1.build())
|
||||
x2.setBody(body)
|
||||
let x3 = SSKProtoContent.builder()
|
||||
x3.setDataMessage(try! x2.build())
|
||||
let x4 = SSKProtoEnvelope.builder(type: .ciphertext, timestamp: timestamp)
|
||||
x4.setSource(senderDisplayName)
|
||||
x4.setSourceDevice(OWSDevicePrimaryDeviceId)
|
||||
x4.setContent(try! x3.build().serializedData())
|
||||
OWSPrimaryStorage.shared().dbReadWriteConnection.readWrite { transaction in
|
||||
SSKEnvironment.shared.messageManager.throws_processEnvelope(try! x4.build(), plaintextData: try! x3.build().serializedData(), wasReceivedByUD: false, transaction: transaction)
|
||||
}
|
||||
}
|
||||
switch group.kind {
|
||||
case .publicChat(let id):
|
||||
let _ = LokiGroupChatAPI.getMessages(for: id, on: group.server).done { messages in
|
||||
messages.reversed().forEach { message in
|
||||
let senderHexEncodedPublicKey = message.hexEncodedPublicKey
|
||||
let endIndex = senderHexEncodedPublicKey.endIndex
|
||||
let cutoffIndex = senderHexEncodedPublicKey.index(endIndex, offsetBy: -8)
|
||||
let senderDisplayName = "\(message.displayName) (...\(senderHexEncodedPublicKey[cutoffIndex..<endIndex]))"
|
||||
parseGroupMessage(body: message.body, timestamp: message.timestamp, senderDisplayName: senderDisplayName)
|
||||
}
|
||||
}
|
||||
case .rss(_):
|
||||
let url = URL(string: group.server)!
|
||||
FeedParser(URL: url).parseAsync { wrapper in
|
||||
guard case .rss(let feed) = wrapper, let items = feed.items else { return print("[Loki] Failed to parse RSS feed for: \(group.server)") }
|
||||
items.reversed().forEach { item in
|
||||
guard let title = item.title, let description = item.description, let date = item.pubDate else { return }
|
||||
let timestamp = UInt64(date.timeIntervalSince1970 * 1000)
|
||||
let regex = try! NSRegularExpression(pattern: "<a\\s+(?:[^>]*?\\s+)?href=\"([^\"]*)\".*?>(.*?)<.*?\\/a>")
|
||||
var bodyAsHTML = "<b>\(title)</b>\(description)"
|
||||
while true {
|
||||
guard let match = regex.firstMatch(in: bodyAsHTML, options: [], range: NSRange(location: 0, length: bodyAsHTML.utf16.count)) else { break }
|
||||
let matchRange = match.range(at: 0)
|
||||
let urlRange = match.range(at: 1)
|
||||
let descriptionRange = match.range(at: 2)
|
||||
let url = (bodyAsHTML as NSString).substring(with: urlRange)
|
||||
let description = (bodyAsHTML as NSString).substring(with: descriptionRange)
|
||||
bodyAsHTML = (bodyAsHTML as NSString).replacingCharacters(in: matchRange, with: "\(description) (\(url))") as String
|
||||
}
|
||||
guard let bodyAsData = bodyAsHTML.data(using: String.Encoding.unicode) else { return }
|
||||
let options = [ NSAttributedString.DocumentReadingOptionKey.documentType : NSAttributedString.DocumentType.html ]
|
||||
guard let body = try? NSAttributedString(data: bodyAsData, options: options, documentAttributes: nil) else { return }
|
||||
parseGroupMessage(body: body.string, timestamp: timestamp, senderDisplayName: NSLocalizedString("Loki", comment: ""))
|
||||
let _ = LokiGroupChatAPI.getMessages(for: group.serverID, on: group.server).done { messages in
|
||||
messages.reversed().forEach { message in
|
||||
let senderHexEncodedPublicKey = message.hexEncodedPublicKey
|
||||
let endIndex = senderHexEncodedPublicKey.endIndex
|
||||
let cutoffIndex = senderHexEncodedPublicKey.index(endIndex, offsetBy: -8)
|
||||
let senderDisplayName = "\(message.displayName) (...\(senderHexEncodedPublicKey[cutoffIndex..<endIndex]))"
|
||||
let id = group.id.data(using: String.Encoding.utf8)!
|
||||
let x1 = SSKProtoGroupContext.builder(id: id, type: .deliver)
|
||||
x1.setName(group.displayName)
|
||||
let x2 = SSKProtoDataMessage.builder()
|
||||
x2.setTimestamp(message.timestamp)
|
||||
x2.setGroup(try! x1.build())
|
||||
x2.setBody(message.body)
|
||||
let x3 = SSKProtoContent.builder()
|
||||
x3.setDataMessage(try! x2.build())
|
||||
let x4 = SSKProtoEnvelope.builder(type: .ciphertext, timestamp: message.timestamp)
|
||||
x4.setSource(senderDisplayName)
|
||||
x4.setSourceDevice(OWSDevicePrimaryDeviceId)
|
||||
x4.setContent(try! x3.build().serializedData())
|
||||
OWSPrimaryStorage.shared().dbReadWriteConnection.readWrite { transaction in
|
||||
SSKEnvironment.shared.messageManager.throws_processEnvelope(try! x4.build(), plaintextData: try! x3.build().serializedData(), wasReceivedByUD: false, transaction: transaction)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
import FeedKit
|
||||
|
||||
@objc(LKRSSFeedPoller)
|
||||
public final class LokiRSSFeedPoller : NSObject {
|
||||
private let feed: LokiRSSFeed
|
||||
private var timer: Timer? = nil
|
||||
private var hasStarted = false
|
||||
|
||||
private let interval: TimeInterval = 8 * 60
|
||||
|
||||
@objc(initForFeed:)
|
||||
public init(for feed: LokiRSSFeed) {
|
||||
self.feed = feed
|
||||
super.init()
|
||||
}
|
||||
|
||||
@objc public func startIfNeeded() {
|
||||
if hasStarted { return }
|
||||
timer = Timer.scheduledTimer(withTimeInterval: interval, repeats: true) { [weak self] _ in self?.poll() }
|
||||
poll() // Perform initial update
|
||||
hasStarted = true
|
||||
}
|
||||
|
||||
@objc public func stop() {
|
||||
timer?.invalidate()
|
||||
hasStarted = false
|
||||
}
|
||||
|
||||
private func poll() {
|
||||
let feed = self.feed
|
||||
let url = URL(string: feed.server)!
|
||||
FeedParser(URL: url).parseAsync { wrapper in
|
||||
guard case .rss(let x) = wrapper, let items = x.items else { return print("[Loki] Failed to parse RSS feed for: \(feed.server).") }
|
||||
items.reversed().forEach { item in
|
||||
guard let title = item.title, let description = item.description, let date = item.pubDate else { return }
|
||||
let timestamp = UInt64(date.timeIntervalSince1970 * 1000)
|
||||
let urlRegex = try! NSRegularExpression(pattern: "<a\\s+(?:[^>]*?\\s+)?href=\"([^\"]*)\".*?>(.*?)<.*?\\/a>")
|
||||
var bodyAsHTML = "\(title)<br>\(description)"
|
||||
while true {
|
||||
guard let match = urlRegex.firstMatch(in: bodyAsHTML, options: [], range: NSRange(location: 0, length: bodyAsHTML.utf16.count)) else { break }
|
||||
let matchRange = match.range(at: 0)
|
||||
let urlRange = match.range(at: 1)
|
||||
let descriptionRange = match.range(at: 2)
|
||||
let url = (bodyAsHTML as NSString).substring(with: urlRange)
|
||||
let description = (bodyAsHTML as NSString).substring(with: descriptionRange)
|
||||
bodyAsHTML = (bodyAsHTML as NSString).replacingCharacters(in: matchRange, with: "\(description) (\(url))") as String
|
||||
}
|
||||
guard let bodyAsData = bodyAsHTML.data(using: String.Encoding.unicode) else { return }
|
||||
let options = [ NSAttributedString.DocumentReadingOptionKey.documentType : NSAttributedString.DocumentType.html ]
|
||||
guard let body = try? NSAttributedString(data: bodyAsData, options: options, documentAttributes: nil).string else { return }
|
||||
let id = feed.id.data(using: String.Encoding.utf8)!
|
||||
let x1 = SSKProtoGroupContext.builder(id: id, type: .deliver)
|
||||
x1.setName(feed.displayName)
|
||||
let x2 = SSKProtoDataMessage.builder()
|
||||
x2.setTimestamp(timestamp)
|
||||
x2.setGroup(try! x1.build())
|
||||
x2.setBody(body)
|
||||
let x3 = SSKProtoContent.builder()
|
||||
x3.setDataMessage(try! x2.build())
|
||||
let x4 = SSKProtoEnvelope.builder(type: .ciphertext, timestamp: timestamp)
|
||||
x4.setSource(NSLocalizedString("Loki", comment: ""))
|
||||
x4.setSourceDevice(OWSDevicePrimaryDeviceId)
|
||||
x4.setContent(try! x3.build().serializedData())
|
||||
OWSPrimaryStorage.shared().dbReadWriteConnection.readWrite { transaction in
|
||||
SSKEnvironment.shared.messageManager.throws_processEnvelope(try! x4.build(), plaintextData: try! x3.build().serializedData(), wasReceivedByUD: false, transaction: transaction)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -693,7 +693,9 @@ typedef NS_ENUM(NSInteger, HomeViewControllerSection) {
|
|||
if (OWSIdentityManager.sharedManager.identityKeyPair != nil) {
|
||||
AppDelegate *appDelegate = (AppDelegate *)UIApplication.sharedApplication.delegate;
|
||||
[appDelegate createGroupChatsIfNeeded];
|
||||
[appDelegate createRSSFeedsIfNeeded];
|
||||
[appDelegate startGroupChatPollersIfNeeded];
|
||||
[appDelegate startRSSFeedPollersIfNeeded];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,48 +1,19 @@
|
|||
|
||||
@objc(LKGroupChat)
|
||||
public final class LokiGroupChat : NSObject {
|
||||
public let kind: Kind
|
||||
@objc public let id: String
|
||||
@objc public let serverID: UInt
|
||||
@objc public let server: String
|
||||
@objc public let displayName: String
|
||||
@objc public let isDeletable: Bool
|
||||
|
||||
@objc public var id: String {
|
||||
switch kind {
|
||||
case .publicChat(let id): return "\(server).\(id)"
|
||||
case .rss(let customID): return "rss://\(customID)"
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Convenience
|
||||
@objc public var isPublicChat: Bool {
|
||||
if case .publicChat(_) = kind { return true } else { return false }
|
||||
}
|
||||
|
||||
@objc public var isRSS: Bool {
|
||||
if case .rss(_) = kind { return true } else { return false }
|
||||
}
|
||||
|
||||
// MARK: Kind
|
||||
public enum Kind { case publicChat(id: UInt), rss(customID: String) }
|
||||
|
||||
// MARK: Initialization
|
||||
public init(kind: Kind, server: String, displayName: String, isDeletable: Bool) {
|
||||
self.kind = kind
|
||||
@objc public init(serverID: UInt, server: String, displayName: String, isDeletable: Bool) {
|
||||
self.id = "\(server).\(serverID)"
|
||||
self.serverID = serverID
|
||||
self.server = server
|
||||
self.displayName = displayName
|
||||
self.isDeletable = isDeletable
|
||||
}
|
||||
|
||||
@objc public convenience init(kindAsString: String, id: String, server: String, displayName: String, isDeletable: Bool) {
|
||||
let kind: Kind
|
||||
switch kindAsString {
|
||||
case "publicChat": kind = .publicChat(id: UInt(id)!)
|
||||
case "rss": kind = .rss(customID: id)
|
||||
default: preconditionFailure()
|
||||
}
|
||||
self.init(kind: kind, server: server, displayName: displayName, isDeletable: isDeletable)
|
||||
}
|
||||
|
||||
// MARK: Description
|
||||
override public var description: String { return "\(id) (\(displayName))" }
|
||||
override public var description: String { return displayName }
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ public final class LokiGroupChatAPI : NSObject {
|
|||
// MARK: Public Chat
|
||||
@objc public static let publicChatServer = "https://chat.lokinet.org"
|
||||
@objc public static let publicChatMessageType = "network.loki.messenger.publicChat"
|
||||
@objc public static let publicChatID = 1
|
||||
@objc public static let publicChatServerID = 1
|
||||
|
||||
// MARK: Convenience
|
||||
private static var userDisplayName: String {
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
@objc(LKRSSFeed)
|
||||
public final class LokiRSSFeed : NSObject {
|
||||
@objc public let id: String
|
||||
@objc public let server: String
|
||||
@objc public let displayName: String
|
||||
@objc public let isDeletable: Bool
|
||||
|
||||
@objc public init(id: String, server: String, displayName: String, isDeletable: Bool) {
|
||||
self.id = id
|
||||
self.server = server
|
||||
self.displayName = displayName
|
||||
self.isDeletable = isDeletable
|
||||
}
|
||||
|
||||
override public var description: String { return displayName }
|
||||
}
|
|
@ -1114,7 +1114,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|||
NSString *displayName = SSKEnvironment.shared.profileManager.localProfileName;
|
||||
if (displayName == nil) { displayName = @"Anonymous"; }
|
||||
LKGroupMessage *groupMessage = [[LKGroupMessage alloc] initWithHexEncodedPublicKey:userHexEncodedPublicKey displayName:displayName body:message.body type:LKGroupChatAPI.publicChatMessageType timestamp:message.timestamp];
|
||||
[[LKGroupChatAPI sendMessage:groupMessage toGroup:LKGroupChatAPI.publicChatID onServer:LKGroupChatAPI.publicChatServer]
|
||||
[[LKGroupChatAPI sendMessage:groupMessage toGroup:LKGroupChatAPI.publicChatServerID onServer:LKGroupChatAPI.publicChatServer]
|
||||
.thenOn(OWSDispatch.sendingQueue, ^(id result) {
|
||||
[self messageSendDidSucceed:messageSend deviceMessages:deviceMessages wasSentByUD:false wasSentByWebsocket:false];
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue