예제 #1
0
		public void RenderIssue()
		{
			if (ViewModel.Issue == null)
				return;

            var avatar = new Avatar(ViewModel.Issue.ReportedBy?.Avatar);

			NavigationItem.RightBarButtonItem.Enabled = true;
            HeaderView.Text = ViewModel.Issue.Title;
            HeaderView.SetImage(avatar.ToUrl(), Images.Avatar);
            HeaderView.SubText = ViewModel.Issue.Content ?? "Updated " + ViewModel.Issue.UtcLastUpdated.Humanize();
            RefreshHeaderView();

            var split = new SplitButtonElement();
            split.AddButton("Comments", ViewModel.Comments.Items.Count.ToString());
            split.AddButton("Watches", ViewModel.Issue.FollowerCount.ToString());

            var root = new RootElement(Title);
            root.Add(new Section { split });

			var secDetails = new Section();

			if (!string.IsNullOrEmpty(ViewModel.Issue.Content))
			{
                _descriptionElement.LoadContent(new MarkdownRazorView { Model = ViewModel.Issue.Content }.GenerateString());
				secDetails.Add(_descriptionElement);
			}

            _split1.Button1.Text = ViewModel.Issue.Status;
            _split1.Button2.Text = ViewModel.Issue.Priority;
            secDetails.Add(_split1);

            _split2.Button1.Text = ViewModel.Issue.Metadata.Kind;
            _split2.Button2.Text = ViewModel.Issue.Metadata.Component ?? "No Component";
			secDetails.Add(_split2);

            _split3.Button1.Text = ViewModel.Issue.Metadata.Version ?? "No Version";
            _split3.Button2.Text = ViewModel.Issue.Metadata.Milestone ?? "No Milestone";
            secDetails.Add(_split3);

			var assigneeElement = new StyledStringElement("Assigned", ViewModel.Issue.Responsible != null ? ViewModel.Issue.Responsible.Username : "******", UITableViewCellStyle.Value1) {
                Image = AtlassianIcon.User.ToImage(),
				Accessory = UITableViewCellAccessory.DisclosureIndicator
			};
			assigneeElement.Tapped += () => ViewModel.GoToAssigneeCommand.Execute(null);
			secDetails.Add(assigneeElement);

			root.Add(secDetails);

            if (ViewModel.Comments.Any(x => !string.IsNullOrEmpty(x.Content)))
			{
				root.Add(new Section { _commentsElement });
			}

            var addComment = new StyledStringElement("Add Comment") { Image = AtlassianIcon.Addcomment.ToImage() };
			addComment.Tapped += AddCommentTapped;
			root.Add(new Section { addComment });
			Root = root;
		}
예제 #2
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            _splitButton1 = _split.AddButton("Comments", "-");
            _splitButton2 = _split.AddButton("Participants", "-");

            Title = "Issue #" + ViewModel.Id;
            HeaderView.SetImage(null, Images.Avatar);
            HeaderView.Text = Title;

            Appeared.Take(1)
            .Select(_ => Observable.Timer(TimeSpan.FromSeconds(0.2f)))
            .Switch()
            .ObserveOn(RxApp.MainThreadScheduler)
            .Select(_ => ViewModel.Bind(x => x.IsClosed, true).Where(x => x.HasValue).Select(x => x.Value))
            .Switch()
            .Subscribe(x =>
            {
                HeaderView.SubImageView.TintColor = x ? UIColor.FromRGB(0xbd, 0x2c, 0) : UIColor.FromRGB(0x6c, 0xc6, 0x44);
                HeaderView.SetSubImage((x ? Octicon.IssueClosed :Octicon.IssueOpened).ToImage());
            });

            _milestoneElement = new StringElement("Milestone", "No Milestone", UITableViewCellStyle.Value1)
            {
                Image = Octicon.Milestone.ToImage()
            };
            _assigneeElement = new StringElement("Assigned", "Unassigned", UITableViewCellStyle.Value1)
            {
                Image = Octicon.Person.ToImage()
            };
            _labelsElement = new StringElement("Labels", "None", UITableViewCellStyle.Value1)
            {
                Image = Octicon.Tag.ToImage()
            };
            _addCommentElement = new StringElement("Add Comment")
            {
                Image = Octicon.Pencil.ToImage()
            };

            var actionButton = new UIBarButtonItem(UIBarButtonSystemItem.Action)
            {
                Enabled = false
            };

            NavigationItem.RightBarButtonItem = actionButton;

            ViewModel.Bind(x => x.IsModifying).SubscribeStatus("Loading...");

            ViewModel.Bind(x => x.Issue).Subscribe(x =>
            {
                _assigneeElement.Value  = x.Assignee != null ? x.Assignee.Login : "******";
                _milestoneElement.Value = x.Milestone != null ? x.Milestone.Title : "No Milestone";
                _labelsElement.Value    = x.Labels.Count == 0 ? "None" : string.Join(", ", x.Labels.Select(i => i.Name));

                var model    = new MarkdownModel(ViewModel.MarkdownDescription, (int)UIFont.PreferredSubheadline.PointSize, true);
                var markdown = new MarkdownWebView {
                    Model = model
                };
                var html = markdown.GenerateString();
                _descriptionElement.SetValue(string.IsNullOrEmpty(ViewModel.MarkdownDescription) ? null : html);

                HeaderView.Text    = x.Title;
                HeaderView.SubText = "Updated " + x.UpdatedAt.Humanize();
                HeaderView.SetImage(x.User?.AvatarUrl, Images.Avatar);
                RefreshHeaderView();

                Render();
            });

            ViewModel.BindCollection(x => x.Comments).Subscribe(_ => RenderComments());
            ViewModel.BindCollection(x => x.Events).Subscribe(_ => RenderComments());
            ViewModel.Bind(x => x.ShouldShowPro).Subscribe(x => {
                if (x)
                {
                    this.ShowPrivateView();
                }
            });

            OnActivation(d =>
            {
                d(_milestoneElement.Clicked.BindCommand(ViewModel.GoToMilestoneCommand));
                d(_assigneeElement.Clicked.BindCommand(ViewModel.GoToAssigneeCommand));
                d(_labelsElement.Clicked.BindCommand(ViewModel.GoToLabelsCommand));
                d(_addCommentElement.Clicked.Subscribe(_ => AddCommentTapped()));
                d(_descriptionElement.UrlRequested.BindCommand(ViewModel.GoToUrlCommand));
                d(_commentsElement.UrlRequested.BindCommand(ViewModel.GoToUrlCommand));
                d(actionButton.GetClickedObservable().Subscribe(ShowExtraMenu));
                d(HeaderView.Clicked.BindCommand(ViewModel.GoToOwner));

                d(ViewModel.Bind(x => x.IsCollaborator, true).Subscribe(x => {
                    foreach (var i in new [] { _assigneeElement, _milestoneElement, _labelsElement })
                    {
                        i.Accessory = x ? UITableViewCellAccessory.DisclosureIndicator : UITableViewCellAccessory.None;
                    }
                }));

                d(ViewModel.Bind(x => x.IsLoading).Subscribe(x => actionButton.Enabled = !x));
            });
        }
예제 #3
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            Title = "Gist";

            var editButton = NavigationItem.RightBarButtonItem = new UIBarButtonItem(UIBarButtonSystemItem.Action);

            HeaderView.SetImage(null, Images.Avatar);
            HeaderView.Text = "Gist #" + ViewModel.Id;
            HeaderView.SubImageView.TintColor = UIColor.FromRGB(243, 156, 18);

            Appeared.Take(1)
            .Select(_ => Observable.Timer(TimeSpan.FromSeconds(0.35f)).Take(1))
            .Switch()
            .Select(_ => ViewModel.Bind(x => x.IsStarred, true))
            .Switch()
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(x => HeaderView.SetSubImage(x ? Octicon.Star.ToImage() : null));

            TableView.RowHeight          = UITableView.AutomaticDimension;
            TableView.EstimatedRowHeight = 44f;

            _split = new SplitButtonElement();
            var files    = _split.AddButton("Files", "-");
            var comments = _split.AddButton("Comments", "-");
            var forks    = _split.AddButton("Forks", "-");

            _splitRow1    = new SplitViewElement(Octicon.Lock.ToImage(), Octicon.Package.ToImage());
            _splitRow2    = new SplitViewElement(Octicon.Calendar.ToImage(), Octicon.Star.ToImage());
            _ownerElement = new StringElement("Owner", string.Empty, UITableViewCellStyle.Value1)
            {
                Image     = Octicon.Person.ToImage(),
                Accessory = UITableViewCellAccessory.DisclosureIndicator
            };

            OnActivation(d =>
            {
                d(editButton.GetClickedObservable().Subscribe(_ => ShareButtonTap(editButton)));
                d(_ownerElement.Clicked.BindCommand(ViewModel.GoToUserCommand));

                d(ViewModel.Bind(x => x.IsStarred, true).Subscribe(isStarred => _splitRow2.Button2.Text = isStarred ? "Starred" : "Not Starred"));

                d(ViewModel.BindCollection(x => x.Comments, true).Subscribe(_ => RenderGist()));
                d(HeaderView.Clicked.BindCommand(ViewModel.GoToUserCommand));

                d(ViewModel.Bind(x => x.Gist, true).Where(x => x != null).Subscribe(gist =>
                {
                    var daysOld = gist.CreatedAt.TotalDaysAgo();

                    _splitRow1.Button1.Text = gist.Public ? "Public" : "Private";
                    _splitRow1.Button2.Text = (gist.History?.Count ?? 0) + " Revisions";
                    _splitRow2.Button1.Text = daysOld == 0 ? "Created today" : "day".ToQuantity(daysOld) + " old";
                    _ownerElement.Value     = gist.Owner?.Login ?? "Unknown";
                    files.Text         = gist.Files?.Count.ToString() ?? "-";
                    comments.Text      = gist.Comments.ToString();
                    forks.Text         = gist.Forks?.Count.ToString() ?? "-";
                    HeaderView.SubText = gist.Description;
                    HeaderView.Text    = gist.Files?.Select(x => x.Key).FirstOrDefault() ?? HeaderView.Text;
                    HeaderView.SetImage(gist.Owner?.AvatarUrl, Images.Avatar);
                    RenderGist();
                    RefreshHeaderView();
                }));
            });
        }
예제 #4
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            var split        = new SplitButtonElement();
            var contributors = split.AddButton("Contributors", "-");
            var lastCommit   = split.AddButton("Last Commit", "-");

            var addFeatureButton = new BigButtonElement("Suggest a feature", Octicon.LightBulb);
            var addBugButton     = new BigButtonElement("Report a bug", Octicon.Bug);
            var featuresButton   = new BigButtonElement("Submitted Work Items", Octicon.Clippy);

            HeaderView.SubText = "This app is the product of hard work and great suggestions! Thank you to all whom provide feedback!";
            HeaderView.Image   = UIImage.FromBundle("AppIcons60x60");

            NavigationItem.BackBarButtonItem = new UIBarButtonItem {
                Title = ""
            };

            Root.Reset(
                new Section {
                split
            },
                new Section {
                addFeatureButton, addBugButton
            },
                new Section {
                featuresButton
            });

            OnActivation(d =>
            {
                d(addFeatureButton.Clicked
                  .Select(_ => FeedbackComposerViewController.CreateAsFeature())
                  .Select(viewCtrl => new ThemedNavigationController(viewCtrl))
                  .Subscribe(viewCtrl => PresentViewController(viewCtrl, true, null)));

                d(addBugButton.Clicked
                  .Select(_ => FeedbackComposerViewController.CreateAsBug())
                  .Select(viewCtrl => new ThemedNavigationController(viewCtrl))
                  .Subscribe(viewCtrl => PresentViewController(viewCtrl, true, null)));

                d(this.WhenAnyValue(x => x.ViewModel.Title)
                  .Subscribe(title => Title = title));

                d(featuresButton.Clicked
                  .Subscribe(_ => this.PushViewController(new FeedbackViewController())));

                d(HeaderView.Clicked.Subscribe(_ => GoToRepository()));

                d(this.WhenAnyValue(x => x.ViewModel.Contributors)
                  .Where(x => x.HasValue)
                  .Subscribe(x => contributors.Text = (x.Value >= 100 ? "100+" : x.Value.ToString())));

                d(this.WhenAnyValue(x => x.ViewModel.LastCommit)
                  .Where(x => x.HasValue)
                  .Subscribe(x => lastCommit.Text = x.Value.UtcDateTime.Humanize()));
            });

            Appearing
            .Take(1)
            .Select(_ => Unit.Default)
            .InvokeReactiveCommand(ViewModel.LoadCommand);
        }
예제 #5
0
        public void RenderIssue()
        {
            if (ViewModel.Issue == null)
            {
                return;
            }

            var avatar = new Avatar(ViewModel.Issue.ReportedBy?.Avatar);

            NavigationItem.RightBarButtonItem.Enabled = true;
            HeaderView.Text = ViewModel.Issue.Title;
            HeaderView.SetImage(avatar.ToUrl(), Images.Avatar);
            HeaderView.SubText = ViewModel.Issue.Content ?? "Updated " + ViewModel.Issue.UtcLastUpdated.Humanize();
            RefreshHeaderView();

            var split = new SplitButtonElement();

            split.AddButton("Comments", ViewModel.Comments.Items.Count.ToString());
            split.AddButton("Watches", ViewModel.Issue.FollowerCount.ToString());

            var root = new RootElement(Title);

            root.Add(new Section {
                split
            });

            var secDetails = new Section();

            if (!string.IsNullOrEmpty(ViewModel.Issue.Content))
            {
                _descriptionElement.LoadContent(new MarkdownRazorView {
                    Model = ViewModel.Issue.Content
                }.GenerateString());
                secDetails.Add(_descriptionElement);
            }

            _split1.Button1.Text = ViewModel.Issue.Status;
            _split1.Button2.Text = ViewModel.Issue.Priority;
            secDetails.Add(_split1);

            _split2.Button1.Text = ViewModel.Issue.Metadata.Kind;
            _split2.Button2.Text = ViewModel.Issue.Metadata.Component ?? "No Component";
            secDetails.Add(_split2);

            _split3.Button1.Text = ViewModel.Issue.Metadata.Version ?? "No Version";
            _split3.Button2.Text = ViewModel.Issue.Metadata.Milestone ?? "No Milestone";
            secDetails.Add(_split3);

            var assigneeElement = new StyledStringElement("Assigned", ViewModel.Issue.Responsible != null ? ViewModel.Issue.Responsible.Username : "******", UITableViewCellStyle.Value1)
            {
                Image     = AtlassianIcon.User.ToImage(),
                Accessory = UITableViewCellAccessory.DisclosureIndicator
            };

            assigneeElement.Tapped += () => ViewModel.GoToAssigneeCommand.Execute(null);
            secDetails.Add(assigneeElement);

            root.Add(secDetails);

            if (ViewModel.Comments.Any(x => !string.IsNullOrEmpty(x.Content)))
            {
                root.Add(new Section {
                    _commentsElement
                });
            }

            var addComment = new StyledStringElement("Add Comment")
            {
                Image = AtlassianIcon.Addcomment.ToImage()
            };

            addComment.Tapped += AddCommentTapped;
            root.Add(new Section {
                addComment
            });
            Root = root;
        }
예제 #6
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            NavigationItem.RightBarButtonItem = new UIBarButtonItem(UIBarButtonSystemItem.Action, (s, e) => ShowExtraMenu());
            NavigationItem.RightBarButtonItem.EnableIfExecutable(ViewModel.WhenAnyValue(x => x.Commit).Select(x => x != null));

            _split = new SplitButtonElement();
            var additions = _split.AddButton("Additions", "-");
            var deletions = _split.AddButton("Deletions", "-");
            var parents   = _split.AddButton("Parents", "-");

            var commentsElement = new WebElement("comments");

            commentsElement.UrlRequested = ViewModel.GoToUrlCommand.ExecuteIfCan;
            //commentsSection.Add(commentsElement);

            var headerSection = new Section(HeaderView)
            {
                _split
            };

            Root.Reset(headerSection);

            ViewModel.WhenAnyValue(x => x.Commit).IsNotNull().SubscribeSafe(x =>
            {
                HeaderView.Image = Images.LoginUserUnknown;

                if (x.Author != null)
                {
                    HeaderView.ImageUri = x.Author.AvatarUrl;
                }

                var msg         = x.Commit.Message ?? string.Empty;
                var firstLine   = msg.IndexOf("\n", StringComparison.Ordinal);
                HeaderView.Text = firstLine > 0 ? msg.Substring(0, firstLine) : msg;

                HeaderView.SubText = "Commited " + (x.Commit.Committer.Date).ToDaysAgo();

                additions.Text = x.Stats.Additions.ToString();
                deletions.Text = x.Stats.Deletions.ToString();
                parents.Text   = x.Parents.Count.ToString();

                ReloadData();
            });

            ViewModel.WhenAnyValue(x => x.Commit).Where(x => x != null).Subscribe(Render);

            ViewModel.Comments.Changed
            .Select(_ => new Unit())
            .StartWith(new Unit())
            .Subscribe(x =>
            {
                var commentModels = ViewModel.Comments.Select(c =>
                                                              new Comment(c.User.AvatarUrl, c.User.Login, c.BodyHtml, c.CreatedAt.ToDaysAgo()));
                var razorView = new CommentsView {
                    Model = commentModels
                };
                var html = razorView.GenerateString();
                commentsElement.Value = html;

                if (commentsElement.GetRootElement() == null && ViewModel.Comments.Count > 0)
                {
                    _commentSection.Add(commentsElement);
                }
            });
        }
