예제 #1
0
        public void displayAppRequests()
        {
            if (_webView == null)
            {
                return;
            }
            Utils.sendUiCommand(_webView, "clearAppRequests");
            var app_pages = Node.customAppManager.getAppPages();

            lock (app_pages)
            {
                foreach (CustomAppPage page in app_pages.Values)
                {
                    if (page.accepted)
                    {
                        continue;
                    }
                    Friend    f    = FriendList.getFriend(page.hostUserAddress);
                    CustomApp app  = Node.customAppManager.getApp(page.appId);
                    string    text = f.nickname + " wants to use " + app.name + " with you.";
                    Utils.sendUiCommand(_webView, "addAppRequest", Crypto.hashToString(page.sessionId), text);
                }
                if (VoIPManager.isInitiated() && !VoIPManager.currentCallAccepted)
                {
                    Friend f    = VoIPManager.currentCallContact;
                    string text = f.nickname + " is calling you.";
                    Utils.sendUiCommand(_webView, "addAppRequest", Crypto.hashToString(VoIPManager.currentCallSessionId), text);
                }
            }
        }
예제 #2
0
 public void onAppReject(string session_id)
 {
     byte[] b_session_id = Crypto.stringToHash(session_id);
     if (VoIPManager.hasSession(b_session_id))
     {
         VoIPManager.rejectCall(b_session_id);
         return;
     }
     Node.customAppManager.rejectAppRequest(b_session_id);
 }
예제 #3
0
 public void OnAudioFocusChange(AudioFocus focus_change)
 {
     switch (focus_change)
     {
     case AudioFocus.Loss:
         // Permanent loss of audio focus
         // Pause playback immediately
         VoIPManager.hangupCall(null, true);
         break;
     }
 }
예제 #4
0
        public void onAppAccept(string session_id)
        {
            byte[] b_session_id = Crypto.stringToHash(session_id);
            if (VoIPManager.hasSession(b_session_id))
            {
                VoIPManager.acceptCall(b_session_id);
                return;
            }
            CustomAppPage app_page = Node.customAppManager.acceptAppRequest(b_session_id);

            if (app_page != null)
            {
                Navigation.PushAsync(app_page, Config.defaultXamarinAnimations);
            }// TODO else error?
        }
예제 #5
0
        public void displayAppRequests()
        {
            if (_webView == null)
            {
                return;
            }
            Utils.sendUiCommand(_webView, "clearAppRequests");
            var app_pages = Node.customAppManager.getAppPages();

            lock (app_pages)
            {
                foreach (CustomAppPage page in app_pages.Values)
                {
                    if (page.accepted)
                    {
                        continue;
                    }
                    Friend    f    = FriendList.getFriend(page.hostUserAddress);
                    CustomApp app  = Node.customAppManager.getApp(page.appId);
                    string    text = string.Format(SpixiLocalization._SL("global-app-wants-to-use"), f.nickname, app.name);
                    Utils.sendUiCommand(_webView, "addAppRequest", Crypto.hashToString(page.sessionId), text, SpixiLocalization._SL("global-app-accept"), SpixiLocalization._SL("global-app-reject"));
                }
                if (VoIPManager.isInitiated())
                {
                    if (VoIPManager.currentCallAccepted)
                    {
                        if (VoIPManager.currentCallCalleeAccepted)
                        {
                            displayCallBar(VoIPManager.currentCallSessionId, SpixiLocalization._SL("global-call-in-call") + " - " + VoIPManager.currentCallContact.nickname, VoIPManager.currentCallStartedTime);
                        }
                        else
                        {
                            displayCallBar(VoIPManager.currentCallSessionId, SpixiLocalization._SL("global-call-dialing") + " " + VoIPManager.currentCallContact.nickname + "...", 0);
                        }
                    }
                    else
                    {
                        Friend f           = VoIPManager.currentCallContact;
                        string text        = SpixiLocalization._SL("global-call-incoming") + " - " + f.nickname;
                        string accept_html = "<div style='background:#2fd63b;border-radius:16px;width:64px;height:64px;display:table-cell;vertical-align:middle;text-align:center;'><i class='fas fa-phone'></i></div>";
                        string reject_html = "<div style='background:#de0a61;border-radius:16px;width:64px;height:64px;display:table-cell;vertical-align:middle;text-align:center;'><i class='fas fa-phone-slash'></i></div>";
                        Utils.sendUiCommand(_webView, "addAppRequest", Crypto.hashToString(VoIPManager.currentCallSessionId), text, accept_html, reject_html);
                    }
                }
            }
        }
