Exemple #1
0
        protected override bool ShouldStartLoad(WKWebView webView, WKNavigationAction navigationAction)
        {
            try
            {
                //We're being redirected to our redirect URL so we must have been successful
                if (navigationAction.Request.Url.Host == "dillonbuchanan.com")
                {
                    var queryParameters = navigationAction.Request.Url.Query.Split('&');

                    var code      = queryParameters.FirstOrDefault(x => x.StartsWith("code=", StringComparison.OrdinalIgnoreCase));
                    var codeValue = code?.Replace("code=", String.Empty);
                    ViewModel.LoginCommand.ExecuteNow(codeValue);
                    return(false);
                }

                if (navigationAction.Request.Url.AbsoluteString.StartsWith("https://github.com/join"))
                {
                    _alertDialogService.Alert("Error", "Sorry, due to restrictions, creating GitHub accounts cannot be done in CodeHub.");
                    return(false);
                }

                return(base.ShouldStartLoad(webView, navigationAction));
            }
            catch
            {
                _alertDialogService.Alert("Error Logging in!", "CodeHub is unable to login you in due to an unexpected error. Please try again.");
                return(false);
            }
        }
        protected async Task Startup()
        {
            var accounts = (await _accountsService.GetAccounts()).ToList();

            if (!accounts.Any())
            {
                GoToLoginCommand.ExecuteNow();
                return;
            }

            var account = await _applicationService.GetDefaultAccount();

            if (account == null)
            {
                GoToAccountsCommand.ExecuteNow();
                return;
            }

            if (string.IsNullOrEmpty(account.Token) || string.IsNullOrEmpty(account.RefreshToken))
            {
                GoToLoginCommand.ExecuteNow();
                return;
            }

            try
            {
                IsLoggingIn = true;
                Status      = "Logging in as " + account.Username;

                var ret = await BitbucketClient.GetRefreshToken(
                    Secrets.ClientId, Secrets.ClientSecret, account.RefreshToken);

                if (ret == null)
                {
                    await _alertDialogService.Alert("Error!", "Unable to refresh OAuth token. Please login again.");

                    GoToLoginCommand.ExecuteNow();
                    return;
                }

                account.RefreshToken = ret.RefreshToken;
                account.Token        = ret.AccessToken;
                await _accountsService.Save(account);
                await AttemptLogin(account);

                GoToMenuCommand.ExecuteNow();
            }
            catch (Exception e)
            {
                _alertDialogService
                .Alert("Error!", "Unable to login successfully: " + e.Message)
                .ToObservable()
                .BindCommand(GoToAccountsCommand);
            }
            finally
            {
                IsLoggingIn = false;
            }
        }
Exemple #3
0
 private async Task Fork()
 {
     try
     {
         await this.DoWorkAsync("Forking...", ViewModel.ForkGist);
     }
     catch (Exception ex)
     {
         _alertDialogService.Alert("Error", ex.Message).ToBackground();
     }
 }