예제 #7
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            var split        = new SplitButtonElement();
            var contributors = split.AddButton("Contributors", "-");
            var lastCommit   = split.AddButton("Last Commit", "-");

            var openIssue  = new BigButtonElement("Open an Issue on GitHub", Octicon.Bug);
            var sendEmail  = new BigButtonElement("Email Support", Octicon.Mail);
            var openIssues = new BigButtonElement("Existing Issues", Octicon.IssueOpened);

            HeaderView.SubText = "This app is the product of hard work and great suggestions! Thank you to all whom provide feedback!";
            HeaderView.Image   = UIImage.FromBundle("AppIcons60x60");

            NavigationItem.BackBarButtonItem = new UIBarButtonItem {
                Title = ""
            };

            Root.Reset(
                new Section {
                split
            },
                new Section(null, "Opening an issue on the GitHub project page is the fastest way to get a response.")
            {
                openIssue, openIssues
            },
                new Section(),
                new Section(null, "Emails are answered as quickly as possible but there is only one person answering them so expect a delay.")
            {
                sendEmail
            });

            OnActivation(d =>
            {
                d(openIssue.Clicked
                  .Select(_ => new FeedbackComposerViewController())
                  .Select(viewCtrl => new ThemedNavigationController(viewCtrl))
                  .Subscribe(viewCtrl => PresentViewController(viewCtrl, true, null)));

                d(sendEmail.Clicked.Subscribe(_ => SendEmail()));

                d(this.WhenAnyValue(x => x.ViewModel.Title)
                  .Subscribe(title => Title = title));

                d(openIssues.Clicked
                  .Subscribe(_ => this.PushViewController(new FeedbackViewController())));

                d(HeaderView.Clicked.Subscribe(_ => GoToRepository()));

                d(this.WhenAnyValue(x => x.ViewModel.Contributors)
                  .Where(x => x.HasValue)
                  .Subscribe(x => contributors.Text = (x.Value >= 100 ? "100+" : x.Value.ToString())));

                d(this.WhenAnyValue(x => x.ViewModel.LastCommit)
                  .Where(x => x.HasValue)
                  .Subscribe(x => lastCommit.Text = x.Value.UtcDateTime.Humanize()));
            });

            Appearing
            .Take(1)
            .Select(_ => Unit.Default)
            .InvokeReactiveCommand(ViewModel.LoadCommand);
        }
예제 #8
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            NavigationItem.RightBarButtonItem = new UIBarButtonItem(UIBarButtonSystemItem.Action, (s, e) => ShowMenu());
            NavigationItem.RightBarButtonItem.EnableIfExecutable(
                ViewModel.WhenAnyValue(x => x.Repository, x => x.IsStarred, x => x.IsWatched)
                .Select(x => x.Item1 != null && x.Item2 != null && x.Item3 != null));

            _split = new SplitButtonElement();
            var stargazers = _split.AddButton("Stargazers", "-", () => ViewModel.GoToStargazersCommand.ExecuteIfCan());
            var watchers   = _split.AddButton("Watchers", "-", () => ViewModel.GoToWatchersCommand.ExecuteIfCan());
            var forks      = _split.AddButton("Forks", "-", () => ViewModel.GoToForksCommand.ExecuteIfCan());

            Root.Reset(new Section(HeaderView)
            {
                _split
            });

            // Not very efficient but it'll work for now.
            ViewModel.WhenAnyValue(x => x.Readme).IsNotNull()
            .Select(_ => ViewModel.Repository).IsNotNull().Subscribe(_ => Render());

            _splitElements[0]         = new SplitElement();
            _splitElements[0].Button1 = new SplitElement.SplitButton(Images.Locked, string.Empty);
            _splitElements[0].Button2 = new SplitElement.SplitButton(Images.Language, string.Empty);

            _splitElements[1]         = new SplitElement();
            _splitElements[1].Button1 = new SplitElement.SplitButton(Images.Flag, string.Empty, () => ViewModel.GoToIssuesCommand.ExecuteIfCan());
            _splitElements[1].Button2 = new SplitElement.SplitButton(Images.Team, string.Empty, () => ViewModel.GoToContributors.ExecuteIfCan());

            _splitElements[2]         = new SplitElement();
            _splitElements[2].Button1 = new SplitElement.SplitButton(Images.Tag, string.Empty, () => ViewModel.GoToReleasesCommand.ExecuteIfCan());
            _splitElements[2].Button2 = new SplitElement.SplitButton(Images.Branch, string.Empty, () => ViewModel.GoToBranchesCommand.ExecuteIfCan());

            ViewModel.WhenAnyValue(x => x.Repository).Where(x => x != null).Subscribe(x =>
            {
                HeaderView.ImageUri = x.Owner.AvatarUrl;
                HeaderView.SubText  = x.Description;
                stargazers.Text     = x.StargazersCount.ToString();
                watchers.Text       = x.SubscribersCount.ToString();
                forks.Text          = x.ForksCount.ToString();

                _splitElements[0].Button1.Image = x.Private ? Images.Locked : Images.Unlocked;
                _splitElements[0].Button1.Text  = x.Private ? "Private" : "Public";
                _splitElements[0].Button2.Text  = x.Language ?? "N/A";
                _splitElements[1].Button1.Text  = x.OpenIssues + (x.OpenIssues == 1 ? " Issue" : " Issues");

                Render();
            });

            ViewModel.WhenAnyValue(x => x.Contributors).Where(x => x.HasValue).SubscribeSafe(x =>
                                                                                             _splitElements[1].Button2.Text = (x >= 100 ? "100+" : x.ToString()) + (x == 1 ? " Contributor" : " Contributors"));

            ViewModel.WhenAnyValue(x => x.Branches).Where(x => x != null).SubscribeSafe(x =>
                                                                                        _splitElements[2].Button2.Text = (x.Count >= 100 ? "100+" : x.Count.ToString()) + (x.Count == 1 ? " Branch" : " Branches"));

            ViewModel.WhenAnyValue(x => x.Releases).Where(x => x.HasValue).SubscribeSafe(x =>
                                                                                         _splitElements[2].Button1.Text = (x >= 100 ? "100+" : x.ToString()) + (x == 1 ? " Release" : " Releases"));

            ViewModel.WhenAnyValue(x => x.RepositoryName).Subscribe(x => HeaderView.Text = x);
        }
예제 #9
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            if (HeaderView != null)
            {
                HeaderView.Text = ViewModel.Username;
            }
            if (SlideUpTitle != null)
            {
                SlideUpTitle.Text = ViewModel.Username;
            }

            HeaderView.Text         = ViewModel.Username;
            HeaderView.TextColor    = UIColor.White;
            HeaderView.SubTextColor = UIColor.FromWhiteAlpha(0.9f, 1.0f);

            NavigationItem.RightBarButtonItem = new UIBarButtonItem(Images.Gear, UIBarButtonItemStyle.Plain,
                                                                    (s, e) => ViewModel.GoToSettingsCommand.ExecuteIfCan());

            ViewModel.WhenAnyValue(x => x.CanPurchase).Subscribe(x =>
            {
                if (x)
                {
                    NavigationItem.LeftBarButtonItem = new UIBarButtonItem("Upgrade", UIBarButtonItemStyle.Plain,
                                                                           (s, e) => ViewModel.GoToPurchaseCommand.ExecuteIfCan());
                }
                else
                {
                    NavigationItem.LeftBarButtonItem = null;
                }
            });

            ViewModel.WhenAnyValue(x => x.User).Where(x => x != null).Subscribe(x =>
            {
                HeaderView.ImageUri = x.AvatarUrl;
                HeaderView.SubText  = x.Name;
                ReloadData();
            });

            var split     = new SplitButtonElement();
            var likes     = split.AddButton("Likes", "-", () => ViewModel.GoToLikesCommand.ExecuteIfCan());
            var dislikes  = split.AddButton("Dislikes", "-", () => ViewModel.GoToDislikesCommand.ExecuteIfCan());
            var interests = split.AddButton("Interests", "-", () => ViewModel.GoToInterestsCommand.ExecuteIfCan());

            ViewModel.WhenAnyValue(x => x.Likes).Subscribe(x => likes.Text         = x.ToString());
            ViewModel.WhenAnyValue(x => x.Dislikes).Subscribe(x => dislikes.Text   = x.ToString());
            ViewModel.WhenAnyValue(x => x.Interests).Subscribe(x => interests.Text = x.ToString());

            var section = new Section {
                HeaderView = HeaderView
            };

            section.Add(split);

            var section2 = new Section();

            ViewModel.StumbleHistory.Changed.Subscribe(_ =>
            {
                section2.Reset(ViewModel.StumbleHistory.Select(x =>
                                                               new RepositoryElement(x.Owner, x.Name, x.Description, x.ImageUrl,
                                                                                     () => ViewModel.GoToRepositoryCommand.ExecuteIfCan(x))));
            });

            var section3 = new Section();

            ViewModel.WhenAnyValue(x => x.HasMoreHistory).Subscribe(x =>
            {
                if (x)
                {
                    section3.Reset(new [] {
                        new StyledStringElement("See More History", () => ViewModel.GoToHistoryCommand.ExecuteIfCan())
                    });
                }
                else
                {
                    section3.Clear();
                }
            });


            Root.Reset(section, section2, section3);
        }
예제 #10
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            HeaderView.Image = Images.LoginUserUnknown;
            HeaderView.SubImageView.TintColor = UIColor.FromRGB(243, 156, 18);

            var headerSection = new Section();
            var filesSection  = new Section();

            var split    = new SplitButtonElement();
            var files    = split.AddButton("Files", "-");
            var comments = split.AddButton("Comments", "-");
            var forks    = split.AddButton("Forks", "-");

            headerSection.Add(split);

            var commentsSection = new Section()
            {
                FooterView = new TableFooterButton("Add Comment", ViewModel.AddCommentCommand.ExecuteIfCan)
            };
            var commentsElement = new HtmlElement("comments");

            commentsElement.UrlRequested = ViewModel.GoToUrlCommand.ExecuteIfCan;
            commentsSection.Add(commentsElement);

            var detailsSection = new Section {
                _splitRow1, _splitRow2
            };

            Root.Reset(headerSection, detailsSection, filesSection, commentsSection);

            var updatedGistObservable = ViewModel.WhenAnyValue(x => x.Gist).Where(x => x != null);

            ViewModel.WhenAnyValue(x => x.Gist)
            .IsNotNull()
            .Select(x => x.Owner)
            .Subscribe(x =>
            {
                if (x == null)
                {
                    detailsSection.Remove(_ownerElement);
                }
                else if (x != null && !detailsSection.Contains(_ownerElement))
                {
                    detailsSection.Add(_ownerElement);
                }
            });


            updatedGistObservable
            .Select(x => x?.Owner?.Login ?? "Anonymous")
            .Subscribe(x => _ownerElement.Value = x);

            updatedGistObservable
            .Select(x => x.Owner != null ? () => ViewModel.GoToOwnerCommand.ExecuteIfCan() : (Action)null)
            .SubscribeSafe(x => _ownerElement.Tapped = x);

            this.WhenAnyValue(x => x.ViewModel.Avatar)
            .Subscribe(x => HeaderView.SetImage(x?.ToUri(64), Images.LoginUserUnknown));

            updatedGistObservable.SubscribeSafe(x => {
                HeaderView.SubText = x.Description;
                RefreshHeaderView();
            });

            updatedGistObservable.Select(x => x.Files == null ? 0 : x.Files.Count()).SubscribeSafe(x => files.Text = x.ToString());
            updatedGistObservable.SubscribeSafe(x => comments.Text = x.Comments.ToString());
            updatedGistObservable.Select(x => x.Forks == null ? 0 : x.Forks.Count()).SubscribeSafe(x => forks.Text = x.ToString());

            updatedGistObservable.Subscribe(x =>
            {
                var elements = new List <Element>();
                foreach (var file in x.Files.Keys)
                {
                    var sse     = new StringElement(file);
                    sse.Image   = Octicon.FileCode.ToImage();
                    sse.Tapped += () => ViewModel.GoToFileSourceCommand.Execute(x.Files[file]);
                    elements.Add(sse);
                }

                filesSection.Reset(elements);
            });


            ViewModel.Comments.Changed.Subscribe(_ => {
                var commentModels = ViewModel.Comments
                                    .Select(x => {
                    var avatarUrl = x?.User?.AvatarUrl;
                    var avatar    = new GitHubAvatar(avatarUrl);
                    return(new Comment(avatar.ToUri(), x.User.Login, x.BodyHtml, x.CreatedAt.UtcDateTime.Humanize()));
                }).ToList();

                if (commentModels.Count > 0)
                {
                    var model     = new CommentModel(commentModels, (int)UIFont.PreferredSubheadline.PointSize);
                    var razorView = new CommentsView {
                        Model = model
                    };
                    var html = razorView.GenerateString();
                    commentsElement.Value = html;

                    if (!commentsSection.Contains(commentsElement))
                    {
                        commentsSection.Insert(0, UITableViewRowAnimation.Fade, commentsElement);
                    }
                }
                else
                {
                    commentsSection.Remove(commentsElement);
                }
            });
        }
예제 #11
0
        public void Render()
        {
            if (ViewModel.PullRequest == null)
                return;

            var avatarUrl = ViewModel.PullRequest.Author?.Links?.Avatar?.Href;

            HeaderView.Text = ViewModel.PullRequest.Title;
            HeaderView.SubText = "Updated " + ViewModel.PullRequest.UpdatedOn.Humanize();
            HeaderView.SetImage(new Avatar(avatarUrl).ToUrl(128), Images.Avatar);
            RefreshHeaderView();

            var split = new SplitButtonElement();
            split.AddButton("Comments", ViewModel.Comments.Items.Count.ToString());
            split.AddButton("Participants", ViewModel.PullRequest.Participants.Count.ToString());

            var root = new RootElement(Title);
            root.Add(new Section { split });

            var secDetails = new Section();
            if (!string.IsNullOrWhiteSpace(ViewModel.Description))
            {
                if (_descriptionElement == null)
                {
                    _descriptionElement = new WebElement("description");
                    _descriptionElement.UrlRequested = ViewModel.GoToUrlCommand.Execute;
                }

                _descriptionElement.LoadContent(new MarkdownRazorView { Model = ViewModel.Description }.GenerateString());
                secDetails.Add(_descriptionElement);
            }

			var merged = ViewModel.Merged;

            _split1.Button1.Text = ViewModel.PullRequest.CreatedOn.ToString("MM/dd/yy");
            _split1.Button2.Text = merged ? "Merged" : "Not Merged";
            secDetails.Add(_split1);
            secDetails.Add(new StyledStringElement("Commits", () => ViewModel.GoToCommitsCommand.Execute(null), AtlassianIcon.Devtoolscommit.ToImage()));
            root.Add(secDetails);

            if (!merged)
            {
                Action mergeAction = async () =>
                {
                    try
                    {
						await this.DoWorkAsync("Merging...", ViewModel.Merge);
                    }
                    catch (Exception e)
                    {
                        MonoTouch.Utilities.ShowAlert("Unable to Merge", e.Message);
                    }
                };
 
                root.Add(new Section { new StyledStringElement("Merge", mergeAction, AtlassianIcon.Approve.ToImage()) });
            }

            var comments = ViewModel.Comments
                .Where(x => !string.IsNullOrEmpty(x.Content.Raw) && x.Inline == null)
                .OrderBy(x => (x.CreatedOn))
                .Select(x =>
                {
                    var name = x.User.DisplayName ?? x.User.Username ?? "Unknown";
                    var avatar = new Avatar(x.User.Links?.Avatar?.Href);
                    return new CommentViewModel(name, x.Content.Html, x.CreatedOn.Humanize(), avatar.ToUrl());
                }).ToList();

            if (comments.Count > 0)
            {
                if (_commentsElement == null)
                {
                    _commentsElement = new WebElement("comments");
                    _commentsElement.UrlRequested = ViewModel.GoToUrlCommand.Execute;
                }

                _commentsElement.LoadContent(new CommentsRazorView { Model = comments.ToList() }.GenerateString());
                root.Add(new Section { _commentsElement });
            }


            var addComment = new StyledStringElement("Add Comment") { Image = AtlassianIcon.Addcomment.ToImage() };
            addComment.Tapped += AddCommentTapped;
            root.Add(new Section { addComment });
            Root = root;
        }
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            HeaderView.SetImage(null, Images.RepoPlaceholder);

            var actionButton = new UIBarButtonItem(UIBarButtonSystemItem.Action)
            {
                Enabled = false
            };

            NavigationItem.RightBarButtonItem = actionButton;

            var watchers = _split.AddButton("Watchers", "-");
            var forks    = _split.AddButton("Forks", "-");
            var branches = _split.AddButton("Branches", "-");

            _split3.Button2.Text = "- Issues";

            var featuresService = Locator.Current.GetService <IFeaturesService>();

            OnActivation(d =>
            {
                watchers.Clicked
                .BindCommand(ViewModel.GoToStargazersCommand)
                .AddTo(d);

                _commitsButton
                .Clicked
                .SelectUnit()
                .BindCommand(ViewModel.GoToCommitsCommand)
                .AddTo(d);

                _pullRequestsButton
                .Clicked
                .SelectUnit()
                .BindCommand(ViewModel.GoToPullRequestsCommand)
                .AddTo(d);

                _sourceButton
                .Clicked
                .SelectUnit()
                .BindCommand(ViewModel.GoToSourceCommand)
                .AddTo(d);

                branches.Clicked
                .BindCommand(ViewModel.GoToBranchesCommand)
                .AddTo(d);

                this.WhenAnyValue(x => x.ViewModel.BranchesCount)
                .Subscribe(x => branches.Text = x.ToString())
                .AddTo(d);

                this.WhenAnyValue(x => x.ViewModel.Watchers)
                .Subscribe(x => watchers.Text = x?.ToString() ?? "-")
                .AddTo(d);

                this.WhenAnyValue(x => x.ViewModel.Forks)
                .Subscribe(x => forks.Text = x?.ToString() ?? "-")
                .AddTo(d);

                this.WhenAnyValue(x => x.ViewModel.Repository).SelectUnit()
                .Merge(this.WhenAnyValue(x => x.ViewModel.HasReadme).SelectUnit())
                .Where(x => ViewModel.Repository != null)
                .Subscribe(_ => Render())
                .AddTo(d);

                this.WhenAnyValue(x => x.ViewModel.Issues)
                .Select(x => "Issues".ToQuantity(x.GetValueOrDefault()))
                .Subscribe(x => _split3.Button2.Text = x)
                .AddTo(d);

                actionButton
                .Bind(ViewModel.ShowMenuCommand)
                .AddTo(d);

                this.WhenAnyValue(x => x.ViewModel.Repository)
                .Where(x => x != null)
                .Subscribe(x =>
                {
                    if (x.IsPrivate && !featuresService.IsProEnabled)
                    {
                        if (_privateView == null)
                        {
                            _privateView = this.ShowPrivateView();
                        }
                        actionButton.Enabled = false;
                    }
                    else
                    {
                        actionButton.Enabled = true;
                        _privateView?.Dispose();
                    }
                })
                .AddTo(d);
            });
        }
