Merge with siskin@7411133
This commit is contained in:
commit
d566ab6cfe
|
@ -167,6 +167,7 @@ public class Payload: Decodable {
|
|||
public var nickname: String?;
|
||||
public var message: String?;
|
||||
public var sid: String?;
|
||||
public var media: [String]?;
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self);
|
||||
|
@ -176,6 +177,7 @@ public class Payload: Decodable {
|
|||
nickname = try container.decodeIfPresent(String.self, forKey: .nickname);
|
||||
message = try container.decodeIfPresent(String.self, forKey: .message);
|
||||
sid = try container.decodeIfPresent(String.self, forKey: .sid)
|
||||
media = try container.decodeIfPresent([String].self, forKey: .media);
|
||||
// -- and so on...
|
||||
}
|
||||
|
||||
|
@ -193,5 +195,6 @@ public class Payload: Decodable {
|
|||
case nickname
|
||||
case message
|
||||
case sid
|
||||
case media
|
||||
}
|
||||
}
|
||||
|
|
|
@ -512,7 +512,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||
print("got decrypted data:", String(data: decoded, encoding: .utf8) as Any);
|
||||
if let payload = try? JSONDecoder().decode(Payload.self, from: decoded) {
|
||||
print("decoded payload successfully!");
|
||||
if let sid = payload.sid {
|
||||
// we require `media` to be present (even empty) in incoming push for jingle session initiation,
|
||||
// so we can assume that if `media` is `nil` then this is a push for call termination
|
||||
if let sid = payload.sid, payload.media == nil {
|
||||
guard CallManager.isAvailable, CallManager.instance?.currentCall?.state ?? .ringing == .ringing else {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -193,7 +193,7 @@
|
|||
<!--Navigation Controller-->
|
||||
<scene sceneID="CJK-x4-axt">
|
||||
<objects>
|
||||
<navigationController storyboardIdentifier="RoomViewNavigationController" automaticallyAdjustsScrollViewInsets="NO" toolbarHidden="NO" id="Q49-7n-7nT" sceneMemberID="viewController">
|
||||
<navigationController storyboardIdentifier="RoomViewNavigationController" automaticallyAdjustsScrollViewInsets="NO" id="Q49-7n-7nT" sceneMemberID="viewController">
|
||||
<toolbarItems/>
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" translucent="NO" id="C6i-6F-QcS">
|
||||
<rect key="frame" x="0.0" y="44" width="414" height="44"/>
|
||||
|
@ -206,7 +206,6 @@
|
|||
</navigationBar>
|
||||
<nil name="viewControllers"/>
|
||||
<toolbar key="toolbar" opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="g7C-gM-aQF">
|
||||
<rect key="frame" x="0.0" y="813" width="414" height="49"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</toolbar>
|
||||
<connections>
|
||||
|
|
|
@ -1054,8 +1054,8 @@
|
|||
</scene>
|
||||
</scenes>
|
||||
<inferredMetricsTieBreakers>
|
||||
<segue reference="xZo-9l-Nez"/>
|
||||
<segue reference="IbT-RI-igU"/>
|
||||
<segue reference="XRy-yU-VZ5"/>
|
||||
<segue reference="j5J-Tn-QfR"/>
|
||||
</inferredMetricsTieBreakers>
|
||||
<resources>
|
||||
<image name="defaultAvatar" width="100" height="100"/>
|
||||
|
@ -1071,9 +1071,6 @@
|
|||
<systemColor name="groupTableViewBackgroundColor">
|
||||
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="groupTableViewBackgroundColor">
|
||||
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="secondaryLabelColor">
|
||||
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
|
|
|
@ -43,7 +43,11 @@ class ChannelCreateViewController: UITableViewController, ChannelSelectAccountAn
|
|||
}
|
||||
var kind: ChannelKind = .adhoc;
|
||||
|
||||
private var components: [ChannelsHelper.Component] = [];
|
||||
private var components: [ChannelsHelper.Component] = [] {
|
||||
didSet {
|
||||
updateJoinButtonStatus();
|
||||
}
|
||||
}
|
||||
private var invitationOnly: Bool = true;
|
||||
private var useMix: Bool = false;
|
||||
private var needRefresh = false;
|
||||
|
@ -129,6 +133,7 @@ class ChannelCreateViewController: UITableViewController, ChannelSelectAccountAn
|
|||
|
||||
@objc func mixSwitchChanged(_ sender: UISwitch) {
|
||||
useMix = sender.isOn;
|
||||
updateJoinButtonStatus();
|
||||
}
|
||||
|
||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
|
@ -169,9 +174,13 @@ class ChannelCreateViewController: UITableViewController, ChannelSelectAccountAn
|
|||
}
|
||||
|
||||
@IBAction func textFieldChanged(_ sender: Any) {
|
||||
updateJoinButtonStatus();
|
||||
}
|
||||
|
||||
private func updateJoinButtonStatus() {
|
||||
let name = self.channelNameField.text?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "";
|
||||
let channelId = self.channelIdField.text?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "";
|
||||
self.joinButton.isEnabled = (!name.isEmpty) && (kind == .adhoc || !channelId.isEmpty);
|
||||
self.joinButton.isEnabled = (!name.isEmpty) && (kind == .adhoc || !channelId.isEmpty) && self.components.contains(where: { $0.type == (useMix ? .mix : .muc) });
|
||||
}
|
||||
|
||||
private func refresh() {
|
||||
|
@ -193,6 +202,7 @@ class ChannelCreateViewController: UITableViewController, ChannelSelectAccountAn
|
|||
}
|
||||
}
|
||||
self.tableView.reloadData();
|
||||
self.updateJoinButtonStatus();
|
||||
self.operationEnded();
|
||||
}
|
||||
})
|
||||
|
|
|
@ -142,7 +142,10 @@ class DataFormController: UITableViewController {
|
|||
if errors.firstIndex(where: { (idx)->Bool in
|
||||
return idx.row == indexPath.row && idx.section == indexPath.section
|
||||
}) != nil {
|
||||
let backgroundColor = cell.backgroundColor;
|
||||
var backgroundColor = UIColor.white;
|
||||
if #available(iOS 13.0, *) {
|
||||
backgroundColor = UIColor.systemBackground;
|
||||
}
|
||||
UIView.animate(withDuration: 0.5, animations: {
|
||||
//cell.backgroundColor = UIColor(red: 1.0, green: 0.5, blue: 0.5, alpha: 1);
|
||||
cell.backgroundColor = UIColor(hue: 0, saturation: 0.7, brightness: 0.8, alpha: 1)
|
||||
|
@ -163,7 +166,7 @@ class DataFormController: UITableViewController {
|
|||
for (index, fieldName) in form!.visibleFieldNames.enumerated() {
|
||||
if let field = form!.getField(named: fieldName)! as? ValidatableField {
|
||||
if !field.valid {
|
||||
errors.append(IndexPath(row: index, section: 0));
|
||||
errors.append(IndexPath(row: 0, section: index + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,14 @@
|
|||
|
||||
import UIKit
|
||||
|
||||
extension unichar: ExpressibleByUnicodeScalarLiteral {
|
||||
public typealias UnicodeScalarLiteralType = UnicodeScalar
|
||||
|
||||
public init(unicodeScalarLiteral value: UnicodeScalar) {
|
||||
self.init(value.value);
|
||||
}
|
||||
}
|
||||
|
||||
class Markdown {
|
||||
|
||||
static let quoteParagraphStyle: NSParagraphStyle = {
|
||||
|
@ -68,56 +76,63 @@ class Markdown {
|
|||
}
|
||||
}
|
||||
|
||||
static let NEW_LINE: unichar = "\n";
|
||||
static let GT_SIGN: unichar = ">";
|
||||
static let SPACE: unichar = " ";
|
||||
static let ASTERISK: unichar = "*";
|
||||
static let UNDERSCORE: unichar = "_";
|
||||
static let GRAVE_ACCENT: unichar = "`";
|
||||
static let CR_SIGN: unichar = "\r";
|
||||
|
||||
static func applyStyling(attributedString msg: NSMutableAttributedString, font defFont: UIFont, showEmoticons: Bool) {
|
||||
let stylingColor = UIColor.init(white: 0.5, alpha: 1.0);
|
||||
|
||||
var message = msg.string;
|
||||
var message = msg.string as NSString;
|
||||
|
||||
var boldStart: String.Index? = nil;
|
||||
var italicStart: String.Index? = nil;
|
||||
var underlineStart: String.Index? = nil;
|
||||
// var codeStart: String.Index? = nil;
|
||||
// var codeCount: Int = 0;
|
||||
var quoteStart: String.Index? = nil;
|
||||
var boldStart: Int? = nil;
|
||||
var italicStart: Int? = nil;
|
||||
var underlineStart: Int? = nil;
|
||||
var quoteStart: Int? = nil;
|
||||
var quoteLevel = 0;
|
||||
var idx = message.startIndex;
|
||||
var idx = 0;
|
||||
|
||||
var canStart = true;
|
||||
|
||||
var wordIdx: String.Index? = showEmoticons ? message.startIndex : nil;
|
||||
var wordIdx: Int? = showEmoticons ? 0 : nil;
|
||||
|
||||
msg.removeAttribute(.paragraphStyle, range: NSRange(location: 0, length: msg.length));
|
||||
msg.addAttribute(.font, value: defFont, range: NSRange(location: 0, length: msg.length));
|
||||
|
||||
while idx != message.endIndex {
|
||||
let c = message[idx];
|
||||
while idx < message.length {
|
||||
let c = message.character(at: idx);
|
||||
switch c {
|
||||
case ">":
|
||||
if quoteStart == nil && idx == message.startIndex || message[message.index(before: idx)] == "\n" {
|
||||
case GT_SIGN:
|
||||
if quoteStart == nil && (idx == 0 || message.character(at: idx-1) == NEW_LINE) {
|
||||
let start = idx;
|
||||
while idx != message.endIndex, message[idx] == ">" {
|
||||
idx = message.index(after: idx);
|
||||
while idx < message.length, message.character(at: idx) == GT_SIGN {
|
||||
idx = idx + 1;
|
||||
}
|
||||
if idx != message.endIndex && message[idx] == " " {
|
||||
if idx < message.length && message.character(at: idx) == SPACE {
|
||||
quoteStart = start;
|
||||
quoteLevel = message.distance(from: start, to: idx)
|
||||
msg.addAttribute(.foregroundColor, value: stylingColor, range: NSRange(start..<idx, in: message));
|
||||
quoteLevel = idx - start;
|
||||
msg.addAttribute(.foregroundColor, value: stylingColor, range: NSRange(location: start, length: idx - start));
|
||||
} else {
|
||||
idx = message.index(before: idx);
|
||||
idx = idx - 1;
|
||||
}
|
||||
}
|
||||
case "*":
|
||||
let nidx = message.index(after: idx);
|
||||
if nidx != message.endIndex, message[nidx] == "*" {
|
||||
case ASTERISK:
|
||||
let nidx = idx + 1;
|
||||
if nidx < message.length, message.character(at: nidx) == ASTERISK {
|
||||
if boldStart == nil {
|
||||
if canStart {
|
||||
boldStart = idx;
|
||||
}
|
||||
} else {
|
||||
msg.addAttribute(.foregroundColor, value: stylingColor, range: NSRange(boldStart!...message.index(after: boldStart!), in: message));
|
||||
msg.addAttribute(.foregroundColor, value: stylingColor, range: NSRange(idx...nidx, in: message));
|
||||
msg.addAttribute(.foregroundColor, value: stylingColor, range: NSRange(location: boldStart!, length: (nidx+1) - idx));
|
||||
msg.addAttribute(.foregroundColor, value: stylingColor, range: NSRange(location: idx, length: (nidx+1) - idx));
|
||||
|
||||
msg.enumerateAttribute(.font, in: NSRange(boldStart!...nidx, in: message), options: .init()) { (attr, range: NSRange, stop) -> Void in
|
||||
|
||||
msg.enumerateAttribute(.font, in: NSRange(location: boldStart!, length: (nidx+1) - boldStart!), options: .init()) { (attr, range: NSRange, stop) -> Void in
|
||||
let font = attr as? UIFont;
|
||||
let boldFont = Markdown.bold(font: font ?? defFont);
|
||||
msg.addAttribute(.font, value: boldFont, range: range);
|
||||
|
@ -133,112 +148,120 @@ class Markdown {
|
|||
italicStart = idx;
|
||||
}
|
||||
} else {
|
||||
msg.addAttribute(.foregroundColor, value: stylingColor, range: NSRange(italicStart!...italicStart!, in: message));
|
||||
msg.addAttribute(.foregroundColor, value: stylingColor, range: NSRange(idx...idx, in: message));
|
||||
msg.addAttribute(.foregroundColor, value: stylingColor, range: NSRange(location: italicStart!, length: 1));
|
||||
msg.addAttribute(.foregroundColor, value: stylingColor, range: NSRange(location: idx, length: 1));
|
||||
|
||||
msg.enumerateAttribute(.font, in: NSRange(italicStart!...idx, in: message), options: .init()) { (attr, range: NSRange, stop) -> Void in
|
||||
msg.enumerateAttribute(.font, in: NSRange(location: italicStart!, length: (idx+1) - italicStart!), options: .init()) { (attr, range: NSRange, stop) -> Void in
|
||||
let font = attr as? UIFont;
|
||||
let italicFont = Markdown.italic(font: font ?? defFont);
|
||||
msg.addAttribute(.font, value: italicFont, range: range);
|
||||
}
|
||||
|
||||
italicStart = nil;
|
||||
}
|
||||
canStart = true;
|
||||
}
|
||||
case "_":
|
||||
case UNDERSCORE:
|
||||
if underlineStart == nil {
|
||||
if canStart {
|
||||
underlineStart = idx;
|
||||
}
|
||||
} else {
|
||||
msg.addAttribute(.foregroundColor, value: stylingColor, range: NSRange(underlineStart!...underlineStart!, in: message));
|
||||
msg.addAttribute(.foregroundColor, value: stylingColor, range: NSRange(idx...idx, in: message));
|
||||
msg.addAttribute(.foregroundColor, value: stylingColor, range: NSRange(location: underlineStart!, length: 1));
|
||||
msg.addAttribute(.foregroundColor, value: stylingColor, range: NSRange(location: idx, length: 1));
|
||||
|
||||
msg.addAttribute(.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: NSRange(underlineStart!...idx, in: message));
|
||||
msg.addAttribute(.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: NSRange(location: underlineStart!, length: idx - underlineStart!));
|
||||
underlineStart = nil;
|
||||
}
|
||||
canStart = true;
|
||||
case "`":
|
||||
case GRAVE_ACCENT:
|
||||
// if codeStart == nil {
|
||||
if canStart {
|
||||
let codeStart = idx;
|
||||
let isBlock = message.startIndex == idx || (message[message.index(before: idx)] == "\n") || (message.distance(from: message.startIndex, to: idx) > 3 && message[message.index(idx, offsetBy: -1)] == " " && message[message.index(idx, offsetBy: -2)] == ">" && (message.startIndex == message.index(idx, offsetBy: -3) || message[message.index(idx, offsetBy: -3)] == "\n"));
|
||||
wordIdx = nil;
|
||||
while idx != message.endIndex, message[idx] == "`" {
|
||||
idx = message.index(after: idx);
|
||||
}
|
||||
let codeCount = message.distance(from: codeStart, to: idx);
|
||||
print("code tag count = ", codeCount);
|
||||
|
||||
var count = 0;
|
||||
while idx != message.endIndex {
|
||||
if message[idx] == "`" {
|
||||
count = count + 1;
|
||||
if count == codeCount {
|
||||
let tmp = message.index(after: idx);
|
||||
if tmp == message.endIndex || [" ", "\n"].contains(message[tmp]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
count = 0;
|
||||
}
|
||||
idx = message.index(after: idx);
|
||||
}
|
||||
if codeCount != count {
|
||||
idx = message.index(before: idx);
|
||||
} else {
|
||||
msg.addAttribute(.foregroundColor, value: stylingColor, range: NSRange(codeStart...message.index(codeStart, offsetBy: codeCount-1), in: message));
|
||||
msg.addAttribute(.foregroundColor, value: stylingColor, range: NSRange(message.index(idx, offsetBy: codeCount * -1)...idx, in: message));
|
||||
|
||||
|
||||
let codeFont = Markdown.code(font: defFont);
|
||||
msg.addAttribute(.font, value: codeFont, range: NSRange(codeStart...idx, in: message));
|
||||
|
||||
if isBlock {
|
||||
msg.addAttribute(.paragraphStyle, value: codeParagraphStyle, range: NSRange(codeStart...idx, in: message));
|
||||
if canStart {
|
||||
let codeStart = idx;
|
||||
let isBlock = 0 == idx || (message.character(at: idx-1) == NEW_LINE) || (idx > 3 && message.length > (idx + 1) && message.character(at: idx + 1) == SPACE && message.character(at: idx-2) == GT_SIGN && (0 == idx - 3 || message.character(at: idx - 3) == NEW_LINE));
|
||||
wordIdx = nil;
|
||||
while idx < message.length, message.character(at: idx) == "`" {
|
||||
idx = idx + 1;
|
||||
}
|
||||
|
||||
if message.distance(from: codeStart, to: idx) > 1 {
|
||||
let clearRange = NSRange(message.index(codeStart, offsetBy: codeCount)...message.index(idx, offsetBy: codeCount * -1), in: message);
|
||||
msg.removeAttribute(.underlineStyle, range: clearRange);
|
||||
//msg.addAttribute(.foregroundColor, value: textColor ?? NSColor.textColor, range: clearRange);
|
||||
let codeCount = idx - codeStart;
|
||||
print("code tag count = ", codeCount);
|
||||
|
||||
var count = 0;
|
||||
while idx < message.length {
|
||||
if message.character(at: idx) == GRAVE_ACCENT {
|
||||
count = count + 1;
|
||||
if count == codeCount {
|
||||
let tmp = idx + 1;
|
||||
if tmp == message.length || [" ", "\n"].contains(message.character(at: tmp)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
count = 0;
|
||||
}
|
||||
idx = idx + 1;
|
||||
}
|
||||
|
||||
if idx == message.endIndex {
|
||||
wordIdx = message.endIndex;
|
||||
if codeCount != count {
|
||||
idx = codeStart + codeCount;
|
||||
} else {
|
||||
wordIdx = message.index(after: idx);
|
||||
msg.addAttribute(.foregroundColor, value: stylingColor, range: NSRange(location: codeStart, length: codeCount));
|
||||
msg.addAttribute(.foregroundColor, value: stylingColor, range: NSRange(location: (idx+1)-codeCount, length: codeCount));
|
||||
|
||||
let codeFont = Markdown.code(font: defFont);
|
||||
msg.addAttribute(.font, value: codeFont, range: NSRange(location: codeStart, length: idx - codeStart));
|
||||
|
||||
if isBlock {
|
||||
msg.addAttribute(.paragraphStyle, value: codeParagraphStyle, range: NSRange(location: codeStart, length: idx - codeStart));
|
||||
}
|
||||
|
||||
if idx - codeStart > 1 {
|
||||
let clearRange = NSRange(location: codeStart + codeCount, length: idx - (codeStart + (2*codeCount)));
|
||||
//msg.removeAttribute(.foregroundColor, range: clearRange);
|
||||
msg.removeAttribute(.underlineStyle, range: clearRange);
|
||||
//msg.addAttribute(.foregroundColor, value: textColor ?? NSColor.textColor, range: clearRange);
|
||||
}
|
||||
|
||||
if idx == message.length {
|
||||
wordIdx = message.length;
|
||||
} else {
|
||||
wordIdx = idx + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// } else {
|
||||
// }
|
||||
canStart = true;
|
||||
case "\r", "\n", " ":
|
||||
case CR_SIGN, NEW_LINE, SPACE:
|
||||
if showEmoticons {
|
||||
if wordIdx != nil && wordIdx! != idx {
|
||||
// something is wrong, it looks like IDX points to replaced value!
|
||||
if let emoji = String.emojis[String(message[wordIdx!..<idx])] {
|
||||
msg.replaceCharacters(in: NSRange(wordIdx!..<idx, in: message), with: emoji);
|
||||
let distance = message.distance(from: message.startIndex, to: wordIdx!);
|
||||
message.replaceSubrange(wordIdx!..<idx, with: emoji);
|
||||
// we are changing offset as length is changing!!
|
||||
// idx = message.index(wordIdx!, offsetBy: emoji.lengthOfBytes(using: .utf8)-3);
|
||||
idx = message.index(after: message.index(message.startIndex, offsetBy: distance));
|
||||
let range = NSRange(location: wordIdx!, length: idx - wordIdx!);
|
||||
if let emoji = String.emojis[message.substring(with: range)] {
|
||||
let len = message.length;
|
||||
print("replacing:", range, "for:", emoji, "in:", msg, "range:", NSRange(location: 0, length: msg.length));
|
||||
msg.replaceCharacters(in: range, with: emoji);
|
||||
message = msg.string as NSString;
|
||||
let diff = message.length - len;
|
||||
idx = idx + diff;
|
||||
}
|
||||
}
|
||||
if idx != message.endIndex {
|
||||
wordIdx = message.index(after: idx);
|
||||
if idx < message.length {
|
||||
wordIdx = idx + 1;
|
||||
} else {
|
||||
wordIdx = message.endIndex;
|
||||
wordIdx = message.length;
|
||||
}
|
||||
}
|
||||
if "\n" == c {
|
||||
if NEW_LINE == c {
|
||||
boldStart = nil;
|
||||
underlineStart = nil;
|
||||
italicStart = nil
|
||||
if (quoteStart != nil) {
|
||||
|
||||
msg.addAttribute(.paragraphStyle, value: Markdown.quoteParagraphStyle, range: NSRange(quoteStart!..<idx, in: message));
|
||||
print("quote level:", quoteLevel);
|
||||
if idx < message.length {
|
||||
let range = NSRange(location: quoteStart!, length: idx - quoteStart!);
|
||||
print("message possibly causing a crash:", message, "range:", range, "length:", message.length);
|
||||
msg.addAttribute(.paragraphStyle, value: Markdown.quoteParagraphStyle, range: range);
|
||||
}
|
||||
quoteStart = nil;
|
||||
}
|
||||
}
|
||||
|
@ -247,20 +270,21 @@ class Markdown {
|
|||
canStart = false;
|
||||
break;
|
||||
}
|
||||
if idx != message.endIndex {
|
||||
idx = message.index(after: idx);
|
||||
if idx < message.length {
|
||||
idx = idx + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (quoteStart != nil) {
|
||||
msg.addAttribute(.paragraphStyle, value: Markdown.quoteParagraphStyle, range: NSRange(quoteStart!..<idx, in: message));
|
||||
msg.addAttribute(.paragraphStyle, value: Markdown.quoteParagraphStyle, range: NSRange(location: quoteStart!, length: idx - quoteStart!));
|
||||
quoteStart = nil;
|
||||
}
|
||||
|
||||
|
||||
if showEmoticons && wordIdx != nil && wordIdx! != idx {
|
||||
if let emoji = String.emojis[String(message[wordIdx!..<idx])] {
|
||||
msg.replaceCharacters(in: NSRange(wordIdx!..<idx, in: message), with: emoji);
|
||||
message.replaceSubrange(wordIdx!..<idx, with: emoji);
|
||||
let range = NSRange(location: wordIdx!, length: idx - wordIdx!);
|
||||
if let emoji = String.emojis[message.substring(with: range)] {
|
||||
msg.replaceCharacters(in: range, with: emoji);
|
||||
message = msg.string as NSString;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -918,18 +918,25 @@ extension CallManager: PKPushRegistryDelegate {
|
|||
print("got decrypted voip data:", String(data: decoded, encoding: .utf8) as Any);
|
||||
if let payload = try? JSONDecoder().decode(VoIPPayload.self, from: decoded) {
|
||||
print("decoded voip payload successfully!");
|
||||
if let sender = payload.sender, let media = payload.media, let client = XmppService.instance.getClient(for: BareJID(account)) {
|
||||
let session = JingleManager.instance.open(for: client.sessionObject, with: sender, sid: payload.sid, role: .responder, initiationType: .message);
|
||||
let call = Call(account: BareJID(account), with: sender.bareJid, sid: payload.sid, direction: .incoming, media: media, sessionId: session?.id);
|
||||
self.reportIncomingCall(call, completionHandler: { result in
|
||||
switch result {
|
||||
case .success(_):
|
||||
break;
|
||||
case .failure(_):
|
||||
_ = session?.decline();
|
||||
}
|
||||
completion();
|
||||
})
|
||||
if let sender = payload.sender, let client = XmppService.instance.getClient(for: BareJID(account)) {
|
||||
// we require `media` to be present (even empty) in incoming push for jingle session initiation
|
||||
if let media = payload.media {
|
||||
let session = JingleManager.instance.open(for: client.sessionObject, with: sender, sid: payload.sid, role: .responder, initiationType: .message);
|
||||
let call = Call(account: BareJID(account), with: sender.bareJid, sid: payload.sid, direction: .incoming, media: media, sessionId: session?.id);
|
||||
self.reportIncomingCall(call, completionHandler: { result in
|
||||
switch result {
|
||||
case .success(_):
|
||||
break;
|
||||
case .failure(_):
|
||||
_ = session?.decline();
|
||||
}
|
||||
completion();
|
||||
});
|
||||
} else {
|
||||
self.endCall(on: account, sid: payload.sid, completionHandler: {
|
||||
print("ended call");
|
||||
})
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue