Exemple #1
0
        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()));
        }
Exemple #8
0
 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;
        }
Exemple #10
0
        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()));
        }
Exemple #12
0
        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()));
        }
Exemple #13
0
        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());
        }
Exemple #14
0
        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());
        }
Exemple #15
0
        public GistCreateViewModel(ISessionService sessionService, IAlertDialogFactory alertDialogFactory)
        {
            _sessionService = sessionService;
            _alertDialogFactory = alertDialogFactory;

            Title = "Create Gist";
            IsPublic = true;
        }
Exemple #16
0
 protected IssueModifyViewModel(IAlertDialogFactory alertDialogFactory)
 {
     SaveCommand = ReactiveCommand.CreateAsyncTask(async _ => {
         using (alertDialogFactory.Activate("Saving..."))
             await Save();
         Dismiss();
     });
 }
Exemple #17
0
        public GistCreateViewModel(ISessionService sessionService, IAlertDialogFactory alertDialogFactory)
        {
            _sessionService     = sessionService;
            _alertDialogFactory = alertDialogFactory;

            Title    = "Create Gist";
            IsPublic = true;
        }
Exemple #18
0
 public IssueAddViewModel(
     IApplicationService applicationService,
     IAlertDialogFactory statusIndicatorService)
     : base(applicationService, statusIndicatorService)
 {
     _applicationService = applicationService;
     Title = "New Issue";
 }
Exemple #19
0
 public IssueAddViewModel(
     ISessionService applicationService, 
     IAlertDialogFactory alertDialogService)
     : base(applicationService, alertDialogService)
 {
     _sessionService = applicationService;
     _alertDialogFactory = alertDialogService;
     Title = "New Issue";
 }
Exemple #20
0
        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));
            })));
        }
Exemple #23
0
 public IssueAddViewModel(
     ISessionService applicationService, 
     IAlertDialogFactory alertDialogService)
     : base(applicationService, alertDialogService)
 {
     _applicationService = applicationService;
     _alertDialogFactory = alertDialogService;
     Title = "New Issue";
 }
Exemple #24
0
 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());
 }
Exemple #25
0
 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());
 }
Exemple #26
0
        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);
        }
Exemple #28
0
        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()));
        }
Exemple #29
0
        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));
        }
Exemple #31
0
 public static IDisposable Activate(this IAlertDialogFactory @this, IObservable <bool> observable, string text)
 {
     return(observable.Subscribe(x => {
         if (x)
         {
             @this.Show(text);
         }
         else
         {
             @this.Hide();
         }
     }));
 }
Exemple #32
0
 public static IDisposable Activate(this IAlertDialogFactory @this, IReactiveCommand command, string text)
 {
     return(command.IsExecuting.Subscribe(x => {
         if (x)
         {
             @this.Show(text);
         }
         else
         {
             @this.Hide();
         }
     }));
 }
Exemple #33
0
 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());
 }
Exemple #34
0
 public static IDisposable AlertExecuting(this IReactiveCommand @this, IAlertDialogFactory dialogFactory, string text)
 {
     return(@this.IsExecuting.Subscribe(x => {
         if (x)
         {
             dialogFactory.Show(text);
         }
         else
         {
             dialogFactory.Hide();
         }
     }));
 }
Exemple #35
0
        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());
        }
Exemple #37
0
        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);
        }
Exemple #38
0
        public StartupViewModel(
            ISessionService sessionService, 
            IAccountsRepository accountsService, 
            IAlertDialogFactory alertDialogFactory,
            IDefaultValueService defaultValueService)
        {
            _sessionService = sessionService;
            _accountsService = accountsService;
            _alertDialogFactory = alertDialogFactory;
            _defaultValueService = defaultValueService;

            StartupCommand = ReactiveCommand.CreateAsyncTask(x => Load());
        }
Exemple #39
0
        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);
        }
Exemple #41
0
        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));
	        });
	    }
Exemple #43
0
        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()));
        }
Exemple #45
0
        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()));
        }
Exemple #46
0
        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());
        }
Exemple #50
0
        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();
            });
        }
Exemple #51
0
        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);
        }
Exemple #52
0
        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);
            });
        }
Exemple #54
0
        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;
 }
Exemple #57
0
        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);
            });
        }
Exemple #58
0
 public ComposerViewModel(Func<string, Task> saveFunc, IAlertDialogFactory alertDialogFactory) 
     : this("Add Comment", saveFunc, alertDialogFactory)
 {
 }