예제 #13
0
        public void Render()
        {
            if (ViewModel.PullRequest == null)
            {
                return;
            }

            var avatarUrl = ViewModel.PullRequest.Author?.Links?.Avatar?.Href;

            HeaderView.Text    = ViewModel.PullRequest.Title;
            HeaderView.SubText = "Updated " + ViewModel.PullRequest.UpdatedOn.Humanize();
            HeaderView.SetImage(new Avatar(avatarUrl).ToUrl(128), Images.Avatar);
            RefreshHeaderView();

            var split = new SplitButtonElement();

            split.AddButton("Comments", ViewModel.Comments.Items.Count.ToString());
            split.AddButton("Participants", ViewModel.PullRequest.Participants.Count.ToString());

            ICollection <Section> root = new LinkedList <Section>();

            root.Add(new Section {
                split
            });

            var secDetails = new Section();

            if (!string.IsNullOrWhiteSpace(ViewModel.Description))
            {
                var content = new MarkdownRazorView {
                    Model = ViewModel.Description
                }.GenerateString();
                _descriptionElement.SetValue(content);
                secDetails.Add(_descriptionElement);
            }

            var commitsElement = new StringElement("Commits", AtlassianIcon.Devtoolscommit.ToImage());

            commitsElement.Clicked.BindCommand(ViewModel.GoToCommitsCommand);

            var merged = ViewModel.Merged;

            _split1.Button1.Text = ViewModel.PullRequest.CreatedOn.ToString("MM/dd/yy");
            _split1.Button2.Text = merged ? "Merged" : "Not Merged";
            secDetails.Add(_split1);
            secDetails.Add(commitsElement);
            root.Add(secDetails);

            if (!merged)
            {
                var mergeElement = new StringElement("Merge", AtlassianIcon.Approve.ToImage());
                mergeElement.Clicked.Subscribe(_ => MergeClick());
                root.Add(new Section {
                    mergeElement
                });
            }

            var comments = ViewModel.Comments
                           .Where(x => !string.IsNullOrEmpty(x.Content.Raw) && x.Inline == null)
                           .OrderBy(x => (x.CreatedOn))
                           .Select(x =>
            {
                var name   = x.User.DisplayName ?? x.User.Username ?? "Unknown";
                var avatar = new Avatar(x.User.Links?.Avatar?.Href);
                return(new CommentViewModel(name, x.Content.Html, x.CreatedOn.Humanize(), avatar.ToUrl()));
            }).ToList();

            if (comments.Count > 0)
            {
                var content = new CommentsRazorView {
                    Model = comments.ToList()
                }.GenerateString();
                _commentsElement.SetValue(content);
                root.Add(new Section {
                    _commentsElement
                });
            }


            var addComment = new StringElement("Add Comment")
            {
                Image = AtlassianIcon.Addcomment.ToImage()
            };

            addComment.Clicked.Subscribe(_ => AddCommentTapped());
            root.Add(new Section {
                addComment
            });
            Root.Reset(root);
        }
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            var split        = new SplitButtonElement();
            var commentCount = split.AddButton("Comments", "-");
            var participants = split.AddButton("Participants", "-");
            var approvals    = split.AddButton("Approvals", "-");

            this.WhenAnyValue(x => x.ViewModel.Title)
            .Subscribe(x => RefreshHeaderView(x));

            ViewModel.WhenAnyValue(x => x.PullRequest).Subscribe(x =>
            {
                if (x != null)
                {
                    var avatarUrl      = x?.Author?.Links?.Avatar?.Href;
                    HeaderView.SubText = "Updated " + ViewModel.PullRequest.UpdatedOn.Humanize();
                    HeaderView.SetImage(new Avatar(avatarUrl).ToUrl(128), Images.Avatar);
                }
                else
                {
                    HeaderView.SetImage(null, Images.Avatar);
                    HeaderView.SubText = null;
                }
            });

            var root = new List <Section>();

            root.Add(new Section {
                split
            });

            var secDetails = new Section();

            root.Add(secDetails);

            this.WhenAnyValue(x => x.ViewModel.Description)
            .Where(x => !string.IsNullOrWhiteSpace(x))
            .Select(x => new DescriptionModel(x, (int)UIFont.PreferredSubheadline.PointSize, true))
            .Select(x => new MarkdownView {
                Model = x
            }.GenerateString())
            .Subscribe(content =>
            {
                _descriptionElement.SetValue(content);
                secDetails.Insert(0, UITableViewRowAnimation.None, _descriptionElement);
            });

            var split1 = new SplitViewElement(AtlassianIcon.Calendar.ToImage(), AtlassianIcon.Devtoolsbranch.ToImage());

            secDetails.Add(split1);

            this.WhenAnyValue(x => x.ViewModel.PullRequest.State)
            .Select(x => x?.ToLower().Humanize(LetterCasing.Title))
            .Subscribe(x => split1.Button2.Text = x ?? "Open");

            this.WhenAnyValue(x => x.ViewModel.PullRequest)
            .Select(x => x?.CreatedOn.ToString("MM/dd/yy"))
            .Subscribe(x => split1.Button1.Text = x);

            var commitsElement = new ButtonElement("Commits", AtlassianIcon.Devtoolscommit.ToImage());

            commitsElement.Clicked.SelectUnit().BindCommand(ViewModel.GoToCommitsCommand);
            secDetails.Add(commitsElement);

            var mergeElement = new ButtonElement("Merge", AtlassianIcon.ListAdd.ToImage());

            mergeElement.Accessory = UITableViewCellAccessory.None;

            var rejectElement = new LoaderButtonElement("Reject", AtlassianIcon.ListRemove.ToImage());

            rejectElement.Accessory = UITableViewCellAccessory.None;
            rejectElement.BindLoader(ViewModel.RejectCommand);

            var mergeSection = new Section {
                mergeElement, rejectElement
            };

            var approvalSection = new Section("Approvals");
            var approveElement  = new LoaderButtonElement("Approve", AtlassianIcon.Approve.ToImage());

            approveElement.Accessory = UITableViewCellAccessory.None;
            approveElement.BindLoader(ViewModel.ToggleApproveButton);
            approveElement.BindCaption(this.WhenAnyValue(x => x.ViewModel.Approved).Select(x => x ? "Unapprove" : "Approve"));
            root.Add(approvalSection);

            this.WhenAnyValue(x => x.ViewModel.Approvals)
            .Select(x => x.Select(y => new UserElement(y)).OfType <Element>())
            .Subscribe(x => approvalSection.Reset(x.Concat(new[] { approveElement })));

            var commentsSection = new Section("Comments");

            root.Add(commentsSection);

            var addComment = new ButtonElement("Add Comment")
            {
                Image = AtlassianIcon.Addcomment.ToImage()
            };

            commentsSection.Reset(new[] { addComment });

            ViewModel
            .Comments
            .ChangedObservable()
            .Subscribe(x =>
            {
                if (x.Count > 0)
                {
                    var comments     = x.Select(y => new Comment(y.Avatar.ToUrl(), y.Name, y.Content, y.CreatedOn)).ToList();
                    var commentModel = new CommentModel(comments, (int)UIFont.PreferredSubheadline.PointSize);
                    var content      = new CommentsView {
                        Model = commentModel
                    }.GenerateString();
                    _commentsElement.SetValue(content);
                    commentsSection.Insert(0, UITableViewRowAnimation.None, _commentsElement);
                }
                else
                {
                    commentsSection.Remove(_commentsElement);
                }
            });

            Root.Reset(root);

            this.WhenAnyValue(x => x.ViewModel.IsOpen).Subscribe(x =>
            {
                if (x)
                {
                    Root.Insert(root.IndexOf(secDetails) + 1, mergeSection);
                }
                else
                {
                    Root.Remove(mergeSection);
                }
            });

            OnActivation(disposable =>
            {
                mergeElement
                .Clicked
                .SelectUnit()
                .BindCommand(this, x => x.ViewModel.MergeCommand)
                .AddTo(disposable);

                addComment
                .Clicked
                .Subscribe(_ => NewCommentViewController.Present(this, ViewModel.AddComment))
                .AddTo(disposable);

                this.WhenAnyValue(x => x.ViewModel.ParticipantCount)
                .Subscribe(x => participants.Text = x?.ToString() ?? "-")
                .AddTo(disposable);

                this.WhenAnyValue(x => x.ViewModel.ApprovalCount)
                .Subscribe(x => approvals.Text = x?.ToString() ?? "-")
                .AddTo(disposable);

                this.WhenAnyValue(x => x.ViewModel.CommentCount)
                .Subscribe(x => commentCount.Text = x?.ToString() ?? "-")
                .AddTo(disposable);

                this.WhenAnyObservable(x => x.ViewModel.MergeCommand)
                .Subscribe(_ =>
                {
                    var vc = new PullRequestApproveViewController(
                        ViewModel.Username, ViewModel.Repository, ViewModel.PullRequestId);
                    vc.DeleteSourceBranch = ViewModel.PullRequest.CloseSourceBranch;
                    vc.MergeCommand
                    .Do(x => ViewModel.PullRequest = x)
                    .Do(x => DismissViewController(true, null))
                    .Subscribe();
                    this.PresentModal(vc);
                })
                .AddTo(disposable);
            });
        }
예제 #15
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            Title = ViewModel.Username;
            HeaderView.SetImage(null, Images.Avatar);
            HeaderView.Text = ViewModel.RepositoryName;
            HeaderView.SubImageView.TintColor = UIColor.FromRGB(243, 156, 18);

            Appeared.Take(1)
            .Select(_ => Observable.Timer(TimeSpan.FromSeconds(0.35f)).Take(1))
            .Switch()
            .Select(_ => ViewModel.Bind(x => x.IsStarred, true).Where(x => x.HasValue))
            .Switch()
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(x => HeaderView.SetSubImage(x.Value ? Octicon.Star.ToImage() : null));

            var actionButton = NavigationItem.RightBarButtonItem = new UIBarButtonItem(UIBarButtonSystemItem.Action)
            {
                Enabled = false
            };

            _split      = new SplitButtonElement();
            _stargazers = _split.AddButton("Stargazers", "-");
            _watchers   = _split.AddButton("Watchers", "-");
            _forks      = _split.AddButton("Forks", "-");

            OnActivation(d =>
            {
                d(_stargazers.Clicked.BindCommand(ViewModel.GoToStargazersCommand));
                d(_watchers.Clicked.BindCommand(ViewModel.GoToWatchersCommand));
                d(_forks.Clicked.BindCommand(ViewModel.GoToForkedCommand));
                d(actionButton.GetClickedObservable().Subscribe(_ => ShowExtraMenu()));

                d(_eventsElement.Clicked.BindCommand(ViewModel.GoToEventsCommand));
                d(_ownerElement.Clicked.BindCommand(ViewModel.GoToOwnerCommand));

                d(_commitsElement.Clicked.BindCommand(ViewModel.GoToCommitsCommand));
                d(_pullRequestsElement.Clicked.BindCommand(ViewModel.GoToPullRequestsCommand));
                d(_sourceElement.Clicked.BindCommand(ViewModel.GoToSourceCommand));

                d(ViewModel.Bind(x => x.Branches, true).Subscribe(_ => Render()));
                d(ViewModel.Bind(x => x.Readme, true).Subscribe(_ => Render()));

                d(_forkElement.Value.Clicked.Select(x => ViewModel.Repository.Parent).BindCommand(ViewModel.GoToForkParentCommand));
                d(_issuesElement.Value.Clicked.BindCommand(ViewModel.GoToIssuesCommand));
                d(_readmeElement.Value.Clicked.BindCommand(ViewModel.GoToReadmeCommand));
                d(_websiteElement.Value.Clicked.Select(x => ViewModel.Repository.Homepage).BindCommand(ViewModel.GoToUrlCommand));

                d(HeaderView.Clicked.BindCommand(ViewModel.GoToOwnerCommand));

                d(ViewModel.Bind(x => x.Repository, true).Where(x => x != null).Subscribe(x =>
                {
                    if (x.Private && !_featuresService.IsProEnabled)
                    {
                        if (_privateView == null)
                        {
                            _privateView = this.ShowPrivateView();
                        }
                        actionButton.Enabled = false;
                    }
                    else
                    {
                        actionButton.Enabled = true;
                        _privateView?.Dispose();
                    }

                    ViewModel.ImageUrl = x.Owner?.AvatarUrl;
                    HeaderView.SubText = Emojis.FindAndReplace(x.Description);
                    HeaderView.SetImage(x.Owner?.AvatarUrl, Images.Avatar);
                    Render();
                    RefreshHeaderView();
                }));
            });
        }
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            NavigationItem.RightBarButtonItem = new UIBarButtonItem(UIBarButtonSystemItem.Action, (s, e) => ShowMore());
            NavigationItem.RightBarButtonItem.EnableIfExecutable(this.WhenAnyValue(x => x.ViewModel)
                                                                 .Where(x => x != null)
                                                                 .Select(x => x.WhenAnyValue(y => y.Repository))
                                                                 .Switch().Select(x => x != null));

            HeaderView.Text         = string.Empty;
            HeaderView.TextColor    = UIColor.White;
            HeaderView.SubTextColor = UIColor.FromWhiteAlpha(0.9f, 1.0f);

            var section = new Section {
                HeaderView = HeaderView
            };
            var section2 = new Section();

            var split         = new SplitButtonElement();
            var stars         = split.AddButton("Stargazers", "-");
            var forks         = split.AddButton("Forks", "-");
            var collaborators = split.AddButton("Contributors", "-");

            section.Add(split);

            this.WhenAnyValue(x => x.ViewModel)
            .Where(x => x != null)
            .Select(x => x.WhenAnyValue(y => y.RepositoryIdentifier).Where(y => y != null))
            .Switch()
            .Subscribe(x =>
            {
                Title = HeaderView.Text = x.Name;
                ReloadData();
            });

            this.WhenAnyValue(x => x.ViewModel)
            .Where(x => x != null)
            .Select(x => x.WhenAnyValue(y => y.ContributorCount))
            .Switch()
            .Subscribe(x => collaborators.Text = x.HasValue ? x.Value.ToString() : "-");

            this.WhenAnyValue(x => x.ViewModel)
            .Where(x => x != null)
            .Select(x => x.WhenAnyValue(y => y.Repository))
            .Switch()
            .Subscribe(x =>
            {
                if (x == null)
                {
                    HeaderView.ImageUri = null;
                    HeaderView.Text     = null;
                    HeaderView.SubText  = null;
                    stars.Text          = "-";
                    forks.Text          = "-";
                }
                else
                {
                    HeaderView.ImageUri = x.Owner.AvatarUrl;
                    HeaderView.Text     = x.Name;
                    HeaderView.SubText  = x.Description;
                    stars.Text          = x.WatchersCount.ToString();
                    forks.Text          = x.ForksCount.ToString();
                }

                ReloadData();
            });

            this.WhenAnyValue(x => x.ViewModel)
            .Where(x => x != null)
            .Select(x => x.WhenAnyValue(y => y.Liked))
            .Switch()
            .Subscribe(x =>
            {
                if (x == null)
                {
                    DislikeButton.Image = Images.ThumbDown;
                    LikeButton.Image    = Images.ThumbUp;
                }
                else if (x.Value)
                {
                    DislikeButton.Image = Images.ThumbDown;
                    LikeButton.Image    = Images.ThumbUpFilled;
                }
                else
                {
                    DislikeButton.Image = Images.ThumbDownFilled;
                    LikeButton.Image    = Images.ThumbUp;
                }
            });

            _webElement = new WebElement("readme");
            _webElement.UrlRequested += (obj) => ViewModel.GoToUrlCommand.ExecuteIfCan(obj);

            ViewModel.WhenAnyValue(y => y.Readme).Where(_ => !_disposed).Subscribe(x =>
            {
                if (x == null)
                {
                    _webElement.ContentPath = null;
                    section2.HeaderView     = new LoadingView();
                    if (_webElement.GetRootElement() != null)
                    {
                        section2.Remove(_webElement);
                    }
                }
                else
                {
                    var view = new ReadmeRazorView {
                        Model = x
                    };
                    var file = System.IO.Path.GetTempFileName() + ".html";
                    using (var stream = new System.IO.StreamWriter(file, false, System.Text.Encoding.UTF8))
                    {
                        view.Generate(stream);
                        _webElement.ContentPath = file;
                    }

                    section2.HeaderView = null;
                    if (_webElement.GetRootElement() == null)
                    {
                        section2.Add(_webElement);
                    }
                }

                ReloadData();
            });

            ViewModel.DismissCommand.Subscribe(_ =>
            {
                _disposed = true;
                _webElement.Dispose();
            });

            Root.Reset(section, section2);

            ToolbarItems = new []
            {
                new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace),
                DislikeButton,
                new UIBarButtonItem(UIBarButtonSystemItem.FixedSpace)
                {
                    Width = 80
                },
                LikeButton,
                new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace),
            };
        }
