public LoginViewController(IAlertDialogFactory alertDialogService, IDefaultValueService defaultValueService) { _alertDialogService = alertDialogService; this.WhenAnyValue(x => x.ViewModel.ShowLoginOptionsCommand) .Select(x => x.ToBarButtonItem(UIBarButtonSystemItem.Action)) .Subscribe(x => NavigationItem.RightBarButtonItem = x); this.Appearing .Take(1) .Select(_ => this.WhenAnyValue(x => x.ViewModel.LoginUrl)) .Switch() .IsNotNull() .Subscribe(LoadRequest); bool hasSeenWelcome = false; if (!defaultValueService.TryGet(HasSeenWelcomeKey, out hasSeenWelcome)) { hasSeenWelcome = false; } this.Appeared .Where(_ => !hasSeenWelcome) .Take(1) .Subscribe(_ => BlurredAlertView.Display(OAuthWelcome, () => defaultValueService.Set(HasSeenWelcomeKey, true))); }
public FeedbackComposerViewModel(ISessionService applicationService, IAlertDialogFactory alertDialogFactory) { 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.GitHubClient.Issue.Labels.GetAllForRepository(CodeHubOwner, CodeHubName); var createLabels = labels.Where(x => string.Equals(x.Name, IsFeature ? "feature request" : "bug", StringComparison.OrdinalIgnoreCase)).Select(x => x.Name).Distinct(); var createIssueRequest = new Octokit.NewIssue(Subject) { Body = Description }; foreach (var label in createLabels) createIssueRequest.Labels.Add(label); var createdIssue = await applicationService.GitHubClient.Issue.Create(CodeHubOwner, CodeHubName, createIssueRequest); _createdIssueSubject.OnNext(createdIssue); Dismiss(); }); DismissCommand = ReactiveCommand.CreateAsyncTask(async t => { if (string.IsNullOrEmpty(Description) && string.IsNullOrEmpty(Subject)) return true; var itemType = IsFeature ? "feature" : "bug"; return await alertDialogFactory.PromptYesNo("Discard " + itemType.Transform(To.TitleCase) + "?", "Are you sure you want to discard this " + itemType + "?"); }); DismissCommand.Where(x => x).Subscribe(_ => Dismiss()); }
public MarkdownAccessoryViewModel( IImgurService imgurService, IMediaPickerFactory mediaPicker, IAlertDialogFactory alertDialogFactory, IDefaultValueService defaultValueService) { PostToImgurCommand = ReactiveCommand.CreateAsyncTask(async _ => { if (!defaultValueService.GetOrDefault(IMGUR_UPLOAD_WARN, false)) { defaultValueService.Set(IMGUR_UPLOAD_WARN, true); await alertDialogFactory.Alert("Please Read!", IMGUR_UPLOAD_WARN_MESSAGE); } var photo = await mediaPicker.PickPhoto(); var memoryStream = new MemoryStream(); await photo.Save(Splat.CompressedBitmapFormat.Jpeg, 0.8f, memoryStream); using (alertDialogFactory.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 => alertDialogFactory.Alert("Upload Error", x.Message)); }
public MarkdownAccessoryViewModel( IImgurService imgurService, IMediaPickerFactory mediaPicker, IAlertDialogFactory alertDialogFactory, IDefaultValueService defaultValueService) { PostToImgurCommand = ReactiveCommand.CreateAsyncTask(async _ => { if (!defaultValueService.GetOrDefault(IMGUR_UPLOAD_WARN, false)) { defaultValueService.Set(IMGUR_UPLOAD_WARN, true); await alertDialogFactory.Alert("Please Read!", IMGUR_UPLOAD_WARN_MESSAGE); } var photo = await mediaPicker.PickPhoto(); var memoryStream = new MemoryStream(); await photo.Save(Splat.CompressedBitmapFormat.Jpeg, 0.8f, memoryStream); using (alertDialogFactory.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 => alertDialogFactory.Alert("Upload Error", x.Message)); }
public CreateFileViewModel(ISessionService applicationService, IAlertDialogFactory alertDialogFactory) { Title = "Create File"; this.WhenAnyValue(x => x.Name).Subscribe(x => CommitMessage = "Created " + x); _canCommit = this.WhenAnyValue(x => x.Name) .Select(x => !string.IsNullOrEmpty(x)) .ToProperty(this, x => x.CanCommit); SaveCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.Name).Select(x => !string.IsNullOrEmpty(x)), async _ => { var content = Content ?? string.Empty; var path = Path; if (string.IsNullOrEmpty(Path)) path = "/"; path = System.IO.Path.Combine(path, Name); var request = applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].UpdateContentFile(path, CommitMessage, content, null, Branch); await applicationService.Client.ExecuteAsync(request); Dismiss(); }); DismissCommand = ReactiveCommand.CreateAsyncTask(async t => { if (string.IsNullOrEmpty(Name) && string.IsNullOrEmpty(Content)) return true; return await alertDialogFactory.PromptYesNo("Discard File?", "Are you sure you want to discard this file?"); }); DismissCommand.Where(x => x).Subscribe(_ => Dismiss()); }
public OAuthTokenLoginViewModel( ILoginService loginFactory, IAccountsRepository accountsRepository, IAlertDialogFactory alertDialogFactory) { Title = "Login"; var canLogin = this.WhenAnyValue(y => y.Token, (x) => !string.IsNullOrEmpty(x)); LoginCommand = ReactiveCommand.CreateAsyncTask(canLogin, async _ => { try { using (alertDialogFactory.Activate("Logging in...")) { var account = await loginFactory.Authenticate(ApiDomain, WebDomain, Token, false); await accountsRepository.SetDefault(account); return account; } } catch (UnauthorizedException) { throw new Exception("The provided token is invalid! Please try again or " + "create a new token as this one might have been revoked."); } }); LoginCommand.Subscribe(x => MessageBus.Current.SendMessage(new LogoutMessage())); }
protected AddAccountViewModel(IAlertDialogFactory alertDialogFactory) { _alertDialogFactory = alertDialogFactory; Title = "Login"; this.WhenAnyValue(x => x.AttemptedAccount).Where(x => x != null).Subscribe(x => { Username = x.Username; Domain = x.Domain; }); var canLogin = this.WhenAnyValue(x => x.Username, y => y.Password, z => z.Domain, (x, y, z) => !string.IsNullOrEmpty(x) && !string.IsNullOrEmpty(y) && !string.IsNullOrEmpty(z)); LoginCommand = ReactiveCommand.CreateAsyncTask(canLogin, async _ => { using (alertDialogFactory.Activate("Logging in...")) return await Login(); }); LoginCommand.ThrownExceptions.Subscribe(x => { if (x is LoginService.TwoFactorRequiredException) PromptForTwoFactor().ToBackground(); else _alertDialogFactory.Alert("Error", x.Message).ToBackground(); }); LoginCommand.Subscribe(x => MessageBus.Current.SendMessage(new LogoutMessage())); }
public SyntaxHighlighterSettingsView(IAlertDialogFactory alertDialogFactory) { _alertDialogFactory = alertDialogFactory; _pickerView.AutoresizingMask = UIViewAutoresizing.FlexibleWidth; _pickerView.ShowSelectionIndicator = true; _pickerView.BackgroundColor = UIColor.FromRGB(244, 244, 244); }
public OAuthFlowLoginViewModel( IAccountsRepository accountsRepository, IActionMenuFactory actionMenuService, IAlertDialogFactory alertDialogService) { _accountsRepository = accountsRepository; _alertDialogService = alertDialogService; Title = "Login"; var oauthLogin = ReactiveCommand.Create().WithSubscription(_ => NavigateTo(this.CreateViewModel<OAuthTokenLoginViewModel>())); var canLogin = this.WhenAnyValue(x => x.Code).Select(x => !string.IsNullOrEmpty(x)); var loginCommand = ReactiveCommand.CreateAsyncTask(canLogin,_ => Login(Code)); loginCommand.Subscribe(x => MessageBus.Current.SendMessage(new LogoutMessage())); LoginCommand = loginCommand; ShowLoginOptionsCommand = ReactiveCommand.CreateAsyncTask(sender => { var actionMenu = actionMenuService.Create(); actionMenu.AddButton("Login via Token", oauthLogin); return actionMenu.Show(sender); }); _loginUrl = this.WhenAnyValue(x => x.WebDomain) .IsNotNull() .Select(x => x.TrimEnd('/')) .Select(x => string.Format(x + "/login/oauth/authorize?client_id={0}&redirect_uri={1}&scope={2}", ClientId, Uri.EscapeDataString(RedirectUri), Uri.EscapeDataString(string.Join(",", OctokitClientFactory.Scopes)))) .ToProperty(this, x => x.LoginUrl); WebDomain = DefaultWebDomain; }
public IssueEditViewModel( IApplicationService applicationService, IAlertDialogFactory alertDialogFactory) : base(applicationService, alertDialogFactory) { _applicationService = applicationService; Title = "Edit Issue"; GoToDescriptionCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Issue).Select(x => x != null)); // GoToDescriptionCommand.Subscribe(_ => // { // var vm = this.CreateViewModel<ComposerViewModel>(); // vm.Text = Issue.Body; // vm.SaveCommand.Subscribe(__ => // { // Issue.Body = vm.Text; // vm.DismissCommand.ExecuteIfCan(); // }); // NavigateTo(vm); // }); this.WhenAnyValue(x => x.Issue).Where(x => x != null).Subscribe(x => { // Title = x.Title; // AssignedTo = x.Assignee; // Milestone = x.Milestone; // Labels = x.Labels.ToArray(); // Content = x.Body; // IsOpen = string.Equals(x.State, "open"); }); }
public OAuthTokenLoginViewModel( ILoginService loginFactory, IAccountsRepository accountsRepository, IAlertDialogFactory alertDialogFactory) { Title = "Login"; var canLogin = this.WhenAnyValue(y => y.Token, (x) => !string.IsNullOrEmpty(x)); LoginCommand = ReactiveCommand.CreateAsyncTask(canLogin, async _ => { try { using (alertDialogFactory.Activate("Logging in...")) { var account = await loginFactory.Authenticate(ApiDomain, WebDomain, Token, false); await accountsRepository.SetDefault(account); return(account); } } catch (UnauthorizedException) { throw new Exception("The provided token is invalid! Please try again or " + "create a new token as this one might have been revoked."); } }); LoginCommand.Subscribe(x => MessageBus.Current.SendMessage(new LogoutMessage())); }
protected AddAccountViewModel(IAlertDialogFactory alertDialogFactory) { _alertDialogFactory = alertDialogFactory; Title = "Login"; this.WhenAnyValue(x => x.AttemptedAccount).Where(x => x != null).Subscribe(x => { Username = x.Username; Domain = x.Domain; }); LoginCommand = ReactiveCommand.CreateAsyncTask(async _ => { if (string.IsNullOrEmpty(Username)) throw new ArgumentException("Must have a valid username!"); if (string.IsNullOrEmpty(Password)) throw new ArgumentException("Must have a valid password!"); if (string.IsNullOrEmpty(Domain)) throw new ArgumentException("Must have a valid GitHub domain!"); using (alertDialogFactory.Activate("Logging in...")) return await Login(); }); LoginCommand.ThrownExceptions.Subscribe(x => { if (x is LoginService.TwoFactorRequiredException) PromptForTwoFactor().ToBackground(); else _alertDialogFactory.Alert("Error", x.Message).ToBackground(); }); LoginCommand.Subscribe(x => MessageBus.Current.SendMessage(new LogoutMessage())); }
public CreateFileViewModel(ISessionService sessionService, IAlertDialogFactory alertDialogFactory) { Title = "Create File"; this.WhenAnyValue(x => x.Name) .Subscribe(x => CommitMessage = "Created " + x); _canCommit = this.WhenAnyValue(x => x.Name) .Select(x => !string.IsNullOrEmpty(x)) .ToProperty(this, x => x.CanCommit); SaveCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.Name).Select(x => !string.IsNullOrEmpty(x)), async _ => { var content = Content ?? string.Empty; var path = System.IO.Path.Combine(Path ?? string.Empty, Name); var request = new Octokit.CreateFileRequest(CommitMessage, content) { Branch = Branch }; using (alertDialogFactory.Activate("Commiting...")) return(await sessionService.GitHubClient.Repository.Content.CreateFile(RepositoryOwner, RepositoryName, path, request)); }); SaveCommand.Subscribe(x => Dismiss()); DismissCommand = ReactiveCommand.CreateAsyncTask(async t => { if (string.IsNullOrEmpty(Name) && string.IsNullOrEmpty(Content)) { return(true); } return(await alertDialogFactory.PromptYesNo("Discard File?", "Are you sure you want to discard this file?")); }); DismissCommand.Where(x => x).Subscribe(_ => Dismiss()); }
public CreateFileViewModel(ISessionService sessionService, IAlertDialogFactory alertDialogFactory) { Title = "Create File"; this.WhenAnyValue(x => x.Name) .Subscribe(x => CommitMessage = "Created " + x); GoToCommitMessageCommand = ReactiveCommand.Create( this.WhenAnyValue(x => x.Name, x => !string.IsNullOrEmpty(x))); SaveCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.Name).Select(x => !string.IsNullOrEmpty(x)), async _ => { var content = Content ?? string.Empty; var path = System.IO.Path.Combine(Path ?? string.Empty, Name); var request = new Octokit.CreateFileRequest(CommitMessage, content) { Branch = Branch }; using (alertDialogFactory.Activate("Commiting...")) return await sessionService.GitHubClient.Repository.Content.CreateFile(RepositoryOwner, RepositoryName, path, request); }); SaveCommand.Subscribe(x => Dismiss()); DismissCommand = ReactiveCommand.CreateAsyncTask(async t => { if (string.IsNullOrEmpty(Name) && string.IsNullOrEmpty(Content)) return true; return await alertDialogFactory.PromptYesNo("Discard File?", "Are you sure you want to discard this file?"); }); DismissCommand.Where(x => x).Subscribe(_ => Dismiss()); }
public GistCreateViewModel(ISessionService sessionService, IAlertDialogFactory alertDialogFactory) { _sessionService = sessionService; _alertDialogFactory = alertDialogFactory; Title = "Create Gist"; IsPublic = true; }
protected IssueModifyViewModel(IAlertDialogFactory alertDialogFactory) { SaveCommand = ReactiveCommand.CreateAsyncTask(async _ => { using (alertDialogFactory.Activate("Saving...")) await Save(); Dismiss(); }); }
public IssueAddViewModel( IApplicationService applicationService, IAlertDialogFactory statusIndicatorService) : base(applicationService, statusIndicatorService) { _applicationService = applicationService; Title = "New Issue"; }
public IssueAddViewModel( ISessionService applicationService, IAlertDialogFactory alertDialogService) : base(applicationService, alertDialogService) { _sessionService = applicationService; _alertDialogFactory = alertDialogService; Title = "New Issue"; }
public SyntaxHighlighterViewController(IAlertDialogFactory alertDialogFactory) { _alertDialogFactory = alertDialogFactory; _pickerView.AutoresizingMask = UIViewAutoresizing.FlexibleWidth; _pickerView.ShowSelectionIndicator = true; _pickerView.BackgroundColor = UIColor.FromRGB(244, 244, 244); Disappearing.Subscribe(_ => ViewModel.SaveCommand.ExecuteIfCan()); }
public static IDisposable AlertExecuting(this IReactiveCommand @this, IAlertDialogFactory dialogFactory, string text) { return @this.IsExecuting.Subscribe(x => { if (x) dialogFactory.Show(text); else dialogFactory.Hide(); }); }
public GistCreateViewModel(IApplicationService applicationService, IAlertDialogFactory alertDialogFactory) { _applicationService = applicationService; CurrentAccount = applicationService.Account; Title = "Create Gist"; IsPublic = true; var files = new ReactiveList <Tuple <string, string> >(); Files = files.CreateDerivedCollection(x => { var item = new GistFileItemViewModel(x.Item1, x.Item2); item.EditCommand.Subscribe(_ => NavigateTo(new GistFileEditViewModel(y => { var i = files.IndexOf(x); files.Remove(x); files.Insert(i, y); return(Task.FromResult(0)); }) { Filename = x.Item1, Description = x.Item2 })); item.DeleteCommand.Subscribe(_ => files.Remove(x)); return(item); }); SaveCommand = ReactiveCommand.CreateAsyncTask(Files.CountChanged.Select(x => x > 0), async t => { var createGist = new GistCreateModel { Description = Description, Public = IsPublic, Files = Files.ToDictionary(x => x.Name, x => new GistCreateModel.File { Content = x.Content }) }; var request = _applicationService.Client.AuthenticatedUser.Gists.CreateGist(createGist); using (alertDialogFactory.Activate("Creating Gist...")) return((await _applicationService.Client.ExecuteAsync(request)).Data); }); SaveCommand.Subscribe(_ => Dismiss()); AddGistFileCommand = ReactiveCommand.Create() .WithSubscription(_ => NavigateTo(new GistFileAddViewModel(x => { if (Files.Any(y => y.Name == x.Item1)) { throw new Exception("Gist already contains a file with that name!"); } files.Add(x); return(Task.FromResult(0)); }))); }
public IssueAddViewModel( ISessionService applicationService, IAlertDialogFactory alertDialogService) : base(applicationService, alertDialogService) { _applicationService = applicationService; _alertDialogFactory = alertDialogService; Title = "New Issue"; }
public GistCommentViewModel(IApplicationService applicationService, IImgurService imgurService, IMediaPickerFactory mediaPicker, IAlertDialogFactory alertDialogFactory) : base(imgurService, mediaPicker, alertDialogFactory) { Title = "Add Comment"; SaveCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.Text).Select(x => !string.IsNullOrEmpty(x)), async t => await applicationService.GitHubClient.Gist.Comment.Create(int.Parse(Id), Text)); SaveCommand.Subscribe(x => Dismiss()); }
public IssueCommentViewModel(IApplicationService applicationService, IImgurService imgurService, IMediaPickerFactory mediaPicker, IAlertDialogFactory alertDialogFactory) : base(imgurService, mediaPicker, alertDialogFactory) { Title = "Add Comment"; SaveCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.Text).Select(x => !string.IsNullOrEmpty(x)), t => applicationService.GitHubClient.Issue.Comment.Create(RepositoryOwner, RepositoryName, Id, Text)); SaveCommand.Subscribe(x => Dismiss()); }
public LoginView(IAlertDialogFactory alertDialogService) { _alertDialogService = alertDialogService; this.WhenAnyValue(x => x.ViewModel.ShowLoginOptionsCommand) .Select(x => x.ToBarButtonItem(UIBarButtonSystemItem.Action)) .Subscribe(x => NavigationItem.RightBarButtonItem = x); this.WhenAnyValue(x => x.ViewModel.LoginUrl).IsNotNull().Subscribe(LoadRequest); }
public PullRequestViewModel( ISessionService applicationService, IMarkdownService markdownService, IActionMenuFactory actionMenuService, IAlertDialogFactory alertDialogFactory) : base(applicationService, markdownService, actionMenuService, alertDialogFactory) { this.WhenAnyValue(x => x.Id) .Subscribe(x => Title = "Pull Request #" + x); this.WhenAnyValue(x => x.PullRequest.HtmlUrl) .ToProperty(this, x => x.HtmlUrl, out _htmlUrl); var canMergeObservable = this.WhenAnyValue(x => x.PullRequest) .Select(x => x != null && !x.Merged && x.Mergeable.HasValue && x.Mergeable.Value); _canMerge = canMergeObservable.CombineLatest( this.WhenAnyValue(x => x.PushAccess), (x, y) => x && y) .ToProperty(this, x => x.CanMerge); _commentsCount = this.WhenAnyValue(x => x.Issue.Comments, x => x.Comments.Count, (x, y) => x + y) .ToProperty(this, x => x.CommentCount); MergeCommand = ReactiveCommand.CreateAsyncTask(canMergeObservable, async t => { using (alertDialogFactory.Activate("Merging...")) { var req = new MergePullRequest { Message = MergeComment }; var response = await applicationService.GitHubClient.PullRequest.Merge(RepositoryOwner, RepositoryName, Id, req); if (!response.Merged) { throw new Exception(string.Format("Unable to merge pull request: {0}", response.Message)); } await LoadCommand.ExecuteAsync(); } }); var canGoToCommits = this.WhenAnyValue(x => x.PullRequest.Commits).Select(x => x > 0); GoToCommitsCommand = ReactiveCommand.Create(canGoToCommits); GoToCommitsCommand .Select(x => this.CreateViewModel <PullRequestCommitsViewModel>()) .Select(x => x.Init(RepositoryOwner, RepositoryName, Id)) .Subscribe(NavigateTo); var canGoToFiles = this.WhenAnyValue(x => x.PullRequest.ChangedFiles).Select(x => x > 0); GoToFilesCommand = ReactiveCommand.Create(canGoToFiles); GoToFilesCommand .Select(x => this.CreateViewModel <PullRequestFilesViewModel>()) .Select(x => x.Init(RepositoryOwner, RepositoryName, Id, PullRequest.Head.Sha)) .Do(x => x.CommentCreated.Subscribe(AddComment)) .Subscribe(NavigateTo); }
public EnterpriseOAuthTokenLoginViewModel( ILoginService loginFactory, IAccountsRepository accountsRepository, IAlertDialogFactory alertDialogFactory) { Title = "Login"; LoginCommand = ReactiveCommand.CreateAsyncTask(async _ => { if (string.IsNullOrEmpty(Domain)) { throw new ArgumentException("Must have a valid GitHub domain"); } if (string.IsNullOrEmpty(Token)) { throw new ArgumentException("Must have a valid Token"); } Uri domainUri; if (!Uri.TryCreate(Domain, UriKind.Absolute, out domainUri)) { throw new Exception("The provided domain is not a valid URL."); } var apiUrl = Domain; if (apiUrl != null) { if (!apiUrl.EndsWith("/", StringComparison.Ordinal)) { apiUrl += "/"; } if (!apiUrl.Contains("/api/")) { apiUrl += "api/v3/"; } } try { using (alertDialogFactory.Activate("Logging in...")) { var account = await loginFactory.Authenticate(apiUrl, Domain, Token, true); await accountsRepository.SetDefault(account); return(account); } } catch (UnauthorizedException) { throw new Exception("The provided token is invalid! Please try again or " + "create a new token as this one might have been revoked."); } }); LoginCommand.Subscribe(x => MessageBus.Current.SendMessage(new LogoutMessage())); }
public EditFileViewModel(ISessionService sessionService, IAlertDialogFactory alertDialogFactory) { Title = "Edit"; this.WhenAnyValue(x => x.Path) .IsNotNull() .Subscribe(x => CommitMessage = "Updated " + x.Substring(x.LastIndexOf('/') + 1)); this.WhenAnyValue(x => x.Text) .Subscribe(x => _lastEdit = DateTime.Now); LoadCommand = ReactiveCommand.CreateAsyncTask(async t => { var path = Path; if (!path.StartsWith("/", StringComparison.Ordinal)) { path = "/" + path; } var request = sessionService.Client.Users[RepositoryOwner].Repositories[RepositoryName].GetContentFile(path, Branch ?? "master"); request.UseCache = false; var data = await sessionService.Client.ExecuteAsync(request); BlobSha = data.Data.Sha; var content = Convert.FromBase64String(data.Data.Content); Text = System.Text.Encoding.UTF8.GetString(content, 0, content.Length) ?? string.Empty; _lastLoad = DateTime.Now; }); GoToCommitMessageCommand = ReactiveCommand.Create(); SaveCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.CommitMessage).Select(x => !string.IsNullOrEmpty(x)), async _ => { var path = Path.TrimStart('/'); var request = new Octokit.UpdateFileRequest(CommitMessage, Text, BlobSha) { Branch = Branch }; using (alertDialogFactory.Activate("Commiting...")) return(await sessionService.GitHubClient.Repository.Content.UpdateFile(RepositoryOwner, RepositoryName, path, request)); }); SaveCommand.Subscribe(x => Dismiss()); DismissCommand = ReactiveCommand.CreateAsyncTask(async t => { if (string.IsNullOrEmpty(Text)) { return(true); } if (_lastEdit <= _lastLoad) { return(true); } return(await alertDialogFactory.PromptYesNo("Discard Edit?", "Are you sure you want to discard these changes?")); }); DismissCommand.Where(x => x).Subscribe(_ => Dismiss()); }
public FeedbackComposerViewModel( IApplicationService applicationService, IImgurService imgurService, IMediaPickerFactory mediaPicker, IAlertDialogFactory 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.GitHubClient.Issue.Labels.GetForRepository(CodeHubOwner, CodeHubName); var createLabels = labels.Where(x => string.Equals(x.Name, IsFeature ? "feature request" : "bug", StringComparison.OrdinalIgnoreCase)).Select(x => x.Name).Distinct(); var createIssueRequest = new Octokit.NewIssue(Subject) { Body = Description }; foreach (var label in createLabels) { createIssueRequest.Labels.Add(label); } var createdIssue = await applicationService.GitHubClient.Issue.Create(CodeHubOwner, CodeHubName, createIssueRequest); _createdIssueSubject.OnNext(createdIssue); Dismiss(); }); PostToImgurCommand = ReactiveCommand.CreateAsyncTask(async _ => { var photo = await mediaPicker.PickPhoto(); var memoryStream = new MemoryStream(); await photo.Save(Splat.CompressedBitmapFormat.Jpeg, 0.8f, memoryStream); using (alertDialogService.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 static IDisposable Activate(this IAlertDialogFactory @this, IObservable <bool> observable, string text) { return(observable.Subscribe(x => { if (x) { @this.Show(text); } else { @this.Hide(); } })); }
public static IDisposable Activate(this IAlertDialogFactory @this, IReactiveCommand command, string text) { return(command.IsExecuting.Subscribe(x => { if (x) { @this.Show(text); } else { @this.Hide(); } })); }
public CommitCommentViewModel(IApplicationService applicationService, IImgurService imgurService, IMediaPickerFactory mediaPicker, IAlertDialogFactory alertDialogFactory) : base(imgurService, mediaPicker, alertDialogFactory) { SaveCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.Text).Select(x => !string.IsNullOrEmpty(x)), t => { var commitComment = new Octokit.NewCommitComment(Text); return(applicationService.GitHubClient.Repository.RepositoryComments.Create(RepositoryOwner, RepositoryName, Node, commitComment)); }); SaveCommand.Subscribe(x => Dismiss()); }
public static IDisposable AlertExecuting(this IReactiveCommand @this, IAlertDialogFactory dialogFactory, string text) { return(@this.IsExecuting.Subscribe(x => { if (x) { dialogFactory.Show(text); } else { dialogFactory.Hide(); } })); }
public IssueViewModel( ISessionService applicationService, IActionMenuFactory actionMenuFactory, IMarkdownService markdownService, IAlertDialogFactory alertDialogFactory) : base(applicationService, markdownService, actionMenuFactory, alertDialogFactory) { this.WhenAnyValue(x => x.Id) .Subscribe(x => Title = "Issue #" + x); _htmlUrl = this.WhenAnyValue(x => x.Issue.HtmlUrl) .ToProperty(this, x => x.HtmlUrl); }
public StartupViewModel( ISessionService sessionService, IAccountsRepository accountsService, IAlertDialogFactory alertDialogFactory, IDefaultValueService defaultValueService) { _sessionService = sessionService; _accountsService = accountsService; _alertDialogFactory = alertDialogFactory; _defaultValueService = defaultValueService; StartupCommand = ReactiveCommand.CreateAsyncTask(x => Load()); }
public EditFileViewModel(ISessionService applicationService, IAlertDialogFactory alertDialogFactory) { Title = "Edit"; this.WhenAnyValue(x => x.Path) .IsNotNull() .Subscribe(x => CommitMessage = "Updated " + x.Substring(x.LastIndexOf('/') + 1)); this.WhenAnyValue(x => x.Text) .Subscribe(x => _lastEdit = DateTime.Now); LoadCommand = ReactiveCommand.CreateAsyncTask(async t => { var path = Path; if (!path.StartsWith("/", StringComparison.Ordinal)) path = "/" + path; var request = applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].GetContentFile(path, Branch ?? "master"); request.UseCache = false; var data = await applicationService.Client.ExecuteAsync(request); BlobSha = data.Data.Sha; var content = Convert.FromBase64String(data.Data.Content); Text = System.Text.Encoding.UTF8.GetString(content, 0, content.Length) ?? string.Empty; _lastLoad = DateTime.Now; }); SaveCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.CommitMessage).Select(x => !string.IsNullOrEmpty(x)), async _ => { var path = Path.StartsWith("/", StringComparison.Ordinal) ? Path : string.Concat("/", Path); var request = applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName] .UpdateContentFile(path, CommitMessage, Text, BlobSha, Branch); using (alertDialogFactory.Activate("Commiting...")) { var response = await applicationService.Client.ExecuteAsync(request); _sourceChangedSubject.OnNext(response.Data); } Dismiss(); }); DismissCommand = ReactiveCommand.CreateAsyncTask(async t => { if (string.IsNullOrEmpty(Text)) return true; if (_lastEdit <= _lastLoad) return true; return await alertDialogFactory.PromptYesNo("Discard Edit?", "Are you sure you want to discard these changes?"); }); DismissCommand.Where(x => x).Subscribe(_ => Dismiss()); }
public PullRequestViewModel( ISessionService applicationService, IMarkdownService markdownService, IActionMenuFactory actionMenuService, IAlertDialogFactory alertDialogFactory) : base(applicationService, markdownService, actionMenuService, alertDialogFactory) { this.WhenAnyValue(x => x.Id) .Subscribe(x => Title = "Pull Request #" + x); this.WhenAnyValue(x => x.PullRequest.HtmlUrl) .ToProperty(this, x => x.HtmlUrl, out _htmlUrl); var canMergeObservable = this.WhenAnyValue(x => x.PullRequest) .Select(x => x != null && !x.Merged && x.Mergeable.HasValue && x.Mergeable.Value); _canMerge = canMergeObservable.CombineLatest( this.WhenAnyValue(x => x.PushAccess), (x, y) => x && y) .ToProperty(this, x => x.CanMerge); _commentsCount = this.WhenAnyValue(x => x.Issue.Comments, x => x.Comments.Count, (x, y) => x + y) .ToProperty(this, x => x.CommentCount); MergeCommand = ReactiveCommand.CreateAsyncTask(canMergeObservable, async t => { using (alertDialogFactory.Activate("Merging...")) { var req = new MergePullRequest { CommitMessage = MergeComment }; var response = await applicationService.GitHubClient.PullRequest.Merge(RepositoryOwner, RepositoryName, Id, req); if (!response.Merged) throw new Exception(string.Format("Unable to merge pull request: {0}", response.Message)); await LoadCommand.ExecuteAsync(); } }); var canGoToCommits = this.WhenAnyValue(x => x.PullRequest.Commits).Select(x => x > 0); GoToCommitsCommand = ReactiveCommand.Create(canGoToCommits); GoToCommitsCommand .Select(x => this.CreateViewModel<PullRequestCommitsViewModel>()) .Select(x => x.Init(RepositoryOwner, RepositoryName, Id)) .Subscribe(NavigateTo); var canGoToFiles = this.WhenAnyValue(x => x.PullRequest.ChangedFiles).Select(x => x > 0); GoToFilesCommand = ReactiveCommand.Create(canGoToFiles); GoToFilesCommand .Select(x => this.CreateViewModel<PullRequestFilesViewModel>()) .Select(x => x.Init(RepositoryOwner, RepositoryName, Id, PullRequest.Head.Sha)) .Do(x => x.CommentCreated.Subscribe(AddComment)) .Subscribe(NavigateTo); }
public PullRequestCommentViewModel(IApplicationService applicationService, IImgurService imgurService, IMediaPickerFactory mediaPicker, IAlertDialogFactory alertDialogFactory) : base(imgurService, mediaPicker, alertDialogFactory) { Title = "Add Comment"; SaveCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.Text).Select(x => !string.IsNullOrEmpty(x)), t => { var req = new Octokit.PullRequestReviewCommentCreate(Text, null, null, 0); return(applicationService.GitHubClient.PullRequest.Comment.Create(RepositoryOwner, RepositoryName, Id, req)); }); SaveCommand.Subscribe(x => Dismiss()); }
public ChangesetDiffViewModel(ISessionService sessionService, IActionMenuFactory actionMenuFactory, IAlertDialogFactory alertDialogFactory) { var comments = new ReactiveList<CommitComment>(); Comments = comments.CreateDerivedCollection( x => new FileDiffCommentViewModel(x.User.Login, x.User.AvatarUrl, x.Body, x.Position ?? 0)); var gotoCreateCommentCommand = ReactiveCommand.Create().WithSubscription(_ => { var vm = new ComposerViewModel(async s => { var cmd = new NewCommitComment(s) { Path = Filename, Position = SelectedPatchLine.Item1 }; var comment = await sessionService.GitHubClient.Repository.RepositoryComments.Create(Username, Repository, Branch, cmd); _commentCreatedObservable.OnNext(comment); comments.Add(comment); }, alertDialogFactory); NavigateTo(vm); }); GoToCommentCommand = ReactiveCommand.CreateAsyncTask(this.WhenAnyValue(x => x.SelectedPatchLine).Select(x => x != null), sender => { var sheet = actionMenuFactory.Create(); sheet.AddButton(string.Format("Add Comment on Line {0}", SelectedPatchLine.Item2), gotoCreateCommentCommand); return sheet.Show(sender); }); _patch = this.WhenAnyValue(x => x.CommitFile) .IsNotNull().Select(x => x.Patch).ToProperty(this, x => x.Patch); this.WhenAnyValue(x => x.Filename).Subscribe(x => { if (string.IsNullOrEmpty(x)) Title = "Diff"; else { _actualFilename = Path.GetFileName(Filename) ?? Filename.Substring(Filename.LastIndexOf('/') + 1); Title = _actualFilename; } }); LoadCommand = ReactiveCommand.CreateAsyncTask(async t => { sessionService.GitHubClient.Repository.RepositoryComments.GetAllForCommit(Username, Repository, Branch) .ToBackground(x => comments.Reset(x.Where(y => string.Equals(y.Path, Filename)))); var commits = await sessionService.GitHubClient.Repository.Commits.Get(Username, Repository, Branch); CommitFile = commits.Files.FirstOrDefault(x => string.Equals(x.Filename, Filename, StringComparison.Ordinal)); }); }
public ComposerViewModel(string title, Func<string, Task> saveFunc, IAlertDialogFactory alertDialogFactory) { Title = title; SaveCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.Text).Select(x => !string.IsNullOrEmpty(x)), t => saveFunc(Text)); SaveCommand.AlertExecuting(alertDialogFactory, "Saving..."); SaveCommand.Subscribe(x => Dismiss()); DismissCommand = ReactiveCommand.CreateAsyncTask(async t => { if (string.IsNullOrEmpty(Text)) return true; return await alertDialogFactory.PromptYesNo("Discard Comment?", "Are you sure you want to discard this comment?"); }); DismissCommand.Where(x => x).Subscribe(_ => Dismiss()); }
public EnterpriseOAuthTokenLoginViewModel( ILoginService loginFactory, IAccountsRepository accountsRepository, IAlertDialogFactory alertDialogFactory) { Title = "Login"; LoginCommand = ReactiveCommand.CreateAsyncTask(async _ => { if (string.IsNullOrEmpty(Domain)) throw new ArgumentException("Must have a valid GitHub domain"); if (string.IsNullOrEmpty(Token)) throw new ArgumentException("Must have a valid Token"); Uri domainUri; if (!Uri.TryCreate(Domain, UriKind.Absolute, out domainUri)) throw new Exception("The provided domain is not a valid URL."); var apiUrl = Domain; if (apiUrl != null) { if (!apiUrl.EndsWith("/", StringComparison.Ordinal)) apiUrl += "/"; if (!apiUrl.Contains("/api/")) apiUrl += "api/v3/"; } try { using (alertDialogFactory.Activate("Logging in...")) { var account = await loginFactory.Authenticate(apiUrl, Domain, Token, true); await accountsRepository.SetDefault(account); return account; } } catch (UnauthorizedException) { throw new Exception("The provided token is invalid! Please try again or " + "create a new token as this one might have been revoked."); } }); LoginCommand.Subscribe(x => MessageBus.Current.SendMessage(new LogoutMessage())); }
protected AddAccountViewModel(IAlertDialogFactory alertDialogFactory) { _alertDialogFactory = alertDialogFactory; Title = "Login"; this.WhenAnyValue(x => x.AttemptedAccount).Where(x => x != null).Subscribe(x => { Username = x.Username; Domain = x.Domain; }); LoginCommand = ReactiveCommand.CreateAsyncTask(async _ => { if (string.IsNullOrEmpty(Username)) { throw new ArgumentException("Must have a valid username!"); } if (string.IsNullOrEmpty(Password)) { throw new ArgumentException("Must have a valid password!"); } if (string.IsNullOrEmpty(Domain)) { throw new ArgumentException("Must have a valid GitHub domain!"); } using (alertDialogFactory.Activate("Logging in...")) return(await Login()); }); LoginCommand.ThrownExceptions.Subscribe(x => { if (x is LoginService.TwoFactorRequiredException) { PromptForTwoFactor().ToBackground(); } else { _alertDialogFactory.Alert("Error", x.Message).ToBackground(); } }); LoginCommand.Subscribe(x => MessageBus.Current.SendMessage(new LogoutMessage())); }
public ComposerViewModel(string title, Func <string, Task> saveFunc, IAlertDialogFactory alertDialogFactory) { Title = title; SaveCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.Text).Select(x => !string.IsNullOrEmpty(x)), t => saveFunc(Text)); SaveCommand.AlertExecuting(alertDialogFactory, "Saving..."); SaveCommand.Subscribe(x => Dismiss()); DismissCommand = ReactiveCommand.CreateAsyncTask(async t => { if (string.IsNullOrEmpty(Text)) { return(true); } return(await alertDialogFactory.PromptYesNo("Discard Comment?", "Are you sure you want to discard this comment?")); }); DismissCommand.Where(x => x).Subscribe(_ => Dismiss()); }
public PullRequestDiffViewModel(ISessionService sessionService, IActionMenuFactory actionMenuFactory, IAlertDialogFactory alertDialogFactory) { var gotoCreateCommentCommand = ReactiveCommand.Create().WithSubscription(_ => { var vm = new ComposerViewModel(async s => { var req = new PullRequestReviewCommentCreate(s, ParentViewModel.HeadSha, Filename, SelectedPatchLine.Item1); var comment = await sessionService.GitHubClient.PullRequest.Comment.Create(ParentViewModel.RepositoryOwner, ParentViewModel.RepositoryName, ParentViewModel.PullRequestId, req); _commentCreatedObservable.OnNext(comment); }, alertDialogFactory); NavigateTo(vm); }); GoToCommentCommand = ReactiveCommand.CreateAsyncTask(this.WhenAnyValue(x => x.SelectedPatchLine).Select(x => x != null), sender => { var sheet = actionMenuFactory.Create(); sheet.AddButton(string.Format("Add Comment on Line {0}", SelectedPatchLine.Item2), gotoCreateCommentCommand); return sheet.Show(sender); }); this.WhenAnyValue(x => x.PullRequestFile.Patch) .IsNotNull() .ToProperty(this, x => x.Patch, out _patch); var comments = new ReactiveList<PullRequestReviewComment>(); Comments = comments.CreateDerivedCollection( x => new FileDiffCommentViewModel(x.User.Login, x.User.AvatarUrl, x.Body, x.Position ?? 0)); this.WhenAnyValue(x => x.ParentViewModel.Comments) .Merge(this.WhenAnyObservable(x => x.ParentViewModel.Comments.Changed).Select(_ => ParentViewModel.Comments)) .Select(x => x.Where(y => string.Equals(y.Path, Filename, StringComparison.OrdinalIgnoreCase)).ToList()) .Subscribe(x => comments.Reset(x)); this.WhenAnyValue(x => x.PullRequestFile.FileName) .ToProperty(this, x => x.Filename, out _filename); this.WhenAnyValue(x => x.Filename) .Subscribe(x => { if (string.IsNullOrEmpty(x)) Title = "Diff"; else Title = Path.GetFileName(Filename) ?? Filename.Substring(Filename.LastIndexOf('/') + 1); }); }
protected IssueModifyViewModel( ISessionService applicationService, IAlertDialogFactory alertDialogFactory) { GoToAssigneesCommand = ReactiveCommand.Create(); GoToLabelsCommand = ReactiveCommand.Create(); GoToMilestonesCommand = ReactiveCommand.Create(); // Make sure repeated access is cached with Lazy var getAssignees = new Lazy<Task<IReadOnlyList<User>>>(() => applicationService.GitHubClient.Issue.Assignee.GetAllForRepository(RepositoryOwner, RepositoryName)); var getMilestones = new Lazy<Task<IReadOnlyList<Milestone>>>(() => applicationService.GitHubClient.Issue.Milestone.GetAllForRepository(RepositoryOwner, RepositoryName)); var getLables = new Lazy<Task<IReadOnlyList<Label>>>(() => applicationService.GitHubClient.Issue.Labels.GetAllForRepository(RepositoryOwner, RepositoryName)); Assignees = new IssueAssigneeViewModel(() => getAssignees.Value); Milestones = new IssueMilestonesViewModel(() => getMilestones.Value); Labels = new IssueLabelsViewModel(() => getLables.Value); var canSave = this.WhenAnyValue(x => x.Subject).Select(x => !string.IsNullOrEmpty(x)); SaveCommand = ReactiveCommand.CreateAsyncTask(canSave, _ => { using (alertDialogFactory.Activate("Saving...")) return Save(); }); // This is because the stupid ReactiveUI issue with the tableview :( SaveCommand.Subscribe(_ => Dismiss()); LoadCommand = ReactiveCommand.CreateAsyncTask(async t => { try { IsCollaborator = await applicationService.GitHubClient.Repository.RepoCollaborators .IsCollaborator(RepositoryOwner, RepositoryName, applicationService.Account.Username); } catch { IsCollaborator = false; } }); DismissCommand = ReactiveCommand.CreateAsyncTask(t => Discard()); DismissCommand.Where(x => x).Subscribe(_ => Dismiss()); }
public FeedbackComposerViewModel(ISessionService applicationService, IAlertDialogFactory alertDialogFactory) { 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.GitHubClient.Issue.Labels.GetAllForRepository(CodeHubOwner, CodeHubName); var createLabels = labels.Where(x => string.Equals(x.Name, IsFeature ? "feature request" : "bug", StringComparison.OrdinalIgnoreCase)).Select(x => x.Name).Distinct(); var createIssueRequest = new Octokit.NewIssue(Subject) { Body = Description }; foreach (var label in createLabels) { createIssueRequest.Labels.Add(label); } var createdIssue = await applicationService.GitHubClient.Issue.Create(CodeHubOwner, CodeHubName, createIssueRequest); _createdIssueSubject.OnNext(createdIssue); Dismiss(); }); DismissCommand = ReactiveCommand.CreateAsyncTask(async t => { if (string.IsNullOrEmpty(Description) && string.IsNullOrEmpty(Subject)) { return(true); } var itemType = IsFeature ? "feature" : "bug"; return(await alertDialogFactory.PromptYesNo("Discard " + itemType.Transform(To.TitleCase) + "?", "Are you sure you want to discard this " + itemType + "?")); }); DismissCommand.Where(x => x).Subscribe(_ => Dismiss()); }
public EditFileViewModel(IApplicationService applicationService, IAlertDialogFactory alertDialogFactory) { Title = "Edit"; this.WhenAnyValue(x => x.Path) .IsNotNull() .Subscribe(x => CommitMessage = "Updated " + x.Substring(x.LastIndexOf('/') + 1)); LoadCommand = ReactiveCommand.CreateAsyncTask(async t => { var path = Path; if (!path.StartsWith("/", StringComparison.Ordinal)) { path = "/" + path; } var request = applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].GetContentFile(path, Branch ?? "master"); request.UseCache = false; var data = await applicationService.Client.ExecuteAsync(request); BlobSha = data.Data.Sha; var content = Convert.FromBase64String(data.Data.Content); Text = System.Text.Encoding.UTF8.GetString(content, 0, content.Length) ?? string.Empty; }); SaveCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.CommitMessage).Select(x => !string.IsNullOrEmpty(x)), async _ => { var path = Path.StartsWith("/", StringComparison.Ordinal) ? Path : string.Concat("/", Path); var request = applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName] .UpdateContentFile(path, CommitMessage, Text, BlobSha, Branch); using (alertDialogFactory.Activate("Commiting...")) { var response = await applicationService.Client.ExecuteAsync(request); _sourceChangedSubject.OnNext(response.Data); } Dismiss(); }); }
public GistEditViewModel(ISessionService sessionService, IAlertDialogFactory alertDialogFactory) { _sessionService = sessionService; _alertDialogFactory = alertDialogFactory; Title = "Edit Gist"; this.WhenAnyValue(x => x.Gist) .IsNotNull() .Subscribe(x => { Description = x.Description; foreach (var file in x.Files) InternalFiles.Add(Tuple.Create(file.Key, file.Value.Content)); _lastLoaded = DateTime.Now; }); this.WhenAnyValue(x => x.Description).Select(x => Unit.Default) .Merge(InternalFiles.Changed.Select(x => Unit.Default)) .Subscribe(_ => _lastChanged = DateTime.Now); }
public IssueEditViewModel( ISessionService sessionService, IAlertDialogFactory alertDialogFactory) : base(sessionService, alertDialogFactory) { _sessionService = sessionService; _alertDialogFactory = alertDialogFactory; Title = "Edit Issue"; this.WhenAnyValue(x => x.Issue) .IsNotNull() .Subscribe(x => { Title = string.Format("Edit Issue #{0}", x.Number); Subject = x.Title; Milestone = x.Milestone; Labels = x.Labels; Assignee = x.Assignee; Content = x.Body; IsOpen = x.State == Octokit.ItemState.Open; }); }
public AddEnterpriseAccountViewModel( ILoginService loginFactory, IAccountsRepository accountsRepository, IAlertDialogFactory alertDialogFactory, IActionMenuFactory actionMenuFactory) : base(alertDialogFactory) { _loginFactory = loginFactory; _accountsRepository = accountsRepository; var gotoOAuthToken = ReactiveCommand.Create().WithSubscription(_ => { var vm = this.CreateViewModel<EnterpriseOAuthTokenLoginViewModel>(); vm.Domain = Domain; NavigateTo(vm); }); ShowLoginOptionsCommand = ReactiveCommand.CreateAsyncTask(sender => { var actionMenu = actionMenuFactory.Create(); actionMenu.AddButton("Login via Token", gotoOAuthToken); return actionMenu.Show(sender); }); }
public CommitViewModel(ISessionService applicationService, IActionMenuFactory actionMenuService, IAlertDialogFactory alertDialogFactory) { Title = "Commit"; var comments = new ReactiveList<CommentModel>(); Comments = comments.CreateDerivedCollection(x => new CommitCommentItemViewModel(x)); this.WhenAnyValue(x => x.Commit) .Select(x => new GitHubAvatar(x.GenerateGravatarUrl())) .ToProperty(this, x => x.Avatar, out _avatar); var files = this.WhenAnyValue(x => x.Commit.Files).IsNotNull(); files.Select(x => x.Count(y => string.Equals(y.Status, "added"))) .ToProperty(this, x => x.DiffAdditions, out _diffAdditions); files.Select(x => x.Count(y => string.Equals(y.Status, "removed"))) .ToProperty(this, x => x.DiffDeletions, out _diffDeletions); files.Select(x => x.Count(y => string.Equals(y.Status, "modified"))) .ToProperty(this, x => x.DiffModifications, out _diffModifications); GoToAddedFiles = ReactiveCommand.Create(this.WhenAnyValue(x => x.DiffAdditions).Select(x => x > 0)); GoToAddedFiles .Select(_ => new CommitFilesViewModel()) .Select(y => y.Init(RepositoryOwner, RepositoryName, Node, "Added", Commit.Files.Where(x => string.Equals(x.Status, "added")))) .Subscribe(NavigateTo); GoToRemovedFiles = ReactiveCommand.Create(this.WhenAnyValue(x => x.DiffDeletions).Select(x => x > 0)); GoToRemovedFiles .Select(_ => new CommitFilesViewModel()) .Select(y => y.Init(RepositoryOwner, RepositoryName, Node, "Removed", Commit.Files.Where(x => string.Equals(x.Status, "removed")))) .Subscribe(NavigateTo); GoToModifiedFiles = ReactiveCommand.Create(this.WhenAnyValue(x => x.DiffModifications).Select(x => x > 0)); GoToModifiedFiles .Select(_ => new CommitFilesViewModel()) .Select(y => y.Init(RepositoryOwner, RepositoryName, Node, "Modified", Commit.Files.Where(x => string.Equals(x.Status, "modified")))) .Subscribe(NavigateTo); GoToAllFiles = ReactiveCommand.Create(this.WhenAnyValue(x => x.Commit.Files).Select(x => x != null)); GoToAllFiles .Select(_ => new CommitFilesViewModel()) .Select(y => y.Init(RepositoryOwner, RepositoryName, Node, "All Changes", Commit.Files)) .Subscribe(NavigateTo); this.WhenAnyValue(x => x.Commit) .IsNotNull() .Select(x => x.GenerateCommiterName()) .ToProperty(this, x => x.CommiterName, out _commiterName); this.WhenAnyValue(x => x.Commit) .IsNotNull() .Select(x => x.Commit.Message ?? string.Empty) .Select(x => Emojis.FindAndReplace(x)) .ToProperty(this, x => x.CommitMessage, out _commitMessage); this.WhenAnyValue(x => x.CommitMessage) .IsNotNull() .Select(x => { var firstNewLine = x.IndexOf("\n", StringComparison.Ordinal); return firstNewLine > 0 ? x.Substring(0, firstNewLine) : x; }) .ToProperty(this, x => x.CommitMessageSummary, out _commitMessageSummary); GoToHtmlUrlCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Commit).Select(x => x != null)); GoToHtmlUrlCommand .Select(_ => this.CreateViewModel<WebBrowserViewModel>()) .Select(x => x.Init(Commit.HtmlUrl)) .Subscribe(NavigateTo); GoToRepositoryCommand = ReactiveCommand.Create(); GoToRepositoryCommand.Subscribe(_ => { var vm = this.CreateViewModel<RepositoryViewModel>(); vm.Init(RepositoryOwner, RepositoryName); NavigateTo(vm); }); AddCommentCommand = ReactiveCommand.Create().WithSubscription(_ => { var vm = new ComposerViewModel(async s => { var request = applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Commits[Node].Comments.Create(s); comments.Add((await applicationService.Client.ExecuteAsync(request)).Data); }, alertDialogFactory); NavigateTo(vm); }); var validCommitObservable = this.WhenAnyValue(x => x.Commit).Select(x => x != null); var copyShaCommand = ReactiveCommand.Create(validCommitObservable) .WithSubscription(x => actionMenuService.SendToPasteBoard(this.Commit.Sha)); var shareCommand = ReactiveCommand.Create(validCommitObservable) .WithSubscription(sender => actionMenuService.ShareUrl(sender, this.Commit.HtmlUrl)); var browseCodeCommand = ReactiveCommand.Create(validCommitObservable) .WithSubscription(x => { var vm = this.CreateViewModel<SourceTreeViewModel>(); vm.RepositoryName = RepositoryName; vm.RepositoryOwner = RepositoryOwner; vm.Branch = this.Commit.Sha; NavigateTo(vm); }); ShowMenuCommand = ReactiveCommand.CreateAsyncTask(sender => { var menu = actionMenuService.Create(); menu.AddButton("Add Comment", AddCommentCommand); menu.AddButton("Copy SHA", copyShaCommand); menu.AddButton("Browse Code", browseCodeCommand); menu.AddButton("Share", shareCommand); menu.AddButton("Show in GitHub", GoToHtmlUrlCommand); return menu.Show(sender); }); LoadCommand = ReactiveCommand.CreateAsyncTask(async t => { var commentRequest = applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Commits[Node].Comments.GetAll(); applicationService.Client.ExecuteAsync(commentRequest).ToBackground(x => comments.Reset(x.Data.Where(y => y.Position.HasValue))); Commit = await applicationService.GitHubClient.Repository.Commits.Get(RepositoryOwner, RepositoryName, Node); }); }
protected BaseIssueViewModel( ISessionService applicationService, IMarkdownService markdownService, IActionMenuFactory actionMenuFactory, IAlertDialogFactory alertDialogFactory) { _applicationService = applicationService; _markdownService = markdownService; _alertDialogFactory = alertDialogFactory; _assigneesCache = new Lazy<Task<IReadOnlyList<Octokit.User>>>(() => _applicationService.GitHubClient.Issue.Assignee.GetAllForRepository(RepositoryOwner, RepositoryName)); _milestonesCache = new Lazy<Task<IReadOnlyList<Octokit.Milestone>>>(() => _applicationService.GitHubClient.Issue.Milestone.GetAllForRepository(RepositoryOwner, RepositoryName)); _labelsCache = new Lazy<Task<IReadOnlyList<Octokit.Label>>>(() => _applicationService.GitHubClient.Issue.Labels.GetAllForRepository(RepositoryOwner, RepositoryName)); IssueUpdated.Subscribe(x => Issue = x); var issuePresenceObservable = this.WhenAnyValue(x => x.Issue, x => x.CanModify) .Select(x => x.Item1 != null && x.Item2); Events = InternalEvents.CreateDerivedCollection(x => x); this.WhenAnyValue(x => x.Issue.Comments) .ToProperty(this, x => x.CommentCount, out _commentsCount); _participants = Events.Changed .Select(_ => Events.Select(y => y.Actor).Distinct().Count()) .Select(x => x == 0 ? 1 : x) .ToProperty(this, x => x.Participants); GoToAssigneesCommand = ReactiveCommand.Create(issuePresenceObservable); GoToLabelsCommand = ReactiveCommand.Create(issuePresenceObservable); GoToMilestonesCommand = ReactiveCommand.Create(issuePresenceObservable); _assignedUser = this.WhenAnyValue(x => x.Issue.Assignee) .ToProperty(this, x => x.AssignedUser); _assignedMilestone = this.WhenAnyValue(x => x.Issue.Milestone) .ToProperty(this, x => x.AssignedMilestone); _assignedLabels = this.WhenAnyValue(x => x.Issue.Labels) .ToProperty(this, x => x.AssignedLabels); _isClosed = this.WhenAnyValue(x => x.Issue.State) .Select(x => x == Octokit.ItemState.Closed) .ToProperty(this, x => x.IsClosed); _markdownDescription = this.WhenAnyValue(x => x.Issue) .Select(x => ((x == null || string.IsNullOrEmpty(x.Body)) ? null : x.Body)) .Where(x => x != null) .Select(x => GetMarkdownDescription().ToObservable()) .Switch() .ToProperty(this, x => x.MarkdownDescription, null, RxApp.MainThreadScheduler); LoadCommand = ReactiveCommand.CreateAsyncTask(t => Load(applicationService)); GoToOwnerCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Issue).Select(x => x != null)); GoToOwnerCommand .Select(_ => this.CreateViewModel<UserViewModel>()) .Select(x => x.Init(Issue.User.Login)) .Subscribe(NavigateTo); ToggleStateCommand = ReactiveCommand.CreateAsyncTask(issuePresenceObservable, async t => { try { var updatedIssue = await applicationService.GitHubClient.Issue.Update(RepositoryOwner, RepositoryName, Id, new Octokit.IssueUpdate { State = (Issue.State == Octokit.ItemState.Open) ? Octokit.ItemState.Closed : Octokit.ItemState.Open }); _issueUpdatedObservable.OnNext(updatedIssue); } catch (Exception e) { var close = (Issue.State == Octokit.ItemState.Open) ? "close" : "open"; throw new Exception("Unable to " + close + " the item. " + e.Message, e); } RetrieveEvents().ToBackground(x => InternalEvents.Reset(x)); }); AddCommentCommand = ReactiveCommand.Create().WithSubscription(_ => { var vm = new ComposerViewModel(async s => { var request = applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Issues[Id].CreateComment(s); var comment = (await applicationService.Client.ExecuteAsync(request)).Data; InternalEvents.Add(new IssueCommentItemViewModel(comment)); }, alertDialogFactory); NavigateTo(vm); }); ShowMenuCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.Issue).Select(x => x != null), sender => { var menu = actionMenuFactory.Create(); menu.AddButton("Edit", GoToEditCommand); menu.AddButton(Issue.State == Octokit.ItemState.Closed ? "Open" : "Close", ToggleStateCommand); menu.AddButton("Comment", AddCommentCommand); menu.AddButton("Share", ShareCommand); menu.AddButton("Show in GitHub", GoToHtmlUrlCommand); return menu.Show(sender); }); GoToEditCommand = ReactiveCommand.Create().WithSubscription(_ => { var vm = this.CreateViewModel<IssueEditViewModel>(); vm.RepositoryOwner = RepositoryOwner; vm.RepositoryName = RepositoryName; vm.Id = Id; vm.Issue = Issue; vm.SaveCommand.Subscribe(_issueUpdatedObservable.OnNext); NavigateTo(vm); }); GoToUrlCommand = ReactiveCommand.Create(); GoToUrlCommand.OfType<string>().Subscribe(GoToUrl); GoToUrlCommand.OfType<Uri>().Subscribe(x => GoToUrl(x.AbsoluteUri)); var hasHtmlObservable = this.WhenAnyValue(x => x.HtmlUrl).Select(x => x != null); ShareCommand = ReactiveCommand.Create(hasHtmlObservable); ShareCommand.Subscribe(sender => actionMenuFactory.ShareUrl(sender, HtmlUrl)); GoToHtmlUrlCommand = ReactiveCommand.Create(hasHtmlObservable); GoToHtmlUrlCommand.Subscribe(_ => GoToUrl(HtmlUrl.AbsoluteUri)); }
public EnablePushNotificationsViewController(IAlertDialogFactory alertDialogFactory, IFeaturesService featuresService) : base("EnablePushNotificationsViewController", null) { _alertDialogFactory = alertDialogFactory; _featuresService = featuresService; }
public GistViewModel( ISessionService sessionService, IActionMenuFactory actionMenuService, IAlertDialogFactory alertDialogFactory) { Comments = new ReactiveList<GistCommentModel>(); Title = "Gist"; this.WhenAnyValue(x => x.Gist).Where(x => x != null && x.Files != null && x.Files.Count > 0) .Select(x => x.Files.First().Key).Subscribe(x => Title = x); ShareCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Gist).Select(x => x != null)); ShareCommand.Subscribe(sender => actionMenuService.ShareUrl(sender, new Uri(Gist.HtmlUrl))); this.WhenAnyValue(x => x.Gist.Owner.AvatarUrl) .Select(x => new GitHubAvatar(x)) .ToProperty(this, x => x.Avatar, out _avatar); ToggleStarCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.IsStarred).Select(x => x.HasValue), async t => { try { if (!IsStarred.HasValue) return; var request = IsStarred.Value ? sessionService.Client.Gists[Id].Unstar() : sessionService.Client.Gists[Id].Star(); await sessionService.Client.ExecuteAsync(request); IsStarred = !IsStarred.Value; } catch (Exception e) { throw new Exception("Unable to start gist. Please try again.", e); } }); ForkCommand = ReactiveCommand.CreateAsyncTask(async t => { var gist = await sessionService.GitHubClient.Gist.Fork(Id); var vm = this.CreateViewModel<GistViewModel>(); vm.Id = gist.Id; vm.Gist = gist; NavigateTo(vm); }); ForkCommand.IsExecuting.Subscribe(x => { if (x) alertDialogFactory.Show("Forking..."); else alertDialogFactory.Hide(); }); GoToEditCommand = ReactiveCommand.Create(); GoToEditCommand.Subscribe(_ => { var vm = this.CreateViewModel<GistEditViewModel>(); vm.Gist = Gist; vm.SaveCommand.Subscribe(x => Gist = x); NavigateTo(vm); }); GoToHtmlUrlCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Gist).Select(x => x != null && !string.IsNullOrEmpty(x.HtmlUrl))); GoToHtmlUrlCommand .Select(_ => this.CreateViewModel<WebBrowserViewModel>()) .Select(x => x.Init(Gist.HtmlUrl)) .Subscribe(NavigateTo); GoToFileSourceCommand = ReactiveCommand.Create(); GoToFileSourceCommand.OfType<GistFile>().Subscribe(x => { var vm = this.CreateViewModel<GistFileViewModel>(); vm.Id = Id; vm.GistFile = x; vm.Filename = x.Filename; NavigateTo(vm); }); GoToOwnerCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Gist).Select(x => x != null && x.Owner != null)); GoToOwnerCommand .Select(_ => this.CreateViewModel<UserViewModel>()) .Select(x => x.Init(Gist.Owner.Login)) .Subscribe(NavigateTo); AddCommentCommand = ReactiveCommand.Create().WithSubscription(_ => NavigateTo(new ComposerViewModel("Add Comment", async x => { var request = sessionService.Client.Gists[Id].CreateGistComment(x); Comments.Add((await sessionService.Client.ExecuteAsync(request)).Data); }, alertDialogFactory))); ShowMenuCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.Gist).Select(x => x != null), sender => { var menu = actionMenuService.Create(); if (Gist.Owner != null && string.Equals(sessionService.Account.Username, Gist.Owner.Login, StringComparison.OrdinalIgnoreCase)) menu.AddButton("Edit", GoToEditCommand); else menu.AddButton("Fork", ForkCommand); menu.AddButton("Share", ShareCommand); menu.AddButton("Show in GitHub", GoToHtmlUrlCommand); return menu.Show(sender); }); LoadCommand = ReactiveCommand.CreateAsyncTask(async _ => { sessionService.GitHubClient.Gist.IsStarred(Id).ToBackground(x => IsStarred = x); Comments.SimpleCollectionLoad(sessionService.Client.Gists[Id].GetComments()); Gist = await sessionService.GitHubClient.Gist.Get(Id); }); }
public ComposerViewModel(Func<string, Task> saveFunc, IAlertDialogFactory alertDialogFactory) : this("Add Comment", saveFunc, alertDialogFactory) { }