Exemple #4
0
        protected MarkdownComposerViewModel(IStatusIndicatorService status, IAlertDialogService alert, IJsonHttpClientService jsonClient)
        {
            var saveCommand = ReactiveCommand.CreateAsyncTask(
                this.WhenAnyValue(x => x.Text).Select(x => !string.IsNullOrEmpty(x)),
                t => Save());

            saveCommand.IsExecuting.Where(x => x).Subscribe(_ => status.Show("Saving..."));
            saveCommand.IsExecuting.Where(x => !x).Subscribe(_ => status.Hide());
            saveCommand.Subscribe(x => DismissCommand.ExecuteIfCan());
            SaveCommand = saveCommand;

            PostToImgurCommand =
                ReactiveCommand.CreateAsyncTask(async data =>
            {
                var uploadData = data as byte[];
                if (uploadData == null)
                {
                    throw new Exception("There is no data to upload!");
                }

                return(await jsonClient.Post <ImgurModel>("https://api.imgur.com/3/image",
                                                          new { image = Convert.ToBase64String(uploadData) },
                                                          new Dictionary <string, string> {
                    { "Authorization", "Client-ID " + AuthorizationClientId }
                }));
            });

            PostToImgurCommand.IsExecuting.Where(x => x).Subscribe(_ => status.Show("Uploading..."));
            PostToImgurCommand.IsExecuting.Where(x => !x).Subscribe(_ => status.Hide());
            PostToImgurCommand.ThrownExceptions.SubscribeSafe(e => alert.Alert("Error", "Unable to upload image: " + e.Message));
        }
        private void SelectImage()
        {
            var imagePicker = new RotatableUIImagePickerController();

            imagePicker.NavigationControllerDelegate = new ImagePickerDelegate();
            imagePicker.SourceType = UIImagePickerControllerSourceType.PhotoLibrary;
            imagePicker.MediaTypes = UIImagePickerController.AvailableMediaTypes(UIImagePickerControllerSourceType.PhotoLibrary);
            imagePicker.MediaTypes = imagePicker.MediaTypes.Where(x => !(x.Contains("movie") || x.Contains("video"))).ToArray();

            imagePicker.FinishedPickingMedia += (sender, e) =>
            {
                // determine what was selected, video or image
                bool isImage = false;
                switch (e.Info[UIImagePickerController.MediaType].ToString())
                {
                case "public.image":
                    isImage = true;
                    break;
                }

                // if it was an image, get the other image info
                if (isImage)
                {
                    // get the original image
                    UIImage originalImage = e.Info[UIImagePickerController.OriginalImage] as UIImage;
                    if (originalImage != null)
                    {
                        // do something with the image
                        try
                        { UploadImage(originalImage); }
                        catch
                        {
                        }
                    }
                }
                else
                { // if it's a video
                    _alertDialogService.Alert("Not supported!", "Video upload is currently not supported.");
                }

                // dismiss the picker
                imagePicker.DismissViewController(true, null);
                UIApplication.SharedApplication.StatusBarStyle = UIStatusBarStyle.LightContent;
            };


            imagePicker.Canceled += (sender, e) =>
            {
                imagePicker.DismissViewController(true, null);
                UIApplication.SharedApplication.StatusBarStyle = UIStatusBarStyle.LightContent;
            };

            NavigationController.PresentViewController(imagePicker, true, null);
        }
Exemple #6
0
        protected override void OnLoadError(object sender, UIWebErrorArgs e)
        {
            base.OnLoadError(sender, e);

            //Frame interrupted error
            if (e.Error.Code == 102)
            {
                return;
            }

            if (ViewModel.IsEnterprise)
            {
                var alert = _alertDialogService.Alert("Error", "Unable to communicate with GitHub with given Url. " + e.Error.LocalizedDescription);
                alert.ContinueWith(t => Stuff(), TaskContinuationOptions.OnlyOnRanToCompletion);
            }
            else
            {
                _alertDialogService.Alert("Error", "Unable to communicate with GitHub. " + e.Error.LocalizedDescription);
            }
        }
        private void LoadingError(Exception err)
        {
            var message       = err.Message;
            var baseException = err.GetInnerException();

            if (baseException is System.Net.Sockets.SocketException)
            {
                message = "Unable to communicate with GitHub. " + baseException.Message;
            }

            _dialogService.Alert("Error Loading", message).ToBackground();
        }