예제 #17
0
        public RepositoryView()
        {
            HeaderView.Image = Images.LoginUserUnknown;

            _sourceSection = new Section
            {
                new DialogStringElement("Commits", () => ViewModel.GoToCommitsCommand.ExecuteIfCan(), Images.Commit),
                new DialogStringElement("Pull Requests", () => ViewModel.GoToPullRequestsCommand.ExecuteIfCan(), Images.PullRequest),
                new DialogStringElement("Source", () => ViewModel.GoToSourceCommand.ExecuteIfCan(), Images.Code),
            };

            _ownerElement = new StyledStringElement("Owner", string.Empty)
            {
                Image = Images.Person, Accessory = UITableViewCellAccessory.DisclosureIndicator
            };
            _ownerElement.Tapped += () => ViewModel.GoToOwnerCommand.ExecuteIfCan();
            this.WhenAnyValue(x => x.ViewModel.Repository)
            .Subscribe(x => _ownerElement.Value = x == null ? string.Empty : x.Owner.Login);

            HeaderView.SubImageView.TintColor = UIColor.FromRGB(243, 156, 18);
            this.WhenAnyValue(x => x.ViewModel.GoToOwnerCommand).Subscribe(x =>
                                                                           HeaderView.ImageButtonAction = x != null ? new Action(() => ViewModel.GoToOwnerCommand.ExecuteIfCan()) : null);

            _splitElements[0]         = new SplitViewElement();
            _splitElements[0].Button1 = new SplitViewElement.SplitButton(Images.Lock, string.Empty);
            _splitElements[0].Button2 = new SplitViewElement.SplitButton(Images.Package, string.Empty);

            _splitElements[1]         = new SplitViewElement();
            _splitElements[1].Button1 = new SplitViewElement.SplitButton(Images.IssueOpened, string.Empty, () => ViewModel.GoToIssuesCommand.ExecuteIfCan());
            _splitElements[1].Button2 = new SplitViewElement.SplitButton(Images.Organization, string.Empty, () => ViewModel.GoToContributors.ExecuteIfCan());

            _splitElements[2]         = new SplitViewElement();
            _splitElements[2].Button1 = new SplitViewElement.SplitButton(Images.Tag, string.Empty, () => ViewModel.GoToReleasesCommand.ExecuteIfCan());
            _splitElements[2].Button2 = new SplitViewElement.SplitButton(Images.Branch, string.Empty, () => ViewModel.GoToBranchesCommand.ExecuteIfCan());

            var stargazers = _split.AddButton("Stargazers", "-", () => ViewModel.GoToStargazersCommand.ExecuteIfCan());
            var watchers   = _split.AddButton("Watchers", "-", () => ViewModel.GoToWatchersCommand.ExecuteIfCan());
            var forks      = _split.AddButton("Forks", "-", () => ViewModel.GoToForksCommand.ExecuteIfCan());

            this.WhenAnyValue(x => x.ViewModel.Stargazers)
            .Select(x => x != null ? x.ToString() : "-")
            .Subscribe(x => stargazers.Text = x);

            this.WhenAnyValue(x => x.ViewModel.Watchers)
            .Select(x => x != null ? x.ToString() : "-")
            .Subscribe(x => watchers.Text = x);

            this.WhenAnyValue(x => x.ViewModel.Repository.ForksCount)
            .Subscribe(x => forks.Text = x.ToString());

            this.WhenAnyValue(x => x.ViewModel.Repository)
            .IsNotNull()
            .Subscribe(x =>
            {
                _splitElements[0].Button1.Text = x.Private ? "Private" : "Public";
                _splitElements[0].Button2.Text = x.Language ?? "N/A";
                _splitElements[1].Button1.Text = x.OpenIssues + (x.OpenIssues == 1 ? " Issue" : " Issues");
            });

            Appeared.Take(1)
            .Select(_ => Observable.Timer(TimeSpan.FromSeconds(0.35f)))
            .Switch()
            .ObserveOn(RxApp.MainThreadScheduler)
            .Select(_ => this.WhenAnyValue(x => x.ViewModel.IsStarred).Where(x => x.HasValue))
            .Switch()
            .Subscribe(x => HeaderView.SetSubImage(x.Value ? Images.Star.ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate) : null));

            this.WhenAnyValue(x => x.ViewModel.RepositoryName)
            .Subscribe(x => HeaderView.Text = x);

            this.WhenAnyValue(x => x.ViewModel.ShowMenuCommand)
            .Select(x => x.ToBarButtonItem(UIBarButtonSystemItem.Action))
            .Subscribe(x => NavigationItem.RightBarButtonItem = x);

            this.WhenAnyValue(x => x.ViewModel.Branches)
            .SubscribeSafe(x =>
            {
                if (x == null)
                {
                    _splitElements[2].Button2.Text = "- Branches";
                }
                else
                {
                    _splitElements[2].Button2.Text = (x.Count >= 100 ? "100+" : x.Count.ToString()) + (x.Count == 1 ? " Branch" : " Branches");
                }
            });

            this.WhenAnyValue(x => x.ViewModel.Contributors)
            .SubscribeSafe(x =>
            {
                if (x == null)
                {
                    _splitElements[1].Button2.Text = "- Contributors";
                }
                else
                {
                    _splitElements[1].Button2.Text = (x >= 100 ? "100+" : x.ToString()) + (x == 1 ? " Contributor" : " Contributors");
                }
            });


            this.WhenAnyValue(x => x.ViewModel.Releases)
            .SubscribeSafe(x =>
            {
                if (x == null)
                {
                    _splitElements[2].Button1.Text = "- Releases";
                }
                else
                {
                    _splitElements[2].Button1.Text = (x >= 100 ? "100+" : x.ToString()) + (x == 1 ? " Release" : " Releases");
                }
            });
        }
예제 #18
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            var updatedGistObservable = ViewModel.WhenAnyValue(x => x.Gist).Where(x => x != null);

            var headerSection = new Section(HeaderView);
            var filesSection  = new Section("Files");

            var split    = new SplitButtonElement();
            var files    = split.AddButton("Files", "-");
            var comments = split.AddButton("Comments", "-");
            var forks    = split.AddButton("Forks", "-");

            headerSection.Add(split);

            var commentsSection = new Section("Comments");
            var commentsElement = new WebElement("comments");

            commentsElement.UrlRequested = ViewModel.GoToUrlCommand.ExecuteIfCan;
            commentsSection.Add(commentsElement);

            var detailsSection = new Section();
            var splitElement1  = new SplitElement();

            splitElement1.Button1 = new SplitElement.SplitButton(Images.Locked, string.Empty);
            splitElement1.Button2 = new SplitElement.SplitButton(Images.Language, string.Empty);
            detailsSection.Add(splitElement1);

            var splitElement2 = new SplitElement();

            splitElement2.Button1 = new SplitElement.SplitButton(Images.Update, string.Empty);
            splitElement2.Button2 = new SplitElement.SplitButton(Images.Star2, string.Empty);
            detailsSection.Add(splitElement2);

            var owner = new StyledStringElement("Owner", string.Empty)
            {
                Image = Images.Person
            };

            owner.Tapped += () => ViewModel.GoToUserCommand.ExecuteIfCan();
            detailsSection.Add(owner);

            updatedGistObservable.SubscribeSafe(x =>
            {
                var publicGist    = x.Public.HasValue && x.Public.Value;
                var revisionCount = x.History == null ? 0 : x.History.Count;

                splitElement1.Button1.Text  = publicGist ? "Public" : "Private";
                splitElement1.Button1.Image = publicGist ? Images.Unlocked : Images.Locked;
                splitElement1.Button2.Text  = revisionCount + " Revisions";
                splitElement2.Button1.Text  = x.UpdatedAt.ToLocalTime().ToString("MM/dd/yy");
            });

            updatedGistObservable.SubscribeSafe(x =>
            {
                if (x.Owner == null)
                {
                    owner.Value     = "Anonymous";
                    owner.Accessory = UITableViewCellAccessory.None;
                }
                else
                {
                    owner.Value     = x.Owner.Login;
                    owner.Accessory = UITableViewCellAccessory.DisclosureIndicator;
                }

                Root.Reload(owner);
            });

            ViewModel.WhenAnyValue(x => x.IsStarred).Where(x => x.HasValue).Subscribe(x =>
            {
                splitElement2.Button2.Text  = x.Value ? "Starred!" : "Unstarred";
                splitElement2.Button2.Image = x.Value ? Images.Star : Images.Star2;
            });

            Root.Reset(headerSection, detailsSection, filesSection);

            updatedGistObservable.SubscribeSafe(x =>
            {
                HeaderView.SubText = x.Description;
                if (x.Owner != null)
                {
                    HeaderView.ImageUri = x.Owner.AvatarUrl;
                }
                Root.Reload(headerSection);
            });

            updatedGistObservable.Select(x => x.Files == null ? 0 : x.Files.Count()).SubscribeSafe(x => files.Text = x.ToString());
            updatedGistObservable.SubscribeSafe(x => comments.Text = x.Comments.ToString());
            updatedGistObservable.Select(x => x.Forks == null ? 0 : x.Forks.Count()).SubscribeSafe(x => forks.Text = x.ToString());

            updatedGistObservable.Subscribe(x =>
            {
                var elements = new List <Element>();
                foreach (var file in x.Files.Keys)
                {
                    var sse = new StyledStringElement(file, x.Files[file].Size + " bytes", UITableViewCellStyle.Subtitle)
                    {
                        Accessory     = UITableViewCellAccessory.DisclosureIndicator,
                        LineBreakMode = UILineBreakMode.TailTruncation,
                        Lines         = 1
                    };

                    var fileSaved     = file;
                    var gistFileModel = x.Files[fileSaved];

                    //              if (string.Equals(gistFileModel.Language, "markdown", StringComparison.OrdinalIgnoreCase))
                    //                  sse.Tapped += () => ViewModel.GoToViewableFileCommand.Execute(gistFileModel);
                    //              else
                    sse.Tapped += () => ViewModel.GoToFileSourceCommand.Execute(gistFileModel);
                    elements.Add(sse);
                }

                filesSection.Reset(elements);
            });
//
//            updatedGistObservable.Take(1).Subscribe(_ => Root.Add(filesSection));


            ViewModel.Comments.Changed.Subscribe(_ =>
            {
                var commentModels = ViewModel.Comments.Select(x =>
                                                              new Comment(x.User.AvatarUrl, x.User.Login, x.BodyHtml, x.CreatedAt.ToDaysAgo()));
                var razorView = new CommentsView {
                    Model = commentModels
                };
                var html = razorView.GenerateString();
                commentsElement.Value = html;
            });

            ViewModel.Comments.Changed.Take(1).Select(x => ViewModel.Comments).Where(x => x.Count > 0)
            .Subscribe(_ => Root.Insert(Root.Count, commentsSection));


            ViewModel.WhenAnyValue(x => x.Gist).Where(x => x != null).Subscribe(gist =>
            {
                if (string.Equals(_applicationService.Account.Username, ViewModel.Gist.Owner.Login, StringComparison.OrdinalIgnoreCase))
                {
                    NavigationItem.RightBarButtonItem = new UIBarButtonItem(UIBarButtonSystemItem.Compose, (s, e) => { });

//                              try
//					{
//						var data = await this.DoWorkAsync("Loading...", () => app.Client.ExecuteAsync(app.Client.Gists[ViewModel.Id].Get()));
//						var gistController = new EditGistController(data.Data);
//						gistController.Created = editedGist => ViewModel.Gist = editedGist;
//						var navController = new UINavigationController(gistController);
//						PresentViewController(navController, true, null);
//
//					}
//					catch (Exception ex)
//					{
//						MonoTouch.Utilities.ShowAlert("Error", ex.Message);
//					}
                }
                else
                {
                    NavigationItem.RightBarButtonItem =
                        new UIBarButtonItem(Theme.CurrentTheme.ForkButton, UIBarButtonItemStyle.Plain, (s, e) =>
                                            ViewModel.ForkCommand.ExecuteIfCan());
                    NavigationItem.RightBarButtonItem.EnableIfExecutable(ViewModel.ForkCommand.CanExecuteObservable);
                }
            });

            ViewModel.ForkCommand.IsExecuting.Subscribe(x =>
            {
                if (x)
                {
                    _statusIndicatorService.Show("Forking...");
                }
                else
                {
                    _statusIndicatorService.Hide();
                }
            });
        }
예제 #19
0
		public void Render(RepositoryDetailedModel model)
        {
            if (model == null)
                return;
            
			Title = model.Name;

            var avatar = new Avatar(model.Logo).ToUrl(128);
            var root = new RootElement(Title) { UnevenRows = true };
            HeaderView.SubText = string.IsNullOrWhiteSpace(model.Description) ? "Updated " + model.UtcLastUpdated.Humanize() : model.Description;
            HeaderView.SetImage(avatar, Images.RepoPlaceholder);
            RefreshHeaderView();

            var stargazersCommand = ViewModel.GoToStargazersCommand;
            var split = new SplitButtonElement();
            split.AddButton("Watchers", model.FollowersCount.ToString(), () => stargazersCommand.Execute(null));
            split.AddButton("Forks", model.ForkCount.ToString());
            split.AddButton("Branches", ViewModel.Branches?.Count.ToString() ?? "-");

            var sec1 = new Section();

            _split1.Button1.Image = model.IsPrivate ? AtlassianIcon.Locked.ToImage() : AtlassianIcon.Unlocked.ToImage();
            _split1.Button1.Text = model.IsPrivate ? "Private" : "Public";
            _split1.Button2.Text = string.IsNullOrEmpty(model.Language) ? "N/A" : model.Language;
            sec1.Add(_split1);

            _split3.Button1.Text = model.Scm.ApplyCase(LetterCasing.Title);
            _split3.Button2.Text = "Issues".ToQuantity(ViewModel.Issues);
            sec1.Add(_split3);

            _split2.Button1.Text = (model.UtcCreatedOn).ToString("MM/dd/yy");
            _split2.Button2.Text = model.Size.Bytes().ToString("#.##");
            sec1.Add(_split2);

            var owner = new StyledStringElement("Owner", model.Owner) { Image = AtlassianIcon.User.ToImage(),  Accessory = UITableViewCellAccessory.DisclosureIndicator };
			owner.Tapped += () => ViewModel.GoToOwnerCommand.Execute(null);
            sec1.Add(owner);

			if (model.ForkOf != null)
            {
                var parent = new StyledStringElement("Forked From", model.ForkOf.Name) { Image = AtlassianIcon.Devtoolsfork.ToImage(),  Accessory = UITableViewCellAccessory.DisclosureIndicator };
				parent.Tapped += () => ViewModel.GoToForkParentCommand.Execute(model.ForkOf);
                sec1.Add(parent);
            }

            var events = new StyledStringElement("Events", () => ViewModel.GoToEventsCommand.Execute(null), AtlassianIcon.Blogroll.ToImage());
            var sec2 = new Section { events };

			if (model.HasWiki)
                sec2.Add(new StyledStringElement("Wiki", () => ViewModel.GoToWikiCommand.Execute(null), AtlassianIcon.Edit.ToImage()));

            if (model.HasIssues)
                sec2.Add(new StyledStringElement("Issues", () => ViewModel.GoToIssuesCommand.Execute(null), AtlassianIcon.Flag.ToImage()));

            if (ViewModel.HasReadme)
                sec2.Add(new StyledStringElement("Readme", () => ViewModel.GoToReadmeCommand.Execute(null), AtlassianIcon.Pagedefault.ToImage()));

            var sec3 = new Section
            {
                new StyledStringElement("Commits", () => ViewModel.GoToCommitsCommand.Execute(null), AtlassianIcon.Devtoolscommit.ToImage()),
                new StyledStringElement("Pull Requests", () => ViewModel.GoToPullRequestsCommand.Execute(null), AtlassianIcon.Devtoolspullrequest.ToImage()),
                new StyledStringElement("Source", () => ViewModel.GoToSourceCommand.Execute(null), AtlassianIcon.Filecode.ToImage()),
            };

            root.Add(new[] { new Section { split }, sec1, sec2, sec3 });

            if (!String.IsNullOrEmpty(ViewModel.Repository.Website))
            {
                root.Add(new Section
                {
                    new StyledStringElement("Website", () => ViewModel.GoToUrlCommand.Execute(ViewModel.Repository.Website), AtlassianIcon.Homepage.ToImage())
                });
            }

            Root = root;
        }
예제 #20
0
파일: GistView.cs 프로젝트: zjdgx/CodeHub
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            var headerSection = new Section();
            var filesSection  = new Section("Files");

            var split    = new SplitButtonElement();
            var files    = split.AddButton("Files", "-");
            var comments = split.AddButton("Comments", "-");
            var forks    = split.AddButton("Forks", "-");

            headerSection.Add(split);

            var commentsSection = new Section("Comments")
            {
                FooterView = new TableFooterButton("Add Comment", ViewModel.AddCommentCommand.ExecuteIfCan)
            };
            var commentsElement = new HtmlElement("comments");

            commentsElement.UrlRequested = ViewModel.GoToUrlCommand.ExecuteIfCan;
            commentsSection.Add(commentsElement);

            var detailsSection = new Section {
                _splitRow1, _splitRow2
            };

            Root.Reset(headerSection, detailsSection, filesSection, commentsSection);

            var updatedGistObservable = ViewModel.WhenAnyValue(x => x.Gist).Where(x => x != null);

            ViewModel.WhenAnyValue(x => x.Gist)
            .IsNotNull()
            .Select(x => x.Owner)
            .Subscribe(x =>
            {
                if (x == null)
                {
                    detailsSection.Remove(_ownerElement);
                }
                else if (x != null && !detailsSection.Contains(_ownerElement))
                {
                    detailsSection.Add(_ownerElement);
                }
            });

            updatedGistObservable.SubscribeSafe(x =>
            {
                if (x.Owner == null)
                {
                    _ownerElement.Value     = "Anonymous";
                    _ownerElement.Accessory = UITableViewCellAccessory.None;
                }
                else
                {
                    _ownerElement.Value     = x.Owner.Login;
                    _ownerElement.Accessory = UITableViewCellAccessory.DisclosureIndicator;
                }

                Root.Reload(_ownerElement);
            });

            updatedGistObservable.SubscribeSafe(x =>
            {
                HeaderView.SubText = x.Description;
                if (x.Owner != null)
                {
                    HeaderView.ImageUri = x.Owner.AvatarUrl;
                }
                else
                {
                    HeaderView.Image = Images.LoginUserUnknown;
                }
                TableView.ReloadData();
            });

            updatedGistObservable.Select(x => x.Files == null ? 0 : x.Files.Count()).SubscribeSafe(x => files.Text = x.ToString());
            updatedGistObservable.SubscribeSafe(x => comments.Text = x.Comments.ToString());
            updatedGistObservable.Select(x => x.Forks == null ? 0 : x.Forks.Count()).SubscribeSafe(x => forks.Text = x.ToString());

            updatedGistObservable.Subscribe(x =>
            {
                var elements = new List <Element>();
                foreach (var file in x.Files.Keys)
                {
                    var sse = new StyledStringElement(file, x.Files[file].Size + " bytes", UITableViewCellStyle.Subtitle)
                    {
                        Accessory     = UITableViewCellAccessory.DisclosureIndicator,
                        LineBreakMode = UILineBreakMode.TailTruncation,
                        Lines         = 1
                    };

                    sse.Tapped += () => ViewModel.GoToFileSourceCommand.Execute(x.Files[file]);
                    elements.Add(sse);
                }

                filesSection.Reset(elements);
            });


            ViewModel.Comments.Changed.Subscribe(_ =>
            {
                var commentModels = ViewModel.Comments
                                    .Select(x => new Comment(x.User.AvatarUrl, x.User.Login, x.BodyHtml, x.CreatedAt.UtcDateTime.Humanize()))
                                    .ToList();

                if (commentModels.Count > 0)
                {
                    var razorView = new CommentsView {
                        Model = commentModels
                    };
                    var html = razorView.GenerateString();
                    commentsElement.Value = html;

                    if (!commentsSection.Contains(commentsElement))
                    {
                        commentsSection.Insert(0, UITableViewRowAnimation.Fade, commentsElement);
                    }
                }
                else
                {
                    commentsSection.Remove(commentsElement);
                }
            });
        }