예제 #6
0
 protected bool onNavigatingGlobal(string url)
 {
     if (url.StartsWith("ixian:appAccept:"))
     {
         string session_id = url.Substring("ixian:appAccept:".Length);
         onAppAccept(session_id);
     }
     else if (url.StartsWith("ixian:appReject:"))
     {
         string session_id = url.Substring("ixian:appReject:".Length);
         onAppReject(session_id);
     }
     else if (url.StartsWith("ixian:hangUp:"))
     {
         string session_id = url.Substring("ixian:hangUp:".Length);
         VoIPManager.hangupCall(Crypto.stringToHash(session_id));
     }
     else
     {
         return(false);
     }
     return(true);
 }
예제 #7
0
 void onVolumeChanged(NSNotification notification)
 {
     VoIPManager.setVolume(AVAudioSession.SharedInstance().OutputVolume);
 }
예제 #8
0
        private void onNavigating(object sender, WebNavigatingEventArgs e)
        {
            string current_url = HttpUtility.UrlDecode(e.Url);

            if (current_url.Equals("ixian:onload", StringComparison.Ordinal))
            {
                onLoaded();
            }
            else if (current_url.Equals("ixian:wallet", StringComparison.Ordinal))
            {
                // Deprecated
            }
            else if (current_url.Equals("ixian:quickscan", StringComparison.Ordinal))
            {
                ICustomQRScanner scanner = DependencyService.Get <ICustomQRScanner>();
                if (scanner != null && scanner.useCustomQRScanner())
                {
                    Logging.error("Custom scanner not implemented");
                    e.Cancel = true;
                    return;
                }
                quickScan();
            }
            else if (current_url.Contains("ixian:qrresult:"))
            {
                string[] split  = current_url.Split(new string[] { "ixian:qrresult:" }, StringSplitOptions.None);
                string   result = split[1];
                processQRResult(result);
                e.Cancel = true;
                return;
            }
            else if (current_url.Equals("ixian:newchat", StringComparison.Ordinal))
            {
                newChat();
            }
            else if (current_url.Equals("ixian:test", StringComparison.Ordinal))
            {
                displaySpixiAlert("Test", current_url, "Ok");
            }
            else if (current_url.Equals("ixian:newcontact", StringComparison.Ordinal))
            {
                Navigation.PushAsync(new ContactNewPage(), Config.defaultXamarinAnimations);
            }
            else if (current_url.Equals("ixian:sendixi", StringComparison.Ordinal))
            {
                Navigation.PushAsync(new WalletSendPage(), Config.defaultXamarinAnimations);
            }
            else if (current_url.Equals("ixian:receiveixi", StringComparison.Ordinal))
            {
                Navigation.PushAsync(new WalletReceivePage(), Config.defaultXamarinAnimations);
            }
            else if (current_url.Equals("ixian:avatar", StringComparison.Ordinal))
            {
                //onChangeAvatarAsync(sender, e);
            }
            else if (current_url.Equals("ixian:settings", StringComparison.Ordinal))
            {
                onSettings(sender, e);
            }
            else if (current_url.Equals("ixian:address", StringComparison.Ordinal))
            {
                Navigation.PushAsync(new MyAddressPage(), Config.defaultXamarinAnimations);
            }
            else if (current_url.Equals("ixian:lock", StringComparison.Ordinal))
            {
                //   prepBackground();
                Navigation.PushAsync(new SetLockPage(), Config.defaultXamarinAnimations);
            }
            else if (current_url.Equals("ixian:activity", StringComparison.Ordinal))
            {
                // TODO show wallet activity screen
            }
            else if (current_url.Equals("ixian:about", StringComparison.Ordinal))
            {
#pragma warning disable CS0618 // Type or member is obsolete
                Device.OpenUri(new Uri(Config.aboutUrl));
#pragma warning restore CS0618 // Type or member is obsolete
            }
            else if (current_url.Equals("ixian:backup", StringComparison.Ordinal))
            {
                Navigation.PushAsync(new BackupPage(), Config.defaultXamarinAnimations);
            }
            else if (current_url.Equals("ixian:encpass", StringComparison.Ordinal))
            {
                Navigation.PushAsync(new EncryptionPassword(), Config.defaultXamarinAnimations);
            }
            else if (current_url.Contains("ixian:chat:"))
            {
                string[] split = current_url.Split(new string[] { "ixian:chat:" }, StringSplitOptions.None);
                string   id    = split[1];
                onChat(id, e);
            }
            else if (current_url.Contains("ixian:details:"))
            {
                string[] split = current_url.Split(new string[] { "ixian:details:" }, StringSplitOptions.None);
                string   id    = split[1];
                // TODO: handle exceptions
                byte[] id_bytes = Base58Check.Base58CheckEncoding.DecodePlain(id);

                Friend friend = FriendList.getFriend(id_bytes);

                if (friend == null)
                {
                    e.Cancel = true;
                    return;
                }

                Navigation.PushAsync(new ContactDetails(friend), Config.defaultXamarinAnimations);
            }
            else if (current_url.Contains("ixian:txdetails:"))
            {
                string[] split = current_url.Split(new string[] { "ixian:txdetails:" }, StringSplitOptions.None);
                string   id    = split[1];

                Transaction transaction = null;
                foreach (Transaction tx in TransactionCache.transactions)
                {
                    if (tx.id.Equals(id, StringComparison.Ordinal))
                    {
                        transaction = tx;
                        break;
                    }
                }

                if (transaction == null)
                {
                    foreach (Transaction tx in TransactionCache.unconfirmedTransactions)
                    {
                        if (tx.id.Equals(id, StringComparison.Ordinal))
                        {
                            transaction = tx;
                            break;
                        }
                    }

                    if (transaction == null)
                    {
                        e.Cancel = true;
                        return;
                    }
                }

                Navigation.PushAsync(new WalletSentPage(transaction), Config.defaultXamarinAnimations);
            }
            else if (current_url.Contains("ixian:tab:"))
            {
                currentTab = current_url.Split(new string[] { "ixian:tab:" }, StringSplitOptions.None)[1];
            }
            else if (current_url.Equals("ixian:apps", StringComparison.Ordinal))
            {
                //   prepBackground();
                Navigation.PushAsync(new AppsPage(), Config.defaultXamarinAnimations);
            }
            else if (current_url.Equals("ixian:downloads", StringComparison.Ordinal))
            {
                //   prepBackground();
                Navigation.PushAsync(new DownloadsPage(), Config.defaultXamarinAnimations);
            }
            else if (current_url.StartsWith("ixian:appAccept:"))
            {
                string session_id = current_url.Substring("ixian:appAccept:".Length);
                onAppAccept(session_id);
            }
            else if (current_url.StartsWith("ixian:appReject:"))
            {
                string session_id = current_url.Substring("ixian:appReject:".Length);
                onAppReject(session_id);
            }
            else if (current_url.StartsWith("ixian:hangUp:"))
            {
                string session_id = current_url.Substring("ixian:hangUp:".Length);
                VoIPManager.hangupCall(Crypto.stringToHash(session_id));
            }
            else if (current_url.StartsWith("ixian:viewLog"))
            {
                if (File.Exists(Path.Combine(Config.spixiUserFolder, "spixi.log.zip")))
                {
                    File.Delete(Path.Combine(Config.spixiUserFolder, "spixi.log.zip"));
                }
                using (ZipArchive archive = ZipFile.Open(Path.Combine(Config.spixiUserFolder, "spixi.log.zip"), ZipArchiveMode.Create))
                {
                    archive.CreateEntryFromFile(Path.Combine(Config.spixiUserFolder, "ixian.log"), "ixian.log");
                }
                DependencyService.Get <IFileOperations>().share(Path.Combine(Config.spixiUserFolder, "spixi.log.zip"), "Share Spixi Log File");
            }
            else
            {
                // Otherwise it's just normal navigation
                e.Cancel = false;
                return;
            }
            e.Cancel = true;
        }