Exemple #8
0
        private async void UploadImage(UIImage img)
        {
            _statusIndicatorService.Show("Uploading...");

            try
            {
                var returnData = await Task.Run <byte[]>(() =>
                {
                    using (var w = new WebClient())
                    {
                        var data         = img.AsJPEG();
                        byte[] dataBytes = new byte[data.Length];
                        System.Runtime.InteropServices.Marshal.Copy(data.Bytes, dataBytes, 0, Convert.ToInt32(data.Length));

                        w.Headers.Set("Authorization", "Client-ID aa5d7d0bc1dffa6");

                        var values = new NameValueCollection
                        {
                            { "image", Convert.ToBase64String(dataBytes) }
                        };

                        return(w.UploadValues("https://api.imgur.com/3/image", values));
                    }
                });


                var json       = IoC.Resolve <IJsonSerializationService>();
                var imgurModel = json.Deserialize <ImgurModel>(System.Text.Encoding.UTF8.GetString(returnData));
                TextView.InsertText("![](" + imgurModel.Data.Link + ")");
            }
            catch (Exception e)
            {
                _alertDialogService.Alert("Error", "Unable to upload image: " + e.Message);
            }
            finally
            {
                _statusIndicatorService.Hide();
            }
        }
        public LoginViewModel(
            IApplicationService applicationService = null,
            IAlertDialogService alertDialogService = null)
        {
            applicationService = applicationService ?? Locator.Current.GetService <IApplicationService>();
            alertDialogService = alertDialogService ?? Locator.Current.GetService <IAlertDialogService>();

            LoginCommand = ReactiveCommand.CreateFromTask <string>(applicationService.Login);
            LoginCommand.Subscribe(x => MessageBus.Current.SendMessage(new LogoutMessage()));
            LoginCommand.ThrownExceptions
            .Select(ex => alertDialogService.Alert("Error", $"Unable to successfully login. {ex.Message}"))
            .Subscribe(x => x.ToBackground());
        }