예제 #21
0
        public void Render(RepositoryDetailedModel model)
        {
            if (model == null)
            {
                return;
            }

            Title = model.Name;

            var avatar = new Avatar(model.Logo).ToUrl(128);
            var root   = new RootElement(Title)
            {
                UnevenRows = true
            };

            HeaderView.SubText = string.IsNullOrWhiteSpace(model.Description) ? "Updated " + model.UtcLastUpdated.Humanize() : model.Description;
            HeaderView.SetImage(avatar, Images.RepoPlaceholder);
            RefreshHeaderView();

            var stargazersCommand = ViewModel.GoToStargazersCommand;
            var split             = new SplitButtonElement();

            split.AddButton("Watchers", model.FollowersCount.ToString(), () => stargazersCommand.Execute(null));
            split.AddButton("Forks", model.ForkCount.ToString());
            split.AddButton("Branches", ViewModel.Branches?.Count.ToString() ?? "-");

            var sec1 = new Section();

            _split1.Button1.Image = model.IsPrivate ? AtlassianIcon.Locked.ToImage() : AtlassianIcon.Unlocked.ToImage();
            _split1.Button1.Text  = model.IsPrivate ? "Private" : "Public";
            _split1.Button2.Text  = string.IsNullOrEmpty(model.Language) ? "N/A" : model.Language;
            sec1.Add(_split1);

            _split3.Button1.Text = model.Scm.ApplyCase(LetterCasing.Title);
            _split3.Button2.Text = "Issues".ToQuantity(ViewModel.Issues);
            sec1.Add(_split3);

            _split2.Button1.Text = (model.UtcCreatedOn).ToString("MM/dd/yy");
            _split2.Button2.Text = model.Size.Bytes().ToString("#.##");
            sec1.Add(_split2);

            var owner = new StyledStringElement("Owner", model.Owner)
            {
                Image = AtlassianIcon.User.ToImage(), Accessory = UITableViewCellAccessory.DisclosureIndicator
            };

            owner.Tapped += () => ViewModel.GoToOwnerCommand.Execute(null);
            sec1.Add(owner);

            if (model.ForkOf != null)
            {
                var parent = new StyledStringElement("Forked From", model.ForkOf.Name)
                {
                    Image = AtlassianIcon.Devtoolsfork.ToImage(), Accessory = UITableViewCellAccessory.DisclosureIndicator
                };
                parent.Tapped += () => ViewModel.GoToForkParentCommand.Execute(model.ForkOf);
                sec1.Add(parent);
            }

            var events = new StyledStringElement("Events", () => ViewModel.GoToEventsCommand.Execute(null), AtlassianIcon.Blogroll.ToImage());
            var sec2   = new Section {
                events
            };

            if (model.HasWiki)
            {
                sec2.Add(new StyledStringElement("Wiki", () => ViewModel.GoToWikiCommand.Execute(null), AtlassianIcon.Edit.ToImage()));
            }

            if (model.HasIssues)
            {
                sec2.Add(new StyledStringElement("Issues", () => ViewModel.GoToIssuesCommand.Execute(null), AtlassianIcon.Flag.ToImage()));
            }

            if (ViewModel.HasReadme)
            {
                sec2.Add(new StyledStringElement("Readme", () => ViewModel.GoToReadmeCommand.Execute(null), AtlassianIcon.Pagedefault.ToImage()));
            }

            var sec3 = new Section
            {
                new StyledStringElement("Commits", () => ViewModel.GoToCommitsCommand.Execute(null), AtlassianIcon.Devtoolscommit.ToImage()),
                new StyledStringElement("Pull Requests", () => ViewModel.GoToPullRequestsCommand.Execute(null), AtlassianIcon.Devtoolspullrequest.ToImage()),
                new StyledStringElement("Source", () => ViewModel.GoToSourceCommand.Execute(null), AtlassianIcon.Filecode.ToImage()),
            };

            root.Add(new[] { new Section {
                                 split
                             }, sec1, sec2, sec3 });

            if (!String.IsNullOrEmpty(ViewModel.Repository.Website))
            {
                root.Add(new Section
                {
                    new StyledStringElement("Website", () => ViewModel.GoToUrlCommand.Execute(ViewModel.Repository.Website), AtlassianIcon.Homepage.ToImage())
                });
            }

            Root = root;
        }
예제 #22
0
        public void Render()
        {
            if (ViewModel.Commits == null || ViewModel.Commit == null)
            {
                return;
            }

            var titleMsg  = (ViewModel.Commit.Message ?? string.Empty).Split(new [] { '\n' }, 2).FirstOrDefault();
            var avatarUrl = ViewModel.Commit.Author?.User?.Links?.Avatar?.Href;
            var node      = ViewModel.Node.Substring(0, ViewModel.Node.Length > 10 ? 10 : ViewModel.Node.Length);

            Title              = node;
            HeaderView.Text    = titleMsg ?? node;
            HeaderView.SubText = "Commited " + (ViewModel.Commit.Date).Humanize();
            HeaderView.SetImage(new Avatar(avatarUrl).ToUrl(128), Images.Avatar);
            RefreshHeaderView();

            var split = new SplitButtonElement();

            split.AddButton("Comments", ViewModel.Comments.Items.Count.ToString());
            split.AddButton("Participants", ViewModel.Commit.Participants.Count.ToString());
            split.AddButton("Approvals", ViewModel.Commit.Participants.Count(x => x.Approved).ToString());

            var commitModel            = ViewModel.Commits;
            ICollection <Section> root = new LinkedList <Section>();

            root.Add(new Section {
                split
            });

            var detailSection = new Section();

            root.Add(detailSection);

            var user = ViewModel.Commit.Author?.User?.DisplayName ?? ViewModel.Commit.Author.Raw ?? "Unknown";

            detailSection.Add(new MultilinedElement(user, ViewModel.Commit.Message));

            if (ViewModel.ShowRepository)
            {
                var repo = new StringElement(ViewModel.Repository)
                {
                    Accessory = UIKit.UITableViewCellAccessory.DisclosureIndicator,
                    Lines     = 1,
                    TextColor = StringElement.DefaultDetailColor,
                    Image     = AtlassianIcon.Devtoolsrepository.ToImage()
                };
                repo.Clicked.BindCommand(ViewModel.GoToRepositoryCommand);
                detailSection.Add(repo);
            }

            if (_viewSegment.SelectedSegment == 0)
            {
                var paths = ViewModel.Commits.GroupBy(y =>
                {
                    var filename = "/" + y.File;
                    return(filename.Substring(0, filename.LastIndexOf("/", System.StringComparison.Ordinal) + 1));
                }).OrderBy(y => y.Key);

                foreach (var p in paths)
                {
                    var fileSection = new Section(p.Key);
                    foreach (var x in p)
                    {
                        var y    = x;
                        var file = x.File.Substring(x.File.LastIndexOf('/') + 1);
                        var sse  = new ChangesetElement(file, x.Type, x.Diffstat.Added, x.Diffstat.Removed);
                        sse.Clicked.Select(_ => y).BindCommand(ViewModel.GoToFileCommand);
                        fileSection.Add(sse);
                    }
                    root.Add(fileSection);
                }
            }
            else if (_viewSegment.SelectedSegment == 1)
            {
                var commentSection = new Section();
                foreach (var comment in ViewModel.Comments)
                {
                    var name   = comment.User.DisplayName ?? comment.User.Username;
                    var avatar = new Avatar(comment.User.Links?.Avatar?.Href);
                    commentSection.Add(new CommentElement(name, comment.Content.Raw, comment.CreatedOn, avatar));
                }

                if (commentSection.Elements.Count > 0)
                {
                    root.Add(commentSection);
                }

                var addComment = new StringElement("Add Comment")
                {
                    Image = AtlassianIcon.Addcomment.ToImage()
                };
                addComment.Clicked.Subscribe(_ => AddCommentTapped());
                root.Add(new Section {
                    addComment
                });
            }
            else if (_viewSegment.SelectedSegment == 2)
            {
                var likeSection = new Section();
                likeSection.AddAll(ViewModel.Commit.Participants.Where(x => x.Approved).Select(l => {
                    var avatar = new Avatar(l.User?.Links?.Avatar?.Href);
                    var el     = new UserElement(l.User.DisplayName, string.Empty, string.Empty, avatar);
                    el.Clicked.Select(_ => l.User.Username).BindCommand(ViewModel.GoToUserCommand);
                    return(el);
                }));

                if (likeSection.Elements.Count > 0)
                {
                    root.Add(likeSection);
                }

                StringElement approveButton;
                if (ViewModel.Commit.Participants.Any(x => x.User.Username.Equals(ViewModel.GetApplication().Account.Username) && x.Approved))
                {
                    approveButton = new StringElement("Unapprove")
                    {
                        Image = AtlassianIcon.Approve.ToImage()
                    };
                    approveButton.Clicked.Subscribe(_ => this.DoWorkAsync("Unapproving...", ViewModel.Unapprove));
                }
                else
                {
                    approveButton = new StringElement("Approve")
                    {
                        Image = AtlassianIcon.Approve.ToImage()
                    };
                    approveButton.Clicked.Subscribe(_ => this.DoWorkAsync("Approving...", ViewModel.Approve));
                }
                root.Add(new Section {
                    approveButton
                });
            }

            Root.Reset(root);
        }
예제 #23
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            HeaderView.Image = Images.LoginUserUnknown;
            HeaderView.SubImageView.TintColor = UIColor.FromRGB(243, 156, 18);

            var headerSection = new Section();
            var filesSection  = new Section();

            var split    = new SplitButtonElement();
            var files    = split.AddButton("Files", "-");
            var comments = split.AddButton("Comments", "-");
            var forks    = split.AddButton("Forks", "-");

            headerSection.Add(split);

            var footerButton    = new TableFooterButton("Add Comment");
            var commentsSection = new Section(null, footerButton);
            var commentsElement = new HtmlElement("comments");

            commentsSection.Add(commentsElement);

            var splitRow1      = new SplitViewElement(Octicon.Lock.ToImage(), Octicon.Package.ToImage());
            var splitRow2      = new SplitViewElement(Octicon.Pencil.ToImage(), Octicon.Star.ToImage());
            var ownerElement   = new ButtonElement("Owner", Octicon.Person.ToImage());
            var detailsSection = new Section {
                splitRow1, splitRow2, ownerElement
            };

            Root.Reset(headerSection, detailsSection, filesSection, commentsSection);

            Appeared.Take(1).Delay(TimeSpan.FromSeconds(0.35f))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Select(_ => this.WhenAnyValue(x => x.ViewModel.IsStarred).Where(x => x.HasValue))
            .Switch()
            .Select(x => x.Value ? Octicon.Star.ToImage() : null)
            .Subscribe(HeaderView.SetSubImage);

            ViewModel.Comments.Changed.Subscribe(_ => {
                var commentModels = ViewModel.Comments
                                    .Select(x => {
                    var avatarUrl = x?.User?.AvatarUrl;
                    var avatar    = new GitHubAvatar(avatarUrl);
                    return(new Comment(avatar.ToUri(), x.User.Login, x.BodyHtml, x.CreatedAt.UtcDateTime.Humanize()));
                }).ToList();

                if (commentModels.Count > 0)
                {
                    var model     = new CommentModel(commentModels, (int)UIFont.PreferredSubheadline.PointSize);
                    var razorView = new CommentsView {
                        Model = model
                    };
                    var html = razorView.GenerateString();
                    commentsElement.Value = html;

                    if (!commentsSection.Contains(commentsElement))
                    {
                        commentsSection.Insert(0, UITableViewRowAnimation.Fade, commentsElement);
                    }
                }
                else
                {
                    commentsSection.Remove(commentsElement);
                }
            });

            OnActivation(d => {
                d(footerButton.Clicked.InvokeCommand(ViewModel.AddCommentCommand));
                d(HeaderView.Clicked.InvokeCommand(ViewModel.GoToOwnerCommand));
                d(commentsElement.UrlRequested.InvokeCommand(ViewModel.GoToUrlCommand));
                d(splitRow2.Button2.Clicked.InvokeCommand(ViewModel.ToggleStarCommand));
                d(ownerElement.Clicked.InvokeCommand(ViewModel.GoToOwnerCommand));
                d(DialogSource.SelectedObservable.OfType <FileElement>().Select(x => x.File).InvokeCommand(ViewModel.GoToFileSourceCommand));

                var updatedGistObservable = ViewModel.WhenAnyValue(x => x.Gist).Where(x => x != null);
                d(updatedGistObservable.SubscribeSafe(x => RefreshHeaderView(subtext: x.Description)));
                d(updatedGistObservable.Subscribe(x => filesSection.Reset(x.Files.Select(y => new FileElement(y.Value)))));
                d(ownerElement.BindValue(updatedGistObservable.Select(x => x.Owner?.Login ?? "Anonymous")));
                d(files.BindText(updatedGistObservable.Select(x => x.Files?.Count() ?? 0)));
                d(forks.BindText(updatedGistObservable.Select(x => x.Forks?.Count() ?? 0)));
                d(comments.BindText(updatedGistObservable.Select(x => x.Comments.ToString())));
                d(splitRow1.Button1.BindText(updatedGistObservable.Select(x => x.Public ? "Public" : "Private")));
                d(splitRow1.Button2.BindText(updatedGistObservable.Select(x => "Revisions".ToQuantity(x.History?.Count ?? 0))));

                d(this.WhenAnyValue(x => x.ViewModel.Gist.Owner).Select(x => x == null)
                  .Subscribe(x => ownerElement.Hidden = x));

                d(this.WhenAnyValue(x => x.ViewModel.Avatar)
                  .Subscribe(x => HeaderView.SetImage(x?.ToUri(64), Images.LoginUserUnknown)));

                d(this.WhenAnyValue(x => x.ViewModel.ShowMenuCommand)
                  .ToBarButtonItem(UIBarButtonSystemItem.Action, x => NavigationItem.RightBarButtonItem = x));

                d(this.WhenAnyValue(x => x.ViewModel.IsStarred)
                  .Where(x => x.HasValue)
                  .Select(x => x.Value ? "Starred!" : "Unstarred")
                  .Subscribe(x => splitRow2.Button2.Text = x));

                d(splitRow2.Button1.BindText(this.WhenAnyValue(x => x.ViewModel.Gist).Select(x => {
                    var delta = DateTimeOffset.UtcNow.UtcDateTime - x.UpdatedAt.UtcDateTime;
                    return((delta.Days <= 0) ? "Created Today" : string.Format("{0} Days Old", delta.Days));
                })));
            });
        }