예제 #9
0
        private void onNavigating(object sender, WebNavigatingEventArgs e)
        {
            string current_url = HttpUtility.UrlDecode(e.Url);

            e.Cancel = true;

            if (current_url.Equals("ixian:onload", StringComparison.Ordinal))
            {
                onLoad();
            }
            else if (current_url.Equals("ixian:back", StringComparison.Ordinal))
            {
                friend.chat_page = null;

                Navigation.PopAsync(Config.defaultXamarinAnimations);
            }
            else if (current_url.Equals("ixian:request", StringComparison.Ordinal))
            {
                Navigation.PushAsync(new WalletReceivePage(friend), Config.defaultXamarinAnimations);
            }
            else if (current_url.Equals("ixian:details", StringComparison.Ordinal))
            {
                Navigation.PushAsync(new ContactDetails(friend, true), Config.defaultXamarinAnimations);
            }
            else if (current_url.Equals("ixian:send", StringComparison.Ordinal))
            {
                Navigation.PushAsync(new WalletSendPage(friend.walletAddress), Config.defaultXamarinAnimations);
            }
            else if (current_url.Equals("ixian:accept", StringComparison.Ordinal))
            {
                onAcceptFriendRequest();
            }
            else if (current_url.Equals("ixian:call", StringComparison.Ordinal))
            {
                if (VoIPManager.isInitiated())
                {
                    VoIPManager.hangupCall(null);
                }
                else
                {
                    VoIPManager.initiateCall(friend);
                }
            }
            else if (current_url.Equals("ixian:sendfile", StringComparison.Ordinal))
            {
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                onSendFile();
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            }
            else if (current_url.Contains("ixian:acceptfile:"))
            {
                string id = current_url.Substring("ixian:acceptfile:".Length);

                FriendMessage fm = friend.messages.Find(x => x.transferId == id);
                if (fm != null)
                {
                    onAcceptFile(fm);
                }
                else
                {
                    Logging.error("Cannot find message with transfer id: {0}", id);
                }
            }
            else if (current_url.Contains("ixian:openfile:"))
            {
                string id = current_url.Substring("ixian:openfile:".Length);

                FriendMessage fm = friend.messages.Find(x => x.transferId == id);

                // Open file in default app. May not work, check https://forums.xamarin.com/discussion/103042/how-to-open-pdf-or-txt-file-in-default-app-on-xamarin-forms
                //Device.OpenUri(new Uri(transfer.filePath));
                if (File.Exists(fm.filePath))
                {
                    DependencyService.Get <IFileOperations>().open(fm.filePath);
                }
            }
            else if (current_url.Contains("ixian:chat:"))
            {
                string msg = current_url.Substring("ixian:chat:".Length);
                onSend(msg);
            }
            else if (current_url.Contains("ixian:viewPayment:"))
            {
                string tx_id = current_url.Substring("ixian:viewPayment:".Length);
                onViewPayment(tx_id);
            }
            else if (current_url.Contains("ixian:app:"))
            {
                string app_id = current_url.Substring("ixian:app:".Length);
                onApp(app_id);
            }
            else if (current_url.StartsWith("ixian:appAccept:"))
            {
                string session_id = current_url.Substring("ixian:appAccept:".Length);
                onAppAccept(session_id);
            }
            else if (current_url.StartsWith("ixian:appReject:"))
            {
                string session_id = current_url.Substring("ixian:appReject:".Length);
                onAppReject(session_id);
            }
            else if (current_url.StartsWith("ixian:hangUp:"))
            {
                string session_id = current_url.Substring("ixian:hangUp:".Length);
                VoIPManager.hangupCall(Crypto.stringToHash(session_id));
            }
            else
            {
                // Otherwise it's just normal navigation
                e.Cancel = false;
                return;
            }
            e.Cancel = true;
        }