Exemple #10
0
        public MarkdownAccessoryViewModel(
            IImgurService imgurService      = null,
            IMedia mediaPicker              = null,
            IAlertDialogService alertDialog = null)
        {
            imgurService = imgurService ?? Locator.Current.GetService <IImgurService>();
            mediaPicker  = mediaPicker ?? Plugin.Media.CrossMedia.Current;
            alertDialog  = alertDialog ?? Locator.Current.GetService <IAlertDialogService>();

            PostToImgurCommand = ReactiveCommand.CreateFromTask(async _ => {
                if (!Settings.HasSeenImgurUploadWarn)
                {
                    Settings.HasSeenImgurUploadWarn = true;
                    await alertDialog.Alert("Please Read!", IMGUR_UPLOAD_WARN_MESSAGE);
                }

                var photo = await mediaPicker.PickPhotoAsync(new PickMediaOptions
                {
                    CompressionQuality = 80
                });

                var memoryStream = new MemoryStream();
                await photo.GetStream().CopyToAsync(memoryStream);

                using (alertDialog.Activate("Uploading..."))
                {
                    var model = await imgurService.SendImage(memoryStream.ToArray());
                    if (model == null || model.Data == null || model.Data.Link == null)
                    {
                        throw new InvalidOperationException("Unable to upload to Imgur. Please try again later.");
                    }
                    return(model.Data.Link);
                }
            });

            PostToImgurCommand.ThrownExceptions
            .Where(x => !(x is TaskCanceledException))
            .Subscribe(x => alertDialog.Alert("Upload Error", x.Message));
        }
        private void SubmitFeedback()
        {
            var ctrl = new MFMailComposeViewController();

            ctrl.SetSubject("CodeHub Support");
            ctrl.SetToRecipients(new[] { "*****@*****.**" });
            ctrl.Finished += (sender, e) => DismissViewController(true, () =>
            {
                if (e.Result == MFMailComposeResult.Sent)
                {
                    _alertDialogService.Alert("Sent!", "Thanks for your feedback!");
                }
            });
            PresentViewController(ctrl, true, null);
        }
 private void SubmitFeedback()
 {
     if (!MFMailComposeViewController.CanSendMail)
     {
         _alertDialogService.Alert(
             "No Email Setup",
             "Looks like you don't have email setup on this device. " +
             "Add a mail provider and try again.").ToBackground();
     }
     else
     {
         var ctrl = new MFMailComposeViewController();
         ctrl.SetSubject("CodeHub Support");
         ctrl.SetToRecipients(new[] { "*****@*****.**" });
         ctrl.Finished += (sender, e) => DismissViewController(true, () =>
         {
             if (e.Result == MFMailComposeResult.Sent)
             {
                 _alertDialogService.Alert("Sent!", "Thanks for your feedback!");
             }
         });
         PresentViewController(ctrl, true, null);
     }
 }
        public OAuthLoginViewModel(
            ILoginService loginService             = null,
            IAlertDialogService alertDialogService = null)
        {
            _loginService       = loginService ?? Locator.Current.GetService <ILoginService>();
            _alertDialogService = alertDialogService ?? Locator.Current.GetService <IAlertDialogService>();

            LoginCommand = ReactiveCommand.CreateFromTask <string>(async code =>
            {
                await _loginService.LoginWithToken(
                    Secrets.GithubOAuthId, Secrets.GithubOAuthSecret,
                    code, RedirectUri, WebDomain, GitHubSharp.Client.DefaultApi);
                MessageBus.Current.SendMessage(new LogoutMessage());
            });

            LoginCommand
            .ThrownExceptions
            .Subscribe(err => _alertDialogService.Alert("Error!", err.Message).ToBackground());
        }
        public FeedbackComposerViewModel(IApplicationService applicationService, IImgurService imgurService,
                                         IMediaPickerService mediaPicker, IStatusIndicatorService statusIndicatorService, IAlertDialogService alertDialogService)
        {
            this.WhenAnyValue(x => x.IsFeature).Subscribe(x => Title = x ? "New Feature" : "Bug Report");

            SubmitCommand = ReactiveCommand.CreateAsyncTask(
                this.WhenAnyValue(x => x.Subject).Select(x => !string.IsNullOrEmpty(x)),
                async _ =>
            {
                if (string.IsNullOrEmpty(Subject))
                {
                    throw new ArgumentException(string.Format("You must provide a title for this {0}!", IsFeature ? "feature" : "bug"));
                }
                var labels       = await applicationService.Client.ExecuteAsync(applicationService.Client.Users[CodeHubOwner].Repositories[CodeHubName].Labels.GetAll());
                var createLabels = labels.Data.Where(x => string.Equals(x.Name, IsFeature ? "feature request" : "bug", StringComparison.OrdinalIgnoreCase)).Select(x => x.Name).Distinct();
                var request      = applicationService.Client.Users[CodeHubOwner].Repositories[CodeHubName].Issues.Create(Subject, Description, null, null, createLabels.ToArray());
                var createdIssue = await applicationService.Client.ExecuteAsync(request);
                _createdIssueSubject.OnNext(createdIssue.Data);
                DismissCommand.ExecuteIfCan();
            });

            PostToImgurCommand = ReactiveCommand.CreateAsyncTask(async _ =>
            {
                var photo        = await mediaPicker.PickPhoto();
                var memoryStream = new MemoryStream();
                await photo.Save(Splat.CompressedBitmapFormat.Jpeg, 0.8f, memoryStream);
                using (statusIndicatorService.Activate("Uploading..."))
                {
                    var model = await imgurService.SendImage(memoryStream.ToArray());
                    if (model == null || model.Data == null || model.Data.Link == null)
                    {
                        throw new InvalidOperationException("Unable to upload to Imgur. Please try again later.");
                    }
                    return(model.Data.Link);
                }
            });

            PostToImgurCommand.ThrownExceptions
            .Where(x => !(x is TaskCanceledException))
            .Subscribe(x => alertDialogService.Alert("Upload Error", x.Message));
        }
        public RepositoryExploreViewModel(
            IApplicationService applicationService = null,
            IAlertDialogService dialogService      = null)
        {
            _applicationService = applicationService ?? Locator.Current.GetService <IApplicationService>();
            dialogService       = dialogService ?? Locator.Current.GetService <IAlertDialogService>();

            RepositoryItemSelected = ReactiveCommand.Create <RepositoryItemViewModel, RepositoryItemViewModel>(x => x);
            var showDescription = _applicationService.Account.ShowRepositoryDescriptionInList;

            var internalItems = new ReactiveList <Repository>(resetChangeThreshold: double.MaxValue);

            Items = internalItems.CreateDerivedCollection(x =>
                                                          new RepositoryItemViewModel(x, true, showDescription, y => RepositoryItemSelected.ExecuteNow(y)));

            var canSearch = this.WhenAnyValue(x => x.SearchText).Select(x => !string.IsNullOrEmpty(x));

            SearchCommand = ReactiveCommand.CreateFromTask(async t =>
            {
                try
                {
                    internalItems.Clear();
                    var request  = new SearchRepositoriesRequest(SearchText);
                    var response = await _applicationService.GitHubClient.Search.SearchRepo(request);
                    internalItems.Reset(response.Items);
                }
                catch (Exception e)
                {
                    var msg = string.Format("Unable to search for {0}. Please try again.", SearchText);
                    throw new Exception(msg, e);
                }
            }, canSearch);

            SearchCommand
            .ThrownExceptions
            .Subscribe(err => dialogService.Alert("Error Searching", err.Message).ToBackground());
        }