예제 #24
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            HeaderView.Image = Images.LoginUserUnknown;
            HeaderView.SubImageView.TintColor = UIColor.FromRGB(243, 156, 18);

            Appeared.Take(1)
            .Select(_ => Observable.Timer(TimeSpan.FromSeconds(0.35f)).Take(1))
            .Switch()
            .Select(_ => this.WhenAnyValue(x => x.ViewModel.IsStarred).Where(x => x.HasValue))
            .Switch()
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(x => HeaderView.SetSubImage(x.Value ? Octicon.Star.ToImage() : null));

            var events = new StringElement("Events", Octicon.Rss.ToImage())
            {
                Accessory = UITableViewCellAccessory.DisclosureIndicator
            };
            var issuesElement = new StringElement("Issues", Octicon.IssueOpened.ToImage())
            {
                Accessory = UITableViewCellAccessory.DisclosureIndicator
            };
            var commitsElement = new StringElement("Commits", Octicon.GitCommit.ToImage())
            {
                Accessory = UITableViewCellAccessory.DisclosureIndicator
            };
            var pullRequestsElement = new StringElement("Pull Requests", Octicon.GitPullRequest.ToImage())
            {
                Accessory = UITableViewCellAccessory.DisclosureIndicator
            };
            var sourceElement = new StringElement("Source", Octicon.Code.ToImage())
            {
                Accessory = UITableViewCellAccessory.DisclosureIndicator
            };
            var websiteElement = new StringElement("Website", Octicon.Globe.ToImage())
            {
                Accessory = UITableViewCellAccessory.DisclosureIndicator
            };
            var readmeElement = new StringElement("Readme", Octicon.Book.ToImage())
            {
                Accessory = UITableViewCellAccessory.DisclosureIndicator
            };
            var forkedElement = new StringElement("Fork", string.Empty)
            {
                Image     = Octicon.RepoForked.ToImage(),
                Font      = StringElement.DefaultDetailFont,
                Accessory = UITableViewCellAccessory.DisclosureIndicator
            };

            _splitElements[0] = new SplitViewElement(Octicon.Lock.ToImage(), Octicon.Package.ToImage());
            _splitElements[1] = new SplitViewElement(Octicon.IssueOpened.ToImage(), Octicon.Organization.ToImage());
            _splitElements[2] = new SplitViewElement(Octicon.Tag.ToImage(), Octicon.GitBranch.ToImage());

            var stargazers = _split.AddButton("Stargazers", "-");
            var watchers   = _split.AddButton("Watchers", "-");
            var forks      = _split.AddButton("Forks", "-");

            var renderFunc = new Action(() => {
                var model = ViewModel.Repository;
                var sec1  = new Section();
                sec1.Add(_splitElements);

                if (model.Parent != null)
                {
                    forkedElement.Value = model.Parent.FullName;
                    sec1.Add(forkedElement);
                }

                var sec2 = new Section {
                    events
                };

                if (model.HasIssues)
                {
                    sec2.Add(issuesElement);
                }

                if (ViewModel.Readme != null)
                {
                    sec2.Add(readmeElement);
                }

                Root.Reset(new Section {
                    _split
                }, sec1, sec2, new Section {
                    commitsElement, pullRequestsElement, sourceElement
                });

                if (!string.IsNullOrEmpty(model.Homepage))
                {
                    Root.Add(new Section {
                        websiteElement
                    });
                }
            });

            OnActivation(d => {
                d(HeaderView.Clicked.InvokeCommand(ViewModel.GoToOwnerCommand));

                d(_splitElements[1].Button1.Clicked.InvokeCommand(ViewModel.GoToIssuesCommand));
                d(_splitElements[1].Button2.Clicked.InvokeCommand(ViewModel.GoToContributors));
                d(_splitElements[2].Button1.Clicked.InvokeCommand(ViewModel.GoToReleasesCommand));
                d(_splitElements[2].Button2.Clicked.InvokeCommand(ViewModel.GoToBranchesCommand));

                d(events.Clicked.InvokeCommand(ViewModel.GoToEventsCommand));
                d(issuesElement.Clicked.InvokeCommand(ViewModel.GoToIssuesCommand));
                d(websiteElement.Clicked.InvokeCommand(ViewModel.GoToHomepageCommand));
                d(forkedElement.Clicked.InvokeCommand(ViewModel.GoToForkParentCommand));
                d(readmeElement.Clicked.InvokeCommand(ViewModel.GoToReadmeCommand));

                d(stargazers.Clicked.InvokeCommand(ViewModel.GoToStargazersCommand));
                d(watchers.Clicked.InvokeCommand(ViewModel.GoToWatchersCommand));
                d(forks.Clicked.InvokeCommand(ViewModel.GoToForksCommand));

                d(commitsElement.Clicked.InvokeCommand(ViewModel.GoToCommitsCommand));
                d(pullRequestsElement.Clicked.InvokeCommand(ViewModel.GoToPullRequestsCommand));
                d(sourceElement.Clicked.InvokeCommand(ViewModel.GoToSourceCommand));

                d(this.WhenAnyValue(x => x.ViewModel.Stargazers)
                  .Select(x => x != null ? x.ToString() : "-")
                  .Subscribe(x => stargazers.Text = x));

                d(this.WhenAnyValue(x => x.ViewModel.Watchers)
                  .Select(x => x != null ? x.ToString() : "-")
                  .Subscribe(x => watchers.Text = x));

                d(this.WhenAnyValue(x => x.ViewModel.Repository.ForksCount)
                  .Subscribe(x => forks.Text = x.ToString()));

                d(this.WhenAnyValue(x => x.ViewModel.Repository)
                  .IsNotNull()
                  .Subscribe(x =>
                {
                    _splitElements[0].Button1.Text = x.Private ? "Private" : "Public";
                    _splitElements[0].Button2.Text = x.Language ?? "N/A";
                    _splitElements[1].Button1.Text = x.OpenIssuesCount + (x.OpenIssuesCount == 1 ? " Issue" : " Issues");
                }));

                d(this.WhenAnyValue(x => x.ViewModel.RepositoryName)
                  .Subscribe(x => HeaderView.Text = x));

                d(this.WhenAnyValue(x => x.ViewModel.ShowMenuCommand)
                  .ToBarButtonItem(UIBarButtonSystemItem.Action, x => NavigationItem.RightBarButtonItem = x));

                d(this.WhenAnyValue(x => x.ViewModel.Branches)
                  .Select(x => x == null ? "Branches" : (x.Count >= 100 ? "100+" : x.Count.ToString()) + (x.Count == 1 ? " Branch" : " Branches"))
                  .SubscribeSafe(x => _splitElements[2].Button2.Text = x));

                d(this.WhenAnyValue(x => x.ViewModel.Contributors)
                  .Select(x => x == null ? "Contributors" : (x >= 100 ? "100+" : x.ToString()) + (x == 1 ? " Contributor" : " Contributors"))
                  .SubscribeSafe(x => _splitElements[1].Button2.Text = x));

                d(this.WhenAnyValue(x => x.ViewModel.Releases)
                  .Select(x => x == null ? "Releases" : (x >= 100 ? "100+" : x.ToString()) + (x == 1 ? " Release" : " Releases"))
                  .SubscribeSafe(x => _splitElements[2].Button1.Text = x));

                d(this.WhenAnyValue(x => x.ViewModel.Description).Subscribe(x => RefreshHeaderView(subtext: x)));

                d(this.WhenAnyValue(x => x.ViewModel.Avatar)
                  .Subscribe(x => HeaderView.SetImage(x?.ToUri(128), Images.LoginUserUnknown)));

                d(this.WhenAnyValue(x => x.ViewModel.Repository)
                  .IsNotNull()
                  .Subscribe(_ => renderFunc()));

                d(this.WhenAnyValue(x => x.ViewModel.Readme)
                  .Where(x => x != null && ViewModel.Repository != null)
                  .Subscribe(_ => renderFunc()));
            });
        }
예제 #25
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            HeaderView.SetImage(null, Images.Avatar);

            var detailsSection   = new Section();
            var diffButton       = new ButtonElement(AtlassianIcon.ListAdd.ToImage());
            var removedButton    = new ButtonElement(AtlassianIcon.ListRemove.ToImage());
            var modifiedButton   = new ButtonElement(AtlassianIcon.Edit.ToImage());
            var allChangesButton = new ButtonElement("All Changes", AtlassianIcon.Devtoolssidediff.ToImage());

            detailsSection.Add(new [] { diffButton, removedButton, modifiedButton, allChangesButton });

            var additions = ViewModel.WhenAnyValue(x => x.DiffAdditions);

            diffButton.BindClick(ViewModel.GoToAddedFiles);
            diffButton.BindDisclosure(additions.Select(x => x > 0));
            diffButton.BindCaption(additions.Select(x => $"{x} Added"));

            var deletions = ViewModel.WhenAnyValue(x => x.DiffDeletions);

            removedButton.BindClick(ViewModel.GoToRemovedFiles);
            removedButton.BindDisclosure(deletions.Select(x => x > 0));
            removedButton.BindCaption(deletions.Select(x => $"{x} Removed"));

            var modifications = ViewModel.WhenAnyValue(x => x.DiffModifications);

            modifiedButton.BindClick(ViewModel.GoToModifiedFiles);
            modifiedButton.BindDisclosure(modifications.Select(x => x > 0));
            modifiedButton.BindCaption(modifications.Select(x => $"{x} Modified"));

            allChangesButton.BindClick(ViewModel.GoToAllFiles);

            var split         = new SplitButtonElement();
            var commentCount  = split.AddButton("Comments", "-");
            var participants  = split.AddButton("Participants", "-");
            var approvals     = split.AddButton("Approvals", "-");
            var headerSection = new Section {
                split
            };

            var actionButton = new UIBarButtonItem(UIBarButtonSystemItem.Action);

            NavigationItem.RightBarButtonItem = actionButton;

            var detailSection  = new Section();
            var detailsElement = new MultilinedElement();

            detailSection.Add(detailsElement);

            var approvalSection = new Section("Approvals");
            var approveElement  = new LoaderButtonElement("Approve", AtlassianIcon.Approve.ToImage());

            approveElement.Accessory = UITableViewCellAccessory.None;
            approveElement.BindLoader(ViewModel.ToggleApproveButton);
            approveElement.BindCaption(ViewModel.WhenAnyValue(x => x.Approved).Select(x => x ? "Unapprove" : "Approve"));

            var commentsSection   = new Section("Comments");
            var addCommentElement = new ButtonElement("Add Comment", AtlassianIcon.Addcomment.ToImage());

            commentsSection.Add(addCommentElement);

            if (ViewModel.ShowRepository)
            {
                var repo = new ButtonElement(ViewModel.Repository)
                {
                    TextColor = StringElement.DefaultDetailColor,
                    Image     = AtlassianIcon.Devtoolsrepository.ToImage()
                };

                detailSection.Add(repo);
                repo.Clicked.SelectUnit().BindCommand(ViewModel.GoToRepositoryCommand);
            }

            ViewModel.WhenAnyValue(x => x.Commit).Where(x => x != null).Subscribe(x => {
                participants.Text = x?.Participants?.Count.ToString() ?? "-";
                approvals.Text    = x?.Participants?.Count(y => y.Approved).ToString() ?? "-";

                var titleMsg  = (ViewModel.Commit.Message ?? string.Empty).Split(new [] { '\n' }, 2).FirstOrDefault();
                var avatarUrl = ViewModel.Commit.Author?.User?.Links?.Avatar?.Href;

                HeaderView.SubText = titleMsg ?? "Commited " + (ViewModel.Commit.Date).Humanize();
                HeaderView.SetImage(new Avatar(avatarUrl).ToUrl(128), Images.Avatar);
                RefreshHeaderView();

                var user = x.Author?.User?.DisplayName ?? x.Author?.Raw ?? "Unknown";
                detailsElement.Caption = user;
                detailsElement.Details = x.Message;
            });

            this.WhenAnyValue(x => x.ViewModel.Approvals)
            .Select(x => x.Select(y => new UserElement(y)).OfType <Element>())
            .Subscribe(x => approvalSection.Reset(x.Concat(new[] { approveElement })));

            ViewModel.Comments
            .CountChanged
            .Select(x => x.ToString())
            .StartWith("-")
            .Subscribe(x => commentCount.Text = x);

            ViewModel
            .Comments
            .ChangedObservable()
            .Subscribe(x =>
            {
                if (x.Count > 0)
                {
                    var comments     = x.Select(y => new Comment(y.Avatar.ToUrl(), y.Name, y.Content, y.CreatedOn)).ToList();
                    var commentModel = new Views.CommentModel(comments, (int)UIFont.PreferredSubheadline.PointSize);
                    var content      = new CommentsView {
                        Model = commentModel
                    }.GenerateString();
                    _commentsElement.SetValue(content);
                    commentsSection.Insert(0, UITableViewRowAnimation.None, _commentsElement);
                }
                else
                {
                    commentsSection.Remove(_commentsElement);
                }
            });

            ViewModel.WhenAnyValue(x => x.Commit)
            .Where(x => x != null)
            .Take(1)
            .Subscribe(_ => Root.Reset(headerSection, detailsSection, approvalSection, commentsSection));

            ViewModel.GoToAddedFiles.Select(_ => CommitFileType.Added).Subscribe(GoToFiles);
            ViewModel.GoToRemovedFiles.Select(_ => CommitFileType.Removed).Subscribe(GoToFiles);
            ViewModel.GoToModifiedFiles.Select(_ => CommitFileType.Modified).Subscribe(GoToFiles);
            ViewModel.GoToAllFiles.Subscribe(_ => GoToAllFiles());

            OnActivation(d =>
            {
                actionButton
                .GetClickedObservable()
                .Select(x => (object)x)
                .BindCommand(ViewModel.ShowMenuCommand)
                .AddTo(d);

                addCommentElement
                .Clicked
                .SelectUnit()
                .BindCommand(ViewModel.AddCommentCommand)
                .AddTo(d);

                this.WhenAnyObservable(x => x.ViewModel.AddCommentCommand)
                .Subscribe(_ => NewCommentViewController.Present(this, ViewModel.AddComment))
                .AddTo(d);
            });
        }
예제 #26
0
        private void Render()
        {
            //Wait for the issue to load
            if (ViewModel.PullRequest == null)
            {
                return;
            }

            var additions = ViewModel.PullRequest?.Additions ?? 0;
            var deletions = ViewModel.PullRequest?.Deletions ?? 0;
            var changes   = ViewModel.PullRequest?.ChangedFiles ?? 0;

            var split = new SplitButtonElement();

            split.AddButton("Additions", additions.ToString());
            split.AddButton("Deletions", deletions.ToString());
            split.AddButton("Changes", changes.ToString());

            ICollection <Section> sections = new LinkedList <Section>();

            sections.Add(new Section {
                split
            });

            var secDetails = new Section();

            if (_descriptionElement.HasValue)
            {
                secDetails.Add(_descriptionElement);
            }

            secDetails.Add(_split1);
            secDetails.Add(_split2);

            foreach (var i in new [] { _assigneeElement, _milestoneElement, _labelsElement })
            {
                i.Accessory = ViewModel.IsCollaborator ? UITableViewCellAccessory.DisclosureIndicator : UITableViewCellAccessory.None;
            }

            secDetails.Add(_assigneeElement);
            secDetails.Add(_milestoneElement);
            secDetails.Add(_labelsElement);
            sections.Add(secDetails);

            var commits = new StringElement("Commits", Octicon.GitCommit.ToImage());

            commits.Clicked.Subscribe(_ => ViewModel.GoToCommitsCommand.Execute(null));

            var files = new StringElement("Files", Octicon.FileCode.ToImage());

            files.Clicked.Subscribe(_ => ViewModel.GoToFilesCommand.Execute(null));

            sections.Add(new Section {
                commits, files
            });

            var isClosed = string.Equals(ViewModel.PullRequest.State, "closed", StringComparison.OrdinalIgnoreCase);
            var isMerged = ViewModel.PullRequest.Merged.GetValueOrDefault();

            if (ViewModel.CanPush && !isClosed && !isMerged)
            {
                Action mergeAction = async() =>
                {
                    try
                    {
                        await this.DoWorkAsync("Merging...", ViewModel.Merge);
                    }
                    catch (Exception e)
                    {
                        AlertDialogService.ShowAlert("Unable to Merge", e.Message);
                    }
                };

                StringElement el;
                if (!ViewModel.PullRequest.Mergeable.HasValue || ViewModel.PullRequest.Mergeable.Value)
                {
                    el = new StringElement("Merge This Pull Request!", Octicon.GitMerge.ToImage());
                    el.Clicked.Subscribe(_ => mergeAction());
                }
                else
                {
                    el           = new StringElement("Merge Conflicted!", Octicon.GitMerge.ToImage());
                    el.Accessory = UITableViewCellAccessory.None;
                }

                sections.Add(new Section {
                    el
                });
            }

            var commentsSection = new Section();

            if (_commentsElement.HasValue)
            {
                commentsSection.Add(_commentsElement);
            }
            commentsSection.Add(_addCommentElement);
            sections.Add(commentsSection);

            Root.Reset(sections);
        }
예제 #27
0
        public void Render()
        {
            var commitModel = ViewModel.Changeset;

            if (commitModel == null)
            {
                return;
            }

            ICollection <Section> sections = new LinkedList <Section>();

            var additions = ViewModel.Changeset.Stats?.Additions ?? 0;
            var deletions = ViewModel.Changeset.Stats?.Deletions ?? 0;

            var split = new SplitButtonElement();

            split.AddButton("Additions", additions.ToString());
            split.AddButton("Deletions", deletions.ToString());
            split.AddButton("Parents", ViewModel.Changeset.Parents.Count().ToString());

            var headerSection = new Section()
            {
                split
            };

            sections.Add(headerSection);

            var detailSection = new Section();

            sections.Add(detailSection);

            var user = "******";

            if (commitModel.Commit.Author != null)
            {
                user = commitModel.Commit.Author.Name;
            }
            if (commitModel.Commit.Committer != null)
            {
                user = commitModel.Commit.Committer.Name;
            }

            detailSection.Add(new MultilinedElement(user, commitModel.Commit.Message));

            if (ViewModel.ShowRepository)
            {
                var repo = new StringElement(ViewModel.Repository)
                {
                    Accessory = UITableViewCellAccessory.DisclosureIndicator,
                    Lines     = 1,
                    Font      = UIFont.PreferredSubheadline,
                    TextColor = StringElement.DefaultDetailColor,
                    Image     = Octicon.Repo.ToImage()
                };
                repo.Clicked.Subscribe(_ => ViewModel.GoToRepositoryCommand.Execute(null));
                detailSection.Add(repo);
            }

            var paths = commitModel.Files.GroupBy(y => {
                var filename = "/" + y.Filename;
                return(filename.Substring(0, filename.LastIndexOf("/", System.StringComparison.Ordinal) + 1));
            }).OrderBy(y => y.Key);

            foreach (var p in paths)
            {
                var fileSection = new Section(p.Key);
                foreach (var x in p)
                {
                    var y    = x;
                    var file = x.Filename.Substring(x.Filename.LastIndexOf('/') + 1);
                    var sse  = new ChangesetElement(file, x.Status, x.Additions, x.Deletions);
                    sse.Clicked.Subscribe(_ => ViewModel.GoToFileCommand.Execute(y));
                    fileSection.Add(sse);
                }
                sections.Add(fileSection);
            }
//
//            var fileSection = new Section();
//            commitModel.Files.ForEach(x => {
//                var file = x.Filename.Substring(x.Filename.LastIndexOf('/') + 1);
//                var sse = new ChangesetElement(file, x.Status, x.Additions, x.Deletions);
//                sse.Tapped += () => ViewModel.GoToFileCommand.Execute(x);
//                fileSection.Add(sse);
//            });

//            if (fileSection.Elements.Count > 0)
//                root.Add(fileSection);
//

            var commentSection = new Section();

            foreach (var comment in ViewModel.Comments)
            {
                //The path should be empty to indicate it's a comment on the entire commit, not a specific file
                if (!string.IsNullOrEmpty(comment.Path))
                {
                    continue;
                }

                commentSection.Add(new CommentElement(comment.User.Login, comment.Body, comment.CreatedAt, comment.User.AvatarUrl));
            }

            if (commentSection.Elements.Count > 0)
            {
                sections.Add(commentSection);
            }

            var addComment = new StringElement("Add Comment")
            {
                Image = Octicon.Pencil.ToImage()
            };

            addComment.Clicked.Subscribe(_ => AddCommentTapped());
            sections.Add(new Section {
                addComment
            });
            Root.Reset(sections);
        }