예제 #10
0
        public void insertMessage(FriendMessage message)
        {
            if (friend.approved == false)
            {
                if (message.type == FriendMessageType.requestAdd)
                {
                    // Call webview methods on the main UI thread only
                    Utils.sendUiCommand(webView, "showContactRequest", "1");
                    if (!message.read)
                    {
                        message.read = true;
                        Node.localStorage.writeMessages(friend.walletAddress, friend.messages);
                    }
                    return;
                }
            }
            else
            {
                // Don't show if the friend is already approved
                if (message.type == FriendMessageType.requestAdd)
                {
                    return;
                }
            }

            string prefix  = "addMe";
            string avatar  = "";
            string address = "";
            string nick    = "";

            if (!message.localSender)
            {
                if (friend.bot)
                {
                    if (message.senderAddress != null)
                    {
                        address = Base58Check.Base58CheckEncoding.EncodePlain(message.senderAddress);
                    }

                    nick = message.senderNick;
                    if (nick == "")
                    {
                        if (message.senderAddress != null && friend.contacts.ContainsKey(message.senderAddress))
                        {
                            nick = friend.contacts[message.senderAddress].nick;
                        }
                    }

                    if (nick == "")
                    {
                        nick = address;
                    }
                }

                prefix = "addThem";
                if (message.senderAddress != null)
                {
                    avatar = Node.localStorage.getAvatarPath(Base58Check.Base58CheckEncoding.EncodePlain(message.senderAddress));
                }
                else
                {
                    avatar = Node.localStorage.getAvatarPath(Base58Check.Base58CheckEncoding.EncodePlain(friend.walletAddress));
                }
                if (avatar == null)
                {
                    avatar = "img/spixiavatar.png";
                }
            }

            if (message.type == FriendMessageType.requestFunds)
            {
                string status      = "WAITING CONFIRMATION";
                string status_icon = "fa-clock";

                string amount = message.message;

                string txid = "";

                bool enableView = false;

                if (!message.localSender)
                {
                    enableView = true;
                }

                if (message.message.StartsWith("::"))
                {
                    status      = "DECLINED";
                    status_icon = "fa-exclamation-circle";
                    amount      = message.message.Substring(2);
                    txid        = Crypto.hashToString(message.id);
                    enableView  = false;
                }
                else if (message.message.StartsWith(":"))
                {
                    status = "PENDING";
                    txid   = message.message.Substring(1);

                    bool        confirmed   = true;
                    Transaction transaction = TransactionCache.getTransaction(txid);
                    if (transaction == null)
                    {
                        transaction = TransactionCache.getUnconfirmedTransaction(txid);
                        confirmed   = false;
                    }

                    amount = "?";

                    if (transaction != null)
                    {
                        amount = transaction.amount.ToString();

                        if (confirmed)
                        {
                            status      = "CONFIRMED";
                            status_icon = "fa-check-circle";
                        }
                    }
                    else
                    {
                        // TODO think about how to make this more private
                        CoreProtocolMessage.broadcastGetTransaction(txid, 0, null);
                    }
                    enableView = true;
                }


                if (message.localSender)
                {
                    Utils.sendUiCommand(webView, "addPaymentRequest", Crypto.hashToString(message.id), txid, address, nick, avatar, "Payment request SENT", amount, status, status_icon, message.timestamp.ToString(), message.localSender.ToString(), message.confirmed.ToString(), message.read.ToString(), enableView.ToString());
                }
                else
                {
                    Utils.sendUiCommand(webView, "addPaymentRequest", Crypto.hashToString(message.id), txid, address, nick, avatar, "Payment request RECEIVED", amount, status, status_icon, message.timestamp.ToString(), "", message.confirmed.ToString(), message.read.ToString(), enableView.ToString());
                }
            }

            if (message.type == FriendMessageType.sentFunds)
            {
                bool        confirmed   = true;
                Transaction transaction = TransactionCache.getTransaction(message.message);
                if (transaction == null)
                {
                    transaction = TransactionCache.getUnconfirmedTransaction(message.message);
                    confirmed   = false;
                }

                string status      = "PENDING";
                string status_icon = "fa-clock";

                string amount = "?";

                if (transaction != null)
                {
                    if (confirmed)
                    {
                        status      = "CONFIRMED";
                        status_icon = "fa-check-circle";
                    }
                    if (message.localSender)
                    {
                        amount = transaction.amount.ToString();
                    }
                    else
                    {
                        amount = HomePage.calculateReceivedAmount(transaction).ToString();
                    }
                }
                else
                {
                    // TODO think about how to make this more private
                    CoreProtocolMessage.broadcastGetTransaction(message.message, 0, null);
                }

                // Call webview methods on the main UI thread only
                if (message.localSender)
                {
                    Utils.sendUiCommand(webView, "addPaymentRequest", Crypto.hashToString(message.id), message.message, address, nick, avatar, "Payment SENT", amount, status, status_icon, message.timestamp.ToString(), message.localSender.ToString(), message.confirmed.ToString(), message.read.ToString(), "True");
                }
                else
                {
                    Utils.sendUiCommand(webView, "addPaymentRequest", Crypto.hashToString(message.id), message.message, address, nick, avatar, "Payment RECEIVED", amount, status, status_icon, message.timestamp.ToString(), "", message.confirmed.ToString(), message.read.ToString(), "True");
                }
            }


            if (message.type == FriendMessageType.fileHeader)
            {
                string[] split = message.message.Split(new string[] { ":" }, StringSplitOptions.None);
                if (split != null && split.Length > 1)
                {
                    string uid  = split[0];
                    string name = split[1];

                    string progress = "0";
                    if (message.completed)
                    {
                        progress = "100";
                    }
                    Utils.sendUiCommand(webView, "addFile", Crypto.hashToString(message.id), address, nick, avatar, uid, name, message.timestamp.ToString(), message.localSender.ToString(), message.confirmed.ToString(), message.read.ToString(), progress, message.completed.ToString());
                }
            }

            if (message.type == FriendMessageType.standard)
            {
                // Normal chat message
                // Call webview methods on the main UI thread only
                Utils.sendUiCommand(webView, prefix, Crypto.hashToString(message.id), address, nick, avatar, message.message, message.timestamp.ToString(), message.confirmed.ToString(), message.read.ToString());
            }

            if (message.type == FriendMessageType.voiceCall || message.type == FriendMessageType.voiceCallEnd)
            {
                string text;
                if (message.localSender)
                {
                    text = "Outgoing call";
                }
                else
                {
                    text = "Incoming call";
                }
                bool declined = false;
                if (message.message == "")
                {
                    if (message.type == FriendMessageType.voiceCallEnd || !VoIPManager.hasSession(message.id))
                    {
                        declined = true;
                        if (message.localSender)
                        {
                            text = "No answer";
                        }
                        else
                        {
                            text = "Missed call";
                        }
                    }
                }
                else if (message.type == FriendMessageType.voiceCallEnd)
                {
                    long seconds = Int32.Parse(message.message);
                    long minutes = seconds / 60;
                    seconds = seconds % 60;
                    text    = text + string.Format(" ended ({0}:{1})", minutes, seconds < 10 ? "0" + seconds : seconds.ToString());
                }
                Utils.sendUiCommand(webView, "addCall", Crypto.hashToString(message.id), text, declined.ToString(), message.timestamp.ToString());
            }

            updateMessageReadStatus(message);
        }