public SourceViewModel( string username, string repository, string branch, string path, IApplicationService applicationService = null, IActionMenuService actionMenuService = null) { applicationService = applicationService ?? Locator.Current.GetService <IApplicationService>(); actionMenuService = actionMenuService ?? Locator.Current.GetService <IActionMenuService>(); GoToHtmlUrlCommand = ReactiveCommand.Create( () => NavigateTo(new WebBrowserViewModel(HtmlUrl)), this.WhenAnyValue(x => x.HtmlUrl).Select(x => !string.IsNullOrEmpty(x))); //Create the filename var fileName = Path.GetFileName(path); if (fileName == null) { fileName = path.Substring(path.LastIndexOf('/') + 1); } //Create the temp file path Title = fileName; var extension = Path.GetExtension(path); IsMarkdown = MarkdownExtensions.Any(x => x == extension); var canExecute = this.WhenAnyValue(x => x.HtmlUrl).Select(x => x != null); var canOpen = this.WhenAnyValue(x => x.FilePath).Select(x => x != null); var canShow = Observable.CombineLatest(canExecute, canOpen, (x, y) => x && y); ShowMenuCommand = ReactiveCommand.CreateFromTask <object>(sender => { var menu = actionMenuService.Create(); menu.AddButton("Open In", x => actionMenuService.OpenIn(x, FilePath)); menu.AddButton("Share", x => actionMenuService.ShareUrl(x, HtmlUrl)); menu.AddButton("Show in Bitbucket", _ => GoToHtmlUrlCommand.ExecuteNow()); return(menu.Show(sender)); }, canShow); LoadCommand = ReactiveCommand.CreateFromTask(async _ => { var filePath = Path.Combine(Path.GetTempPath(), Path.GetFileName(fileName)); using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write)) { await applicationService.Client.Repositories.GetRawFile(username, repository, branch, path, stream); } using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { var buffer = new byte[1024]; var read = stream.Read(buffer, 0, 1024); IsText = !buffer.Take(read).Any(x => x == 0); } FilePath = filePath; HtmlUrl = $"https://bitbucket.org/{username}/{repository}/raw/{branch}/{path.TrimStart('/')}"; }); }
public RepositoryViewModel( string username, string repositoryName, Repository repository = null, IApplicationService applicationService = null, IActionMenuService actionMenuService = null) { applicationService = _applicationService = applicationService ?? Locator.Current.GetService <IApplicationService>(); actionMenuService = actionMenuService ?? Locator.Current.GetService <IActionMenuService>(); Repository = repository; _branches.Changed .Select(_ => _branches.Count) .ToProperty(this, x => x.BranchesCount, out _branchesCount); this.WhenAnyValue(x => x.Repository.Name) .StartWith(repositoryName) .Subscribe(x => Title = x); LoadCommand = ReactiveCommand.CreateFromTask(async _ => { Repository = await applicationService.Client.Repositories.Get(username, repositoryName); _applicationService.Client.Repositories.GetWatchers(username, repositoryName) .ToBackground(x => Watchers = x.Size); _applicationService.Client.Repositories.GetForks(username, repositoryName) .ToBackground(x => Forks = x.Size); _applicationService.Client.Repositories.GetBranches(username, repositoryName) .ToBackground(x => _branches.Reset(x)); if (!Repository.HasIssues) { Issues = 0; } else { _applicationService.Client.Issues.GetAll(username, repositoryName, limit: 0) .ToBackground(x => Issues = x.Count); } LoadReadme(username, repositoryName).ToBackground(); }); ForkCommand = ReactiveCommand.CreateFromTask(async _ => { var fork = await applicationService.Client.Repositories.Fork(username, repositoryName); NavigateTo(new RepositoryViewModel(fork.Owner, fork.Slug)); }); var canGoToFork = this.WhenAnyValue(x => x.Repository) .Select(x => x?.Parent != null); GoToForkParentCommand = ReactiveCommand.Create(() => { var id = RepositoryIdentifier.FromFullName(Repository.Parent.FullName); NavigateTo(new RepositoryViewModel(id.Owner, id.Name)); }, canGoToFork); GoToReadmeCommand = ReactiveCommand.Create( () => NavigateTo(new ReadmeViewModel(username, repositoryName, _readmeFilename)), this.WhenAnyValue(x => x.HasReadme)); GoToPullRequestsCommand .Select(_ => new PullRequestsViewModel(username, repositoryName)) .Subscribe(NavigateTo); GoToWikiCommand = ReactiveCommand.Create( () => NavigateTo(new WikiViewModel(username, repositoryName)), this.WhenAnyValue(x => x.Repository.HasWiki)); GoToSourceCommand .Select(_ => new BranchesAndTagsViewModel(username, repositoryName)) .Subscribe(NavigateTo); GoToIssuesCommand .Select(_ => new IssuesViewModel(username, repositoryName)) .Subscribe(NavigateTo); GoToOwnerCommand .Select(_ => new UserViewModel(username)) .Subscribe(NavigateTo); GoToStargazersCommand .Select(_ => new RepositoryWatchersViewModel(username, repositoryName)) .Subscribe(NavigateTo); GoToEventsCommand .Select(_ => new RepositoryEventsViewModel(username, repositoryName)) .Subscribe(NavigateTo); GoToBranchesCommand .Select(_ => BranchesViewModel.ForSource(username, repositoryName)) .Subscribe(NavigateTo); var validWebsite = this.WhenAnyValue(x => x.Repository.Website) .Select(x => !string.IsNullOrEmpty(x)); GoToWebsiteCommand = ReactiveCommand.Create( () => NavigateTo(new WebBrowserViewModel(Repository.Website)), validWebsite); GoToCommitsCommand .Subscribe(_ => { if (_branches.Count == 1) { NavigateTo(new CommitsViewModel(username, repositoryName, _branches.FirstOrDefault()?.Node)); } else { NavigateTo(BranchesViewModel.ForCommits(username, repositoryName)); } }); ShowMenuCommand = ReactiveCommand.CreateFromTask(sender => { var menu = actionMenuService.Create(); var isPinned = applicationService .Account.PinnedRepositories .Any(x => string.Equals(x.Owner, username, StringComparison.OrdinalIgnoreCase) && string.Equals(x.Slug, repositoryName, StringComparison.OrdinalIgnoreCase)); var pinned = isPinned ? "Unpin from Slideout Menu" : "Pin to Slideout Menu"; menu.AddButton(pinned, _ => PinRepository()); menu.AddButton("Fork Repository", _ => ForkCommand.ExecuteNow()); menu.AddButton("Show in Bitbucket", _ => { var htmlUrl = ("https://bitbucket.org/" + username + "/" + repositoryName).ToLower(); NavigateTo(new WebBrowserViewModel(htmlUrl)); }); return(menu.Show(sender)); }); }