Exemple #16
0
 protected override void OnLoadError(object sender, UIWebErrorArgs e)
 {
     base.OnLoadError(sender, e);
     _alertDialogService.Alert("Error", "Unable to display this type of file.");
 }
Exemple #17
0
        public CommitViewModel(
            string username, string repository, string node, bool showRepository = false,
            IApplicationService applicationService = null, IActionMenuService actionMenuService = null,
            IAlertDialogService alertDialogService = null)
        {
            _applicationService = applicationService = applicationService ?? Locator.Current.GetService <IApplicationService>();
            actionMenuService   = actionMenuService ?? Locator.Current.GetService <IActionMenuService>();
            alertDialogService  = alertDialogService ?? Locator.Current.GetService <IAlertDialogService>();

            Username       = username;
            Repository     = repository;
            Node           = node;
            ShowRepository = showRepository;

            var shortNode = node.Substring(0, node.Length > 7 ? 7 : node.Length);

            Title = $"Commit {shortNode}";

            var changesetFiles =
                this.WhenAnyValue(x => x.Changeset)
                .Where(x => x != null)
                .Select(x => x.Files ?? Enumerable.Empty <Client.V1.ChangesetFile>());

            changesetFiles
            .Select(x => x.Count(y => y.Type == "added"))
            .ToProperty(this, x => x.DiffAdditions, out _diffAdditions);

            changesetFiles
            .Select(x => x.Count(y => y.Type == "removed"))
            .ToProperty(this, x => x.DiffDeletions, out _diffDeletions);

            changesetFiles
            .Select(x => x.Count(y => y.Type != "added" && y.Type != "removed"))
            .ToProperty(this, x => x.DiffModifications, out _diffModifications);

            Comments = _comments.CreateDerivedCollection(comment =>
            {
                var name   = comment.User.DisplayName ?? comment.User.Username;
                var avatar = new Avatar(comment.User.Links?.Avatar?.Href);
                return(new CommentItemViewModel(name, avatar, comment.CreatedOn.Humanize(), comment.Content.Raw));
            }, x => x.Inline == null);

            GoToUserCommand = ReactiveCommand.Create <string>(user => NavigateTo(new UserViewModel(user)));

            GoToRepositoryCommand
            .Select(_ => new RepositoryViewModel(username, repository))
            .Subscribe(NavigateTo);

            GoToAddedFiles = ReactiveCommand.Create(
                () => { },
                this.WhenAnyValue(x => x.DiffAdditions).Select(x => x > 0));

            GoToRemovedFiles = ReactiveCommand.Create(
                () => { },
                this.WhenAnyValue(x => x.DiffDeletions).Select(x => x > 0));

            GoToModifiedFiles = ReactiveCommand.Create(
                () => { },
                this.WhenAnyValue(x => x.DiffModifications).Select(x => x > 0));

            var canShowMenu = this.WhenAnyValue(x => x.Commit).Select(x => x != null);

            ShowMenuCommand = ReactiveCommand.Create <object>(sender =>
            {
                var uri  = new Uri($"https://bitbucket.org/{username}/{repository}/commits/{node}");
                var menu = actionMenuService.Create();
                menu.AddButton("Add Comment", _ => AddCommentCommand.ExecuteNow());
                menu.AddButton("Copy SHA", _ => actionMenuService.SendToPasteBoard(node));
                menu.AddButton("Share", x => actionMenuService.ShareUrl(x, uri));
                menu.AddButton("Show In Bitbucket", _ => NavigateTo(new WebBrowserViewModel(uri.AbsoluteUri)));
                menu.Show(sender);
            }, canShowMenu);

            ToggleApproveButton = ReactiveCommand.CreateFromTask(async _ =>
            {
                if (Approved)
                {
                    await applicationService.Client.Commits.Unapprove(username, repository, node);
                }
                else
                {
                    await applicationService.Client.Commits.Approve(username, repository, node);
                }

                var shouldBe        = !Approved;
                var commit          = await applicationService.Client.Commits.Get(username, repository, node);
                var currentUsername = applicationService.Account.Username;
                var me = commit.Participants.FirstOrDefault(
                    y => string.Equals(currentUsername, y?.User?.Username, StringComparison.OrdinalIgnoreCase));
                if (me != null)
                {
                    me.Approved = shouldBe;
                }
                Commit = commit;
            });

            ToggleApproveButton
            .ThrownExceptions
            .Subscribe(x => alertDialogService.Alert("Error", "Unable to approve commit: " + x.Message).ToBackground());

            var commitFiles = new ReactiveList <Client.V1.ChangesetFile>();

            CommitFiles = commitFiles.CreateDerivedCollection(x =>
            {
                var vm = new CommitFileItemViewModel(username, repository, node, Changeset.Parents.FirstOrDefault(), x);
                vm.GoToCommand
                .Select(_ => new ChangesetDiffViewModel(username, repository, node, x))
                .Subscribe(NavigateTo);
                return(vm);
            });

            this.WhenAnyValue(x => x.Commit.Participants)
            .Select(participants =>
            {
                return((participants ?? Enumerable.Empty <CommitParticipant>())
                       .Where(x => x.Approved)
                       .Select(x =>
                {
                    var avatar = new Avatar(x.User?.Links?.Avatar?.Href);
                    var vm = new UserItemViewModel(x.User?.Username, x.User?.DisplayName, avatar);
                    vm.GoToCommand
                    .Select(_ => new UserViewModel(x.User))
                    .Subscribe(NavigateTo);
                    return vm;
                }));
            })
            .Select(x => x.ToArray())
            .ToProperty(this, x => x.Approvals, out _approvals, new UserItemViewModel[0]);

            this.WhenAnyValue(x => x.Changeset)
            .Subscribe(x => commitFiles.Reset(x?.Files ?? Enumerable.Empty <Client.V1.ChangesetFile>()));

            this.WhenAnyValue(x => x.Commit)
            .Subscribe(x =>
            {
                var currentUsername = applicationService.Account.Username;
                Approved            = x?.Participants
                                      ?.FirstOrDefault(y => string.Equals(currentUsername, y?.User?.Username, StringComparison.OrdinalIgnoreCase))
                                      ?.Approved ?? false;
            });

            LoadCommand = ReactiveCommand.CreateFromTask(_ =>
            {
                var commit = applicationService.Client.Commits.Get(username, repository, node)
                             .OnSuccess(x => Commit = x);
                var changeset = applicationService.Client.Commits.GetChangeset(username, repository, node)
                                .OnSuccess(x => Changeset = x);
                applicationService.Client.AllItems(x => x.Commits.GetComments(username, repository, node))
                .ToBackground(_comments.Reset);
                return(Task.WhenAll(commit, changeset));
            });
        }
Exemple #18
0
 private void LoadingError(Exception err)
 {
     _dialogService.Alert("Error Loading", err.Message).ToBackground();
 }