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; } }
private async Task Fork() { try { await this.DoWorkAsync("Forking...", ViewModel.ForkGist); } catch (Exception ex) { _alertDialogService.Alert("Error", ex.Message).ToBackground(); } }
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); }
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(); }
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()); }
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()); }
protected override void OnLoadError(object sender, UIWebErrorArgs e) { base.OnLoadError(sender, e); _alertDialogService.Alert("Error", "Unable to display this type of file."); }
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)); }); }
private void LoadingError(Exception err) { _dialogService.Alert("Error Loading", err.Message).ToBackground(); }