예제 #28
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            HeaderView.Image = Images.LoginUserUnknown;

            var split         = new SplitButtonElement();
            var headerSection = new Section {
                split
            };
            var descriptionElement = new MultilinedElement();
            var detailsSection     = new Section();
            var footerButton       = new TableFooterButton("Add Comment");
            var commentsSection    = new Section(null, footerButton);

            var diffButton       = new StringElement(Octicon.DiffAdded.ToImage());
            var removedButton    = new StringElement(Octicon.DiffRemoved.ToImage());
            var modifiedButton   = new StringElement(Octicon.DiffModified.ToImage());
            var allChangesButton = new StringElement("All Changes", Octicon.Diff.ToImage());

            detailsSection.Add(new [] { diffButton, removedButton, modifiedButton, allChangesButton });

            var additions       = split.AddButton("Additions");
            var deletions       = split.AddButton("Deletions");
            var parents         = split.AddButton("Parents");
            var commentsElement = new HtmlElement("comments");

            ViewModel.Comments.Changed
            .Select(_ => new Unit())
            .StartWith(new Unit())
            .Subscribe(x =>
            {
                var comments     = ViewModel.Comments.Select(c => new Comment(c.Avatar.ToUri(), c.Actor, c.Body, c.UtcCreatedAt.Humanize())).ToList();
                var commentModel = new CommentModel(comments, (int)UIFont.PreferredSubheadline.PointSize);
                var razorView    = new CommentsView {
                    Model = commentModel
                };
                var html = razorView.GenerateString();
                commentsElement.Value = html;

                if (commentsElement.GetRootElement() == null && ViewModel.Comments.Count > 0)
                {
                    commentsSection.Add(commentsElement);
                }
                TableView.ReloadData();
            });

            this.WhenAnyValue(x => x.ViewModel.Commit)
            .IsNotNull()
            .Take(1)
            .Subscribe(_ => Root.Reset(headerSection, detailsSection, commentsSection));

            Appeared
            .Take(1)
            .Select(_ => this.WhenAnyValue(x => x.ViewModel.CommitMessage, y => y.ViewModel.CommiterName))
            .Switch()
            .Where(x => x.Item1 != null && x.Item2 != null)
            .Take(1)
            .Subscribe(_ => detailsSection.Insert(0, UITableViewRowAnimation.Automatic, descriptionElement));

            OnActivation(d => {
                d(allChangesButton.BindCommand(ViewModel.GoToAllFiles));
                d(footerButton.Clicked.InvokeCommand(ViewModel.AddCommentCommand));

                d(this.WhenAnyValue(x => x.ViewModel.Avatar)
                  .Subscribe(x => HeaderView.SetImage(x?.ToUri(128), Images.LoginUserUnknown)));

                d(this.WhenAnyValue(x => x.ViewModel.CommitMessage)
                  .Subscribe(x => descriptionElement.Details = x ?? string.Empty));

                d(descriptionElement.BindCaption(this.WhenAnyValue(x => x.ViewModel.CommiterName)));

                d(diffButton.BindCommand(ViewModel.GoToAddedFiles));
                d(diffButton.BindDisclosure(this.WhenAnyValue(x => x.ViewModel.DiffAdditions).Select(x => x > 0)));
                d(diffButton.BindCaption(this.WhenAnyValue(x => x.ViewModel.DiffAdditions).StartWith(0).Select(x => string.Format("{0} added", x))));

                d(removedButton.BindCommand(ViewModel.GoToRemovedFiles));
                d(removedButton.BindDisclosure(this.WhenAnyValue(x => x.ViewModel.DiffDeletions).Select(x => x > 0)));
                d(removedButton.BindCaption(this.WhenAnyValue(x => x.ViewModel.DiffDeletions).StartWith(0).Select(x => string.Format("{0} removed", x))));

                d(modifiedButton.BindCommand(ViewModel.GoToModifiedFiles));
                d(modifiedButton.BindDisclosure(this.WhenAnyValue(x => x.ViewModel.DiffModifications).Select(x => x > 0)));
                d(modifiedButton.BindCaption(this.WhenAnyValue(x => x.ViewModel.DiffModifications).StartWith(0).Select(x => string.Format("{0} modified", x))));

                d(allChangesButton.BindDisclosure(this.WhenAnyValue(x => x.ViewModel.DiffAdditions, x => x.ViewModel.DiffDeletions, x => x.ViewModel.DiffModifications)
                                                  .Select(x => x.Item1 + x.Item2 + x.Item3 > 0)));

                d(commentsElement.UrlRequested.InvokeCommand(ViewModel.GoToUrlCommand));

                d(this.WhenAnyValue(x => x.ViewModel.ShowMenuCommand)
                  .ToBarButtonItem(UIBarButtonSystemItem.Action, x => NavigationItem.RightBarButtonItem = x));

                d(this.WhenAnyValue(x => x.ViewModel.CommitMessageSummary).Subscribe(x => RefreshHeaderView(x)));

                d(this.WhenAnyValue(x => x.ViewModel.Commit).IsNotNull()
                  .Select(x => "Commited " + x.Commit.Committer.Date.LocalDateTime.Humanize())
                  .Subscribe(x => RefreshHeaderView(subtext: x)));

                var statsObs = this.WhenAnyValue(x => x.ViewModel.Commit.Stats);
                d(additions.BindText(statsObs.Select(x => x != null ? x.Additions.ToString() : "-")));
                d(deletions.BindText(statsObs.Select(x => x != null ? x.Deletions.ToString() : "-")));

                d(this.WhenAnyValue(x => x.ViewModel.Commit.Parents)
                  .Subscribe(x => parents.Text = x != null ? x.Count.ToString() : "-"));
            });
        }
예제 #29
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            HeaderView.SetImage(null, Images.Avatar);

            var compose = new UIBarButtonItem(UIBarButtonSystemItem.Compose);
            var more    = new UIBarButtonItem(UIBarButtonSystemItem.Action);

            NavigationItem.RightBarButtonItems = new[] { more, compose };

            var split        = new SplitButtonElement();
            var commentCount = split.AddButton("Comments", "-");
            var watchers     = split.AddButton("Watchers", "-");

            ICollection <Section> root = new LinkedList <Section>();

            root.Add(new Section {
                split
            });

            var secDetails = new Section();

            root.Add(secDetails);

            this.WhenAnyValue(x => x.ViewModel.ShowDescription)
            .DistinctUntilChanged()
            .Subscribe(x =>
            {
                if (x)
                {
                    secDetails.Insert(0, UITableViewRowAnimation.None, _descriptionElement);
                }
                else
                {
                    secDetails.Remove(_descriptionElement);
                }
            });

            this.WhenAnyValue(x => x.ViewModel.Description)
            .Where(x => !string.IsNullOrWhiteSpace(x))
            .Select(x => new DescriptionModel(x, (int)UIFont.PreferredSubheadline.PointSize, true))
            .Select(x => new MarkdownView {
                Model = x
            }.GenerateString())
            .Subscribe(_descriptionElement.SetValue);

            var split1 = new SplitViewElement(AtlassianIcon.Configure.ToImage(), AtlassianIcon.Error.ToImage());
            var split2 = new SplitViewElement(AtlassianIcon.Flag.ToImage(), AtlassianIcon.Spacedefault.ToImage());
            var split3 = new SplitViewElement(AtlassianIcon.Copyclipboard.ToImage(), AtlassianIcon.Calendar.ToImage());

            secDetails.Add(split1);
            secDetails.Add(split2);
            secDetails.Add(split3);

            var assigneeElement = new ButtonElement("Assigned", string.Empty, UITableViewCellStyle.Value1)
            {
                Image = AtlassianIcon.User.ToImage(),
            };

            secDetails.Add(assigneeElement);

            var commentsSection = new Section("Comments");

            root.Add(commentsSection);

            var addComment = new ButtonElement("Add Comment")
            {
                Image = AtlassianIcon.Addcomment.ToImage()
            };

            commentsSection.Reset(new[] { addComment });

            ViewModel
            .Comments
            .ChangedObservable()
            .Subscribe(x =>
            {
                if (x.Count > 0)
                {
                    var comments     = x.Select(y => new Comment(y.Avatar.ToUrl(), y.Name, y.Content, y.CreatedOn)).ToList();
                    var commentModel = new CommentModel(comments, (int)UIFont.PreferredSubheadline.PointSize);
                    var content      = new CommentsView {
                        Model = commentModel
                    }.GenerateString();
                    _commentsElement.SetValue(content);
                    commentsSection.Insert(0, UITableViewRowAnimation.None, _commentsElement);
                }
                else
                {
                    commentsSection.Remove(_commentsElement);
                }
            });

            Root.Reset(root);

            OnActivation(d =>
            {
                this.WhenAnyValue(x => x.ViewModel.Issue)
                .Where(x => x != null)
                .Subscribe(x =>
                {
                    var avatarUrl      = x.ReportedBy?.Avatar;
                    HeaderView.Text    = x.Title;
                    HeaderView.SubText = "Updated " + ViewModel.Issue.UtcLastUpdated.Humanize();
                    HeaderView.SetImage(new Avatar(avatarUrl).ToUrl(128), Images.Avatar);
                    TableView.TableHeaderView = HeaderView;
                })
                .AddTo(d);

                this.WhenAnyObservable(x => x.ViewModel.DismissCommand)
                .Subscribe(_ => NavigationController.PopViewController(true))
                .AddTo(d);

                this.WhenAnyValue(x => x.ViewModel.Issue)
                .Subscribe(x =>
                {
                    split1.Button1.Text = x?.Status;
                    split1.Button2.Text = x?.Priority;
                    split2.Button1.Text = x?.Metadata?.Kind;
                    split2.Button2.Text = x?.Metadata?.Component ?? "No Component";
                    split3.Button1.Text = x?.Metadata?.Version ?? "No Version";
                    split3.Button2.Text = x?.Metadata?.Milestone ?? "No Milestone";
                })
                .AddTo(d);

                HeaderView
                .Clicked
                .BindCommand(this, x => x.ViewModel.GoToReporterCommand)
                .AddTo(d);

                compose
                .GetClickedObservable()
                .SelectUnit()
                .BindCommand(ViewModel.GoToEditCommand)
                .AddTo(d);

                addComment
                .Clicked
                .Subscribe(_ => NewCommentViewController.Present(this, ViewModel.AddComment))
                .AddTo(d);

                assigneeElement
                .BindValue(this.WhenAnyValue(x => x.ViewModel.Assigned))
                .AddTo(d);

                assigneeElement
                .BindDisclosure(
                    this.WhenAnyValue(x => x.ViewModel.Assigned)
                    .Select(x => !string.Equals(x, "Unassigned", StringComparison.OrdinalIgnoreCase)))
                .AddTo(d);

                assigneeElement
                .Clicked
                .SelectUnit()
                .BindCommand(ViewModel.GoToAssigneeCommand)
                .AddTo(d);

                more.Bind(ViewModel.ShowMenuCommand)
                .AddTo(d);

                this.WhenAnyValue(x => x.ViewModel.Issue)
                .Select(x => x != null)
                .Subscribe(x => compose.Enabled = x)
                .AddTo(d);

                this.WhenAnyObservable(x => x.ViewModel.Comments.CountChanged)
                .StartWith(ViewModel.Comments.Count)
                .Subscribe(x => commentCount.Text = x.ToString())
                .AddTo(d);

                this.WhenAnyValue(x => x.ViewModel.Issue.FollowerCount)
                .Subscribe(x => watchers.Text = x.ToString())
                .AddTo(d);
            });
        }
예제 #30
0
        protected BaseIssueViewController()
        {
            CommentsElement = new HtmlElement("comments");
            this.WhenAnyValue(x => x.ViewModel.GoToUrlCommand)
            .Subscribe(x => CommentsElement.UrlRequested = x.ExecuteIfCan);

            DescriptionElement = new HtmlElement("description");
            this.WhenAnyValue(x => x.ViewModel.GoToUrlCommand)
            .Subscribe(x => DescriptionElement.UrlRequested = x.ExecuteIfCan);

            this.WhenAnyValue(x => x.ViewModel.ShowMenuCommand)
            .Select(x => x.ToBarButtonItem(UIBarButtonSystemItem.Action))
            .Subscribe(x => NavigationItem.RightBarButtonItem = x);

            this.WhenAnyObservable(x => x.ViewModel.GoToAssigneesCommand)
            .Subscribe(_ => IssueAssigneeViewController.Show(this, ViewModel.CreateAssigneeViewModel()));

            this.WhenAnyObservable(x => x.ViewModel.GoToMilestonesCommand)
            .Subscribe(_ => IssueMilestonesViewController.Show(this, ViewModel.CreateMilestonesViewModel()));

            this.WhenAnyObservable(x => x.ViewModel.GoToLabelsCommand)
            .Subscribe(_ => IssueLabelsViewController.Show(this, ViewModel.CreateLabelsViewModel()));

            this.WhenAnyValue(x => x.ViewModel.GoToOwnerCommand)
            .Subscribe(x => HeaderView.ImageButtonAction = x != null ? new Action(() => ViewModel.GoToOwnerCommand.ExecuteIfCan()) : null);

            Appeared.Take(1)
            .Select(_ => Observable.Timer(TimeSpan.FromSeconds(0.2f)))
            .Switch()
            .ObserveOn(RxApp.MainThreadScheduler)
            .Select(_ => this.WhenAnyValue(x => x.ViewModel.IsClosed))
            .Switch()
            .Subscribe(x =>
            {
                HeaderView.SubImageView.TintColor = x ? UIColor.FromRGB(0xbd, 0x2c, 0) : UIColor.FromRGB(0x6c, 0xc6, 0x44);
                HeaderView.SetSubImage((x ? Octicon.IssueClosed :Octicon.IssueOpened).ToImage());
            });

            MilestoneElement = new StringElement("Milestone", string.Empty, UITableViewCellStyle.Value1)
            {
                Image = Octicon.Milestone.ToImage()
            };
            MilestoneElement.Tapped = () => ViewModel.GoToMilestonesCommand.ExecuteIfCan();
            this.WhenAnyValue(x => x.ViewModel.AssignedMilestone)
            .Select(x => x == null ? "No Milestone" : x.Title)
            .Subscribe(x => MilestoneElement.Value = x);

            AssigneeElement = new StringElement("Assigned", string.Empty, UITableViewCellStyle.Value1)
            {
                Image = Octicon.Person.ToImage()
            };
            AssigneeElement.Tapped = () => ViewModel.GoToAssigneesCommand.ExecuteIfCan();
            this.WhenAnyValue(x => x.ViewModel.AssignedUser)
            .Select(x => x == null ? "Unassigned" : x.Login)
            .Subscribe(x => AssigneeElement.Value = x);

            LabelsElement = new StringElement("Labels", string.Empty, UITableViewCellStyle.Value1)
            {
                Image = Octicon.Tag.ToImage()
            };
            LabelsElement.Tapped = () => ViewModel.GoToLabelsCommand.ExecuteIfCan();
            this.WhenAnyValue(x => x.ViewModel.AssignedLabels)
            .Select(x => (x == null || x.Count == 0) ? "None" : string.Join(",", x.Select(y => y.Name)))
            .Subscribe(x => LabelsElement.Value = x);

            this.WhenAnyValue(x => x.ViewModel.CanModify)
            .Select(x => x ? UITableViewCellAccessory.DisclosureIndicator : UITableViewCellAccessory.None)
            .Subscribe(x => MilestoneElement.Accessory = AssigneeElement.Accessory = LabelsElement.Accessory = x);

            DetailsSection.Add(MilestoneElement);
            DetailsSection.Add(AssigneeElement);
            DetailsSection.Add(LabelsElement);

            this.WhenAnyValue(x => x.ViewModel.Avatar)
            .SubscribeSafe(x => HeaderView.SetImage(x?.ToUri(128), Images.LoginUserUnknown));

            this.WhenAnyValue(x => x.ViewModel.Issue)
            .IsNotNull()
            .Subscribe(x => {
                HeaderView.Text    = x.Title;
                HeaderView.SubText = x.UpdatedAt.HasValue ?
                                     ("Updated " + x.UpdatedAt.Value.UtcDateTime.Humanize()) :
                                     ("Created " + x.CreatedAt.UtcDateTime.Humanize());
                RefreshHeaderView();
            });

            this.WhenAnyValue(x => x.ViewModel.MarkdownDescription)
            .Subscribe(x =>
            {
                if (string.IsNullOrEmpty(x))
                {
                    DetailsSection.Remove(DescriptionElement);
                }
                else
                {
                    var model    = new DescriptionModel(x, (int)UIFont.PreferredSubheadline.PointSize);
                    var markdown = new MarkdownView {
                        Model = model
                    };
                    var html = markdown.GenerateString();
                    DescriptionElement.Value = html;

                    if (!DetailsSection.Contains(DescriptionElement))
                    {
                        DetailsSection.Insert(0, UITableViewRowAnimation.Fade, DescriptionElement);
                    }
                }
            });

            CommentsSection.FooterView = new TableFooterButton("Add Comment", () => ViewModel.AddCommentCommand.ExecuteIfCan());

            this.WhenAnyValue(x => x.ViewModel.Events)
            .Select(x => x.Changed)
            .Switch()
            .Select(x => ViewModel.Events)
            .Subscribe(events =>
            {
                var comments = events.Select(x =>
                {
                    var body    = string.Empty;
                    var comment = x as IssueCommentItemViewModel;
                    var @event  = x as IssueEventItemViewModel;

                    if (comment != null)
                    {
                        body = comment.Comment;
                    }
                    else if (@event != null)
                    {
                        body = CreateEventBody(@event.EventInfo, @event.Commit);
                    }

                    return(new Comment(x.AvatarUrl.ToUri(), x.Actor, body, x.CreatedAt.Humanize()));
                })
                               .Where(x => !string.IsNullOrEmpty(x.Body))
                               .ToList();

                if (comments.Count > 0)
                {
                    var commentModel = new CommentModel(comments, (int)UIFont.PreferredSubheadline.PointSize);
                    var razorView    = new CommentsView {
                        Model = commentModel
                    };
                    var html = razorView.GenerateString();
                    CommentsElement.Value = html;

                    if (!CommentsSection.Contains(CommentsElement))
                    {
                        CommentsSection.Insert(0, UITableViewRowAnimation.Fade, CommentsElement);
                    }
                }
                else
                {
                    CommentsSection.Remove(CommentsElement);
                }
            });

            var commentsButton     = SplitButton.AddButton("Comments", "-");
            var participantsButton = SplitButton.AddButton("Participants", "-");

            this.WhenAnyValue(x => x.ViewModel.CommentCount)
            .Subscribe(x => commentsButton.Text = x.ToString());

            this.WhenAnyValue(x => x.ViewModel.Participants)
            .Subscribe(x => participantsButton.Text = x.ToString());
        }
예제 #31
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            HeaderView.Image = Images.LoginUserUnknown;

            var split         = new SplitButtonElement();
            var headerSection = new Section {
                split
            };
            var descriptionElement = new MultilinedElement();
            var detailsSection     = new Section();
            var commentsSection    = new Section(null, new TableFooterButton("Add Comment", () => ViewModel.AddCommentCommand.ExecuteIfCan()));

            var additions = split.AddButton("Additions");
            var deletions = split.AddButton("Deletions");
            var parents   = split.AddButton("Parents");

            var gotoRepositoryElement = new StringElement(string.Empty)
            {
                Font      = StringElement.DefaultDetailFont,
                TextColor = StringElement.DefaultDetailColor,
                Image     = Octicon.Repo.ToImage()
            };

            gotoRepositoryElement.Tapped += () => ViewModel.GoToRepositoryCommand.ExecuteIfCan();

            detailsSection.Add(
                new StringElement(Octicon.DiffAdded.ToImage())
                .BindCommand(() => ViewModel.GoToAddedFiles)
                .BindDisclosure(this.WhenAnyValue(x => x.ViewModel.DiffAdditions).Select(x => x > 0))
                .BindCaption(this.WhenAnyValue(x => x.ViewModel.DiffAdditions).StartWith(0).Select(x => string.Format("{0} added", x))));

            detailsSection.Add(
                new StringElement(Octicon.DiffRemoved.ToImage())
                .BindCommand(() => ViewModel.GoToRemovedFiles)
                .BindDisclosure(this.WhenAnyValue(x => x.ViewModel.DiffDeletions).Select(x => x > 0))
                .BindCaption(this.WhenAnyValue(x => x.ViewModel.DiffDeletions).StartWith(0).Select(x => string.Format("{0} removed", x))));

            detailsSection.Add(
                new StringElement(Octicon.DiffModified.ToImage())
                .BindCommand(() => ViewModel.GoToModifiedFiles)
                .BindDisclosure(this.WhenAnyValue(x => x.ViewModel.DiffModifications).Select(x => x > 0))
                .BindCaption(this.WhenAnyValue(x => x.ViewModel.DiffModifications).StartWith(0).Select(x => string.Format("{0} modified", x))));

            detailsSection.Add(new StringElement("All Changes", () => ViewModel.GoToAllFiles.ExecuteIfCan(), Octicon.Diff.ToImage()));

            var commentsElement = new HtmlElement("comments");

            commentsElement.UrlRequested = ViewModel.GoToUrlCommand.ExecuteIfCan;

            ViewModel.Comments.Changed
            .Select(_ => new Unit())
            .StartWith(new Unit())
            .Subscribe(x =>
            {
                var comments     = ViewModel.Comments.Select(c => new Comment(c.Avatar.ToUri(), c.Actor, c.Body, c.UtcCreatedAt.Humanize())).ToList();
                var commentModel = new CodeHub.WebViews.CommentModel(comments, (int)UIFont.PreferredSubheadline.PointSize);
                var razorView    = new CommentsView {
                    Model = commentModel
                };
                var html = razorView.GenerateString();
                commentsElement.Value = html;

                if (commentsElement.GetRootElement() == null && ViewModel.Comments.Count > 0)
                {
                    commentsSection.Add(commentsElement);
                }
                TableView.ReloadData();
            });

            this.WhenAnyValue(x => x.ViewModel.Commit)
            .IsNotNull()
            .Take(1)
            .Subscribe(_ => Root.Reset(headerSection, detailsSection, commentsSection));

            Appeared
            .Take(1)
            .Select(_ => this.WhenAnyValue(x => x.ViewModel.CommitMessage, y => y.ViewModel.CommiterName))
            .Switch()
            .Where(x => x.Item1 != null && x.Item2 != null)
            .Take(1)
            .Subscribe(_ => detailsSection.Insert(0, UITableViewRowAnimation.Automatic, descriptionElement));

            this.WhenAnyValue(x => x.ViewModel.CommiterName)
            .Subscribe(x => descriptionElement.Caption = x ?? string.Empty);

            this.WhenAnyValue(x => x.ViewModel.CommitMessage)
            .Subscribe(x => descriptionElement.Details = x ?? string.Empty);


            this.WhenAnyValue(x => x.ViewModel.RepositoryName)
            .Subscribe(x => gotoRepositoryElement.Caption = x);

            this.WhenAnyValue(x => x.ViewModel.ShowRepository)
            .StartWith(false)
            .Where(x => x)
            .Take(1)
            .Subscribe(x => detailsSection.Add(gotoRepositoryElement));

            this.WhenAnyValue(x => x.ViewModel.Commit)
            .SubscribeSafe(x =>
            {
                additions.Text = x != null ? x.Stats.Additions.ToString() : "-";
                deletions.Text = x != null ? x.Stats.Deletions.ToString() : "-";
                parents.Text   = x != null ? x.Parents.Count.ToString() : "-";
            });

            this.WhenAnyValue(x => x.ViewModel.ShowMenuCommand)
            .Select(x => x.ToBarButtonItem(UIBarButtonSystemItem.Action))
            .Subscribe(x => NavigationItem.RightBarButtonItem = x);

            this.WhenAnyValue(x => x.ViewModel.CommitMessageSummary)
            .Subscribe(x => {
                HeaderView.Text = x;
                RefreshHeaderView();
            });

            this.WhenAnyValue(x => x.ViewModel.Avatar)
            .Subscribe(x => HeaderView.SetImage(x?.ToUri(128), Images.LoginUserUnknown));

            this.WhenAnyValue(x => x.ViewModel.Commit)
            .IsNotNull()
            .Subscribe(x => {
                HeaderView.SubText = "Commited " + x.Commit.Committer.Date.LocalDateTime.Humanize();
                RefreshHeaderView();
            });
        }
예제 #32
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            HeaderView.Image = Images.LoginUserUnknown;

            _sourceSection = new Section
            {
                new StringElement("Commits", () => ViewModel.GoToCommitsCommand.ExecuteIfCan(), Octicon.GitCommit.ToImage()),
                new StringElement("Pull Requests", () => ViewModel.GoToPullRequestsCommand.ExecuteIfCan(), Octicon.GitPullRequest.ToImage()),
                new StringElement("Source", () => ViewModel.GoToSourceCommand.ExecuteIfCan(), Octicon.Code.ToImage()),
            };

            _ownerElement = new StringElement("Owner", string.Empty)
            {
                Image = Octicon.Person.ToImage()
            };
            _ownerElement.Tapped += () => ViewModel.GoToOwnerCommand.ExecuteIfCan();
            this.WhenAnyValue(x => x.ViewModel.Repository)
            .Subscribe(x => _ownerElement.Value = x == null ? string.Empty : x.Owner.Login);

            HeaderView.SubImageView.TintColor = UIColor.FromRGB(243, 156, 18);
            this.WhenAnyValue(x => x.ViewModel.GoToOwnerCommand).Subscribe(x =>
                                                                           HeaderView.ImageButtonAction = x != null ? new Action(() => ViewModel.GoToOwnerCommand.ExecuteIfCan()) : null);

            _splitElements[0]         = new SplitViewElement();
            _splitElements[0].Button1 = new SplitViewElement.SplitButton(Octicon.Lock.ToImage(), string.Empty);
            _splitElements[0].Button2 = new SplitViewElement.SplitButton(Octicon.Package.ToImage(), string.Empty);

            _splitElements[1]         = new SplitViewElement();
            _splitElements[1].Button1 = new SplitViewElement.SplitButton(Octicon.IssueOpened.ToImage(), string.Empty, () => ViewModel.GoToIssuesCommand.ExecuteIfCan());
            _splitElements[1].Button2 = new SplitViewElement.SplitButton(Octicon.Organization.ToImage(), string.Empty, () => ViewModel.GoToContributors.ExecuteIfCan());

            _splitElements[2]         = new SplitViewElement();
            _splitElements[2].Button1 = new SplitViewElement.SplitButton(Octicon.Tag.ToImage(), string.Empty, () => ViewModel.GoToReleasesCommand.ExecuteIfCan());
            _splitElements[2].Button2 = new SplitViewElement.SplitButton(Octicon.GitBranch.ToImage(), string.Empty, () => ViewModel.GoToBranchesCommand.ExecuteIfCan());

            var stargazers = _split.AddButton("Stargazers", "-", () => ViewModel.GoToStargazersCommand.ExecuteIfCan());
            var watchers   = _split.AddButton("Watchers", "-", () => ViewModel.GoToWatchersCommand.ExecuteIfCan());
            var forks      = _split.AddButton("Forks", "-", () => ViewModel.GoToForksCommand.ExecuteIfCan());

            this.WhenAnyValue(x => x.ViewModel.Stargazers)
            .Select(x => x != null ? x.ToString() : "-")
            .Subscribe(x => stargazers.Text = x);

            this.WhenAnyValue(x => x.ViewModel.Watchers)
            .Select(x => x != null ? x.ToString() : "-")
            .Subscribe(x => watchers.Text = x);

            this.WhenAnyValue(x => x.ViewModel.Repository.ForksCount)
            .Subscribe(x => forks.Text = x.ToString());

            this.WhenAnyValue(x => x.ViewModel.Repository)
            .IsNotNull()
            .Subscribe(x =>
            {
                _splitElements[0].Button1.Text = x.Private ? "Private" : "Public";
                _splitElements[0].Button2.Text = x.Language ?? "N/A";
                _splitElements[1].Button1.Text = x.OpenIssuesCount + (x.OpenIssuesCount == 1 ? " Issue" : " Issues");
            });

            Appeared.Take(1)
            .Select(_ => Observable.Timer(TimeSpan.FromSeconds(0.35f)))
            .Switch()
            .ObserveOn(RxApp.MainThreadScheduler)
            .Select(_ => this.WhenAnyValue(x => x.ViewModel.IsStarred).Where(x => x.HasValue))
            .Switch()
            .Subscribe(x => HeaderView.SetSubImage(x.Value ? Octicon.Star.ToImage() : null));

            this.WhenAnyValue(x => x.ViewModel.RepositoryName)
            .Subscribe(x => HeaderView.Text = x);

            this.WhenAnyValue(x => x.ViewModel.ShowMenuCommand)
            .Select(x => x.ToBarButtonItem(UIBarButtonSystemItem.Action))
            .Subscribe(x => NavigationItem.RightBarButtonItem = x);

            this.WhenAnyValue(x => x.ViewModel.Branches)
            .Select(x => x == null ? "- Branches" : (x.Count >= 100 ? "100+" : x.Count.ToString()) + (x.Count == 1 ? " Branch" : " Branches"))
            .SubscribeSafe(x => _splitElements[2].Button2.Text = x);

            this.WhenAnyValue(x => x.ViewModel.Contributors)
            .Select(x => x == null ? "- Contributors" : (x >= 100 ? "100+" : x.ToString()) + (x == 1 ? " Contributor" : " Contributors"))
            .SubscribeSafe(x => _splitElements[1].Button2.Text = x);

            this.WhenAnyValue(x => x.ViewModel.Releases)
            .Select(x => x == null ? "- Releases" : (x >= 100 ? "100+" : x.ToString()) + (x == 1 ? " Release" : " Releases"))
            .SubscribeSafe(x => _splitElements[2].Button1.Text = x);

            this.WhenAnyValue(x => x.ViewModel.Description)
            .Subscribe(x => {
                HeaderView.SubText = x;
                RefreshHeaderView();
            });

            this.WhenAnyValue(x => x.ViewModel.Avatar)
            .Subscribe(x => HeaderView.SetImage(x?.ToUri(128), Images.LoginUserUnknown));

            this.WhenAnyValue(x => x.ViewModel.Repository)
            .IsNotNull()
            .Subscribe(_ => Render());

            this.WhenAnyValue(x => x.ViewModel.Readme)
            .Where(x => x != null && ViewModel.Repository != null)
            .Subscribe(_ => Render());
        }
예제 #33
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            Title = string.Format("Gist #{0}", ViewModel.Id);
            var updatedGistObservable = ViewModel.WhenAnyValue(x => x.Gist).Where(x => x != null);

            var headerSection   = new Section(HeaderView);
            var filesSection    = new Section("Files");
            var commentsSection = new Section("Comments");

            var split    = new SplitButtonElement();
            var files    = split.AddButton("Files", "-", () => {});
            var comments = split.AddButton("Comments", "-", () => {});
            var forks    = split.AddButton("Forks", "-", () => ViewModel.GoToForksCommand.ExecuteIfCan());

            headerSection.Add(split);

            Root.Reset(headerSection, filesSection, commentsSection);

            updatedGistObservable.SubscribeSafe(x =>
            {
                HeaderView.SubText = x.Description;
                if (x.Owner != null)
                {
                    HeaderView.ImageUri = x.Owner.AvatarUrl;
                }
                ReloadData();
            });

            updatedGistObservable.SubscribeSafe(x => files.Text    = x.Files.Count.ToString());
            updatedGistObservable.SubscribeSafe(x => comments.Text = x.Comments.ToString());
            updatedGistObservable.SubscribeSafe(x => forks.Text    = x.Forks.Count.ToString());
            //updatedGistObservable.Take(1).SubscribeSafe(x => detailsSection.Visible = !string.IsNullOrEmpty(x.Description));


//            var splitElement1 = new SplitElement();
//            detailsSection.Add(splitElement1);
//
//            updatedGistObservable.Subscribe(x =>
//            {
//                splitElement1.Button1 = new SplitElement.SplitButton(x.Public.HasValue && x.Public.Value ? Images.Unlocked : Images.Locked, model.Private ? "Private" : "Public");
//                splitElement1.Button2 = new SplitElement.SplitButton(Images.Language, model.Language ?? "N/A");
//            });

//            updatedGistObservable.Take(1).Subscribe(_ => root.Add(detailsSection));
//
//
            updatedGistObservable.Subscribe(x =>
            {
                var elements = new List <Element>();
                foreach (var file in x.Files.Keys)
                {
                    var sse = new StyledStringElement(file, x.Files[file].Size + " bytes", UITableViewCellStyle.Subtitle)
                    {
                        Accessory     = UITableViewCellAccessory.DisclosureIndicator,
                        LineBreakMode = UILineBreakMode.TailTruncation,
                        Lines         = 1
                    };

                    var fileSaved     = file;
                    var gistFileModel = x.Files[fileSaved];

                    //              if (string.Equals(gistFileModel.Language, "markdown", StringComparison.OrdinalIgnoreCase))
                    //                  sse.Tapped += () => ViewModel.GoToViewableFileCommand.Execute(gistFileModel);
                    //              else
                    sse.Tapped += () => ViewModel.GoToFileSourceCommand.Execute(gistFileModel);
                    elements.Add(sse);
                }

                filesSection.Reset(elements);
            });
//
//            updatedGistObservable.Take(1).Subscribe(_ => Root.Add(filesSection));

//
//            ViewModel.Comments.Changed.Subscribe(_ =>
//            {
//                foreach (var comment in ViewModel.Comments)
//                {
//                    var el = new NameTimeStringElement
//                    {
//                        Name = "Anonymous",
//                        Image = Theme.CurrentTheme.AnonymousUserImage,
//                        String = comment.Body,
//                        Time = comment.CreatedAt.ToDaysAgo(),
//                    };
//
//                    if (comment.User != null)
//                    {
//                        el.Name = comment.User.Login;
//                        el.ImageUri = new Uri(comment.User.AvatarUrl);
//                    }
//
//                    commentsSection.Add(el);
//                }
//            });
//
//            ViewModel.Comments.Changed.Skip(1).Take(1).Subscribe(_ => Root.Insert(Root.Count, commentsSection));

//
            //Sometimes there's no user!
//            d.Name = (model.Owner == null) ? "Anonymous" : model.Owner.Login;
//            d.ImageUri = (model.Owner == null) ? null : new Uri(model.Owner.AvatarUrl);
//
//            sec.Add(d);
//
//            var sec2 = new Section("Files");
//            root.Add(sec2);
//
//            if (ViewModel.Comments.Count > 0)
//            {
//                var sec3 = new Section("Comments");
//                foreach (var comment in ViewModel.Comments)
//                {
//                    var el = new NameTimeStringElement
//                    {
//                        Name = "Anonymous",
//                        Image = Theme.CurrentTheme.AnonymousUserImage,
//                        String = comment.Body,
//                        Time = comment.CreatedAt.ToDaysAgo(),
//                    };
//
//                    if (comment.User != null)
//                    {
//                        el.Name = comment.User.Login;
//                        el.ImageUri = new Uri(comment.User.AvatarUrl);
//                    }
//
//                    sec3.Add(el);
//                }
//                root.Add(sec3);
//            }


            ViewModel.WhenAnyValue(x => x.Gist).Where(x => x != null).Subscribe(gist =>
            {
                if (string.Equals(_applicationService.Account.Username, ViewModel.Gist.Owner.Login, StringComparison.OrdinalIgnoreCase))
                {
                    NavigationItem.RightBarButtonItem = new UIBarButtonItem(UIBarButtonSystemItem.Compose, (s, e) => { });

//                              try
//					{
//						var data = await this.DoWorkAsync("Loading...", () => app.Client.ExecuteAsync(app.Client.Gists[ViewModel.Id].Get()));
//						var gistController = new EditGistController(data.Data);
//						gistController.Created = editedGist => ViewModel.Gist = editedGist;
//						var navController = new UINavigationController(gistController);
//						PresentViewController(navController, true, null);
//
//					}
//					catch (Exception ex)
//					{
//						MonoTouch.Utilities.ShowAlert("Error", ex.Message);
//					}
                }
                else
                {
                    NavigationItem.RightBarButtonItem =
                        new UIBarButtonItem(Theme.CurrentTheme.ForkButton, UIBarButtonItemStyle.Plain, (s, e) =>
                                            ViewModel.ForkCommand.ExecuteIfCan());
                    NavigationItem.RightBarButtonItem.EnableIfExecutable(ViewModel.ForkCommand.CanExecuteObservable);
                }
            });


//            ViewModel.WhenAnyValue(x => x.IsStarred).Subscribe(isStarred =>
//            {
//                _starButton.Enabled = isStarred.HasValue;
//                _starButton.SetImage((isStarred.HasValue && isStarred.Value) ? Images.Gist.StarHighlighted : Images.Gist.Star, UIControlState.Normal);
//                _starButton.SetNeedsDisplay();
//            });
//
            ViewModel.ForkCommand.IsExecuting.Subscribe(x =>
            {
                if (x)
                {
                    _statusIndicatorService.Show("Forking...");
                }
                else
                {
                    _statusIndicatorService.Hide();
                }
            });
        }