Skip to content
This repository was archived by the owner on Jul 2, 2022. It is now read-only.

Commit 9d9e7f8

Browse files
committed
Added trending repositories
1 parent 57003bb commit 9d9e7f8

11 files changed

Lines changed: 282 additions & 14 deletions

File tree

CodeHub.Core/CodeHub.Core.iOS.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@
129129
<Compile Include="ViewModels\App\UpgradesViewModel.cs" />
130130
<Compile Include="ViewModels\Gists\GistCreateViewModel.cs" />
131131
<Compile Include="Messages\GistAddMessage.cs" />
132+
<Compile Include="ViewModels\Repositories\RepositoriesTrendingViewModel.cs" />
132133
</ItemGroup>
133134
<ItemGroup />
134135
<ItemGroup>

CodeHub.Core/ViewModels/App/MenuViewModel.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,12 @@ public ICommand GoToExploreRepositoriesCommand
119119
get { return new MvxCommand(() => ShowMenuViewModel<RepositoriesExploreViewModel>(null));}
120120
}
121121

122+
[PotentialStartupViewAttribute("Trending Repositories")]
123+
public ICommand GoToTrendingRepositoriesCommand
124+
{
125+
get { return new MvxCommand(() => ShowMenuViewModel<RepositoriesTrendingViewModel>(null));}
126+
}
127+
122128
public ICommand GoToOrganizationEventsCommand
123129
{
124130
get { return new MvxCommand<string>(x => ShowMenuViewModel<Events.UserEventsViewModel>(new Events.UserEventsViewModel.NavObject { Username = x }));}
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
using System;
2+
using CodeFramework.Core.ViewModels;
3+
using System.Windows.Input;
4+
using System.Threading.Tasks;
5+
using Cirrious.MvvmCross.ViewModels;
6+
using CodeFramework.Core.Services;
7+
using System.Collections.Generic;
8+
9+
namespace CodeHub.Core.ViewModels.Repositories
10+
{
11+
public class RepositoriesTrendingViewModel : LoadableViewModel
12+
{
13+
private const string LanguagesUrl = "http://codehub-trending.herokuapp.com/languages";
14+
private const string TrendingUrl = "http://codehub-trending.herokuapp.com/trending";
15+
private readonly IJsonHttpClientService _jsonHttpClient;
16+
private readonly TimeModel[] _times =
17+
{
18+
new TimeModel { Name = "Daily", Slug = "daily" },
19+
new TimeModel { Name = "Weekly", Slug = "weekly" },
20+
new TimeModel { Name = "Monthly", Slug = "monthly" }
21+
};
22+
private readonly LanguageModel _defaultLanguage = new LanguageModel { Name = "All Languages", Slug = null };
23+
24+
public TimeModel[] Times
25+
{
26+
get { return _times; }
27+
}
28+
29+
private readonly CollectionViewModel<RepositoryModel> _repositories = new CollectionViewModel<RepositoryModel>();
30+
public CollectionViewModel<RepositoryModel> Repositories
31+
{
32+
get { return _repositories; }
33+
}
34+
35+
private readonly CollectionViewModel<LanguageModel> _languages = new CollectionViewModel<LanguageModel>();
36+
public CollectionViewModel<LanguageModel> Languages
37+
{
38+
get { return _languages; }
39+
}
40+
41+
private LanguageModel _selectedLanguage;
42+
public LanguageModel SelectedLanguage
43+
{
44+
get { return _selectedLanguage; }
45+
set
46+
{
47+
if (object.Equals(_selectedLanguage, value))
48+
return;
49+
_selectedLanguage = value;
50+
RaisePropertyChanged(() => SelectedLanguage);
51+
}
52+
}
53+
54+
private TimeModel _selectedTime;
55+
public TimeModel SelectedTime
56+
{
57+
get { return _selectedTime; }
58+
set
59+
{
60+
if (object.Equals(_selectedTime, value))
61+
return;
62+
_selectedTime = value;
63+
RaisePropertyChanged(() => SelectedTime);
64+
}
65+
}
66+
67+
68+
public bool ShowRepositoryDescription
69+
{
70+
get { return this.GetApplication().Account.ShowRepositoryDescriptionInList; }
71+
}
72+
73+
public RepositoriesTrendingViewModel(IJsonHttpClientService jsonHttpClient)
74+
{
75+
_jsonHttpClient = jsonHttpClient;
76+
}
77+
78+
public void Init()
79+
{
80+
SelectedTime = Times[0];
81+
SelectedLanguage = _defaultLanguage;
82+
GetLanguages().FireAndForget();
83+
this.Bind(x => x.SelectedTime, () => LoadCommand.Execute(null));
84+
this.Bind(x => x.SelectedLanguage, () => LoadCommand.Execute(null));
85+
}
86+
87+
public ICommand GoToRepositoryCommand
88+
{
89+
get { return new MvxCommand<RepositoryModel>(x => ShowViewModel<RepositoryViewModel>(new RepositoryViewModel.NavObject { Username = x.Owner, Repository = x.Name })); }
90+
}
91+
92+
protected override async Task Load(bool forceCacheInvalidation)
93+
{
94+
var query = "?";
95+
if (SelectedLanguage != null && SelectedLanguage.Slug != null)
96+
query += string.Format("language={0}&", SelectedLanguage.Slug);
97+
if (SelectedTime != null && SelectedTime.Slug != null)
98+
query += string.Format("since={0}", SelectedTime.Slug);
99+
100+
var repos = await _jsonHttpClient.Get<List<RepositoryModel>>(TrendingUrl + query);
101+
Repositories.Items.Clear();
102+
Repositories.Items.Reset(repos);
103+
}
104+
105+
106+
private async Task GetLanguages()
107+
{
108+
var languages = await _jsonHttpClient.Get<List<LanguageModel>>(LanguagesUrl);
109+
languages.Insert(0, _defaultLanguage);
110+
Languages.Items.Reset(languages);
111+
}
112+
113+
public class LanguageModel
114+
{
115+
public string Name { get; set; }
116+
public string Slug { get; set; }
117+
118+
public override bool Equals(object obj)
119+
{
120+
if (obj == null)
121+
return false;
122+
if (ReferenceEquals(this, obj))
123+
return true;
124+
if (obj.GetType() != typeof(LanguageModel))
125+
return false;
126+
LanguageModel other = (LanguageModel)obj;
127+
return Name == other.Name && Slug == other.Slug;
128+
}
129+
130+
131+
public override int GetHashCode()
132+
{
133+
unchecked
134+
{
135+
return (Name != null ? Name.GetHashCode() : 0) ^ (Slug != null ? Slug.GetHashCode() : 0);
136+
}
137+
}
138+
139+
}
140+
141+
public class TimeModel
142+
{
143+
public string Name { get; set; }
144+
public string Slug { get; set; }
145+
146+
public override bool Equals(object obj)
147+
{
148+
if (obj == null)
149+
return false;
150+
if (ReferenceEquals(this, obj))
151+
return true;
152+
if (obj.GetType() != typeof(TimeModel))
153+
return false;
154+
TimeModel other = (TimeModel)obj;
155+
return Name == other.Name && Slug == other.Slug;
156+
}
157+
158+
public override int GetHashCode()
159+
{
160+
unchecked
161+
{
162+
return (Name != null ? Name.GetHashCode() : 0) ^ (Slug != null ? Slug.GetHashCode() : 0);
163+
}
164+
}
165+
166+
}
167+
168+
public class RepositoryModel
169+
{
170+
public string Url { get; set; }
171+
public string Owner { get; set; }
172+
public string Name { get; set; }
173+
public string Description { get; set; }
174+
public int Stars { get; set; }
175+
public int Forks { get; set; }
176+
}
177+
}
178+
}
179+

CodeHub.iOS/CodeHub.iOS.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@
211211
<Compile Include="XCallbackProvider.cs" />
212212
<Compile Include="Views\Gists\GistCreateView.cs" />
213213
<None Include="Entitlements.plist" />
214+
<Compile Include="Views\Repositories\RepositoriesTrendingView.cs" />
214215
</ItemGroup>
215216
<ItemGroup>
216217
<ProjectReference Include="..\lib\CodeFramework\CodeFramework.Core\CodeFramework.Core.iOS.csproj">
@@ -413,6 +414,8 @@
413414
<BundleResource Include="Resources\Icon-76%402x.png" />
414415
<BundleResource Include="Resources\Icon-Small-40.png" />
415416
<BundleResource Include="Resources\Icon-Small-40%402x.png" />
417+
<BundleResource Include="Images\chart%402x.png" />
418+
<BundleResource Include="Images\chart.png" />
416419
</ItemGroup>
417420
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.MonoTouch.CSharp.targets" />
418421
<ItemGroup>

CodeHub.iOS/CodeHub.iOS.sln

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@ Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 2012
44
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeHub.iOS", "CodeHub.iOS.csproj", "{B061316A-F386-4FE2-93B7-555584234FF8}"
55
EndProject
6-
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{F112095C-7262-445E-91C4-D35C1E986E69}"
6+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CodeFramework", "CodeFramework", "{F112095C-7262-445E-91C4-D35C1E986E69}"
77
EndProject
88
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeFramework.Core.iOS", "..\lib\CodeFramework\CodeFramework.Core\CodeFramework.Core.iOS.csproj", "{C99FE7E3-0985-48F1-9EBB-91680A795F0F}"
99
EndProject
10-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeHub.Core.iOS", "..\CodeHub.Core\CodeHub.Core.iOS.csproj", "{B7970173-9022-466B-B57A-7AB1E1F3145F}"
11-
EndProject
1210
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeFramework.iOS", "..\lib\CodeFramework\CodeFramework.iOS\CodeFramework.iOS.csproj", "{2698B412-26A3-4269-AA01-AC3BC79A0F14}"
1311
EndProject
1412
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lib", "Lib", "{F7C14107-24A4-404A-AD12-A12EC9F28490}"
@@ -21,6 +19,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoTouch.Dialog", "..\lib\
2119
EndProject
2220
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UserVoice", "..\lib\CodeFramework\CodeFramework.iOS\lib\monotouch-uservoice\UserVoice\UserVoice.csproj", "{3A0C5D98-D568-43C1-A877-B1BA00BA4A87}"
2321
EndProject
22+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeHub.Core.iOS", "..\CodeHub.Core\CodeHub.Core.iOS.csproj", "{B7970173-9022-466B-B57A-7AB1E1F3145F}"
23+
EndProject
2424
Global
2525
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2626
AdHoc|Any CPU = AdHoc|Any CPU
@@ -367,7 +367,6 @@ Global
367367
EndGlobalSection
368368
GlobalSection(NestedProjects) = preSolution
369369
{C99FE7E3-0985-48F1-9EBB-91680A795F0F} = {F112095C-7262-445E-91C4-D35C1E986E69}
370-
{B7970173-9022-466B-B57A-7AB1E1F3145F} = {F112095C-7262-445E-91C4-D35C1E986E69}
371370
{2698B412-26A3-4269-AA01-AC3BC79A0F14} = {F112095C-7262-445E-91C4-D35C1E986E69}
372371
{89E14828-85BB-4790-9B4E-E44DD4CE000E} = {F7C14107-24A4-404A-AD12-A12EC9F28490}
373372
{6D7B9B53-CFEF-46BE-A608-14A4A1381CF6} = {F7C14107-24A4-404A-AD12-A12EC9F28490}

CodeHub.iOS/Images/Images.cs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,10 @@ namespace CodeHub.iOS
88
public static class Images
99
{
1010
public static UIImage Merge { get { return UIImage.FromBundle("/Images/merge"); } }
11-
public static UIImage Language { get { return UIImage.FromBundle("/Images/language"); } }
1211
public static UIImage Webpage { get { return UIImage.FromBundle("/Images/webpage"); } }
1312
public static UIImage Repo { get { return UIImage.FromBundle("/Images/repo"); } }
1413
public static UIImage Team { get { return UIImageHelper.FromFileAuto("Images/team"); } }
1514
public static UIImage Size { get { return UIImage.FromBundle("/Images/size"); } }
16-
public static UIImage Locked { get { return UIImage.FromBundle("/Images/locked"); } }
17-
public static UIImage Unlocked { get { return UIImage.FromBundle("/Images/unlocked"); } }
1815
public static UIImage Heart { get { return UIImage.FromBundle("/Images/heart"); } }
1916
public static UIImage Fork { get { return UIImage.FromBundle("/Images/fork"); } }
2017
public static UIImage Pencil { get { return UIImage.FromBundle("/Images/pencil"); } }
@@ -31,21 +28,26 @@ public static class Images
3128
public static UIImage File { get { return UIImage.FromBundle("/Images/file"); } }
3229
public static UIImage Branch { get { return UIImage.FromBundle("/Images/branch"); } }
3330
public static UIImage Create { get { return UIImage.FromBundle("/Images/create"); } }
34-
public static UIImage Info { get { return UIImage.FromBundle("/Images/info"); } }
3531
public static UIImage Flag { get { return UIImage.FromBundle("/Images/flag"); } }
3632
public static UIImage User { get { return UIImage.FromBundle("/Images/user"); } }
37-
public static UIImage Explore { get { return UIImage.FromBundle("/Images/explore"); } }
3833
public static UIImage Group { get { return UIImage.FromBundle("/Images/group"); } }
3934
public static UIImage Event { get { return UIImage.FromBundle("/Images/events"); } }
4035
public static UIImage Person { get { return UIImage.FromBundle("/Images/person"); } }
4136
public static UIImage Cog { get { return UIImage.FromBundle("/Images/cog"); } }
4237
public static UIImage Star { get { return UIImage.FromBundle("/Images/star"); } }
4338
public static UIImage Star2 { get { return UIImage.FromBundle("/Images/star2"); } }
44-
public static UIImage News { get { return UIImage.FromBundle("/Images/news"); } }
4539
public static UIImage Public { get { return UIImage.FromBundle("/Images/public"); } }
46-
public static UIImage Notifications { get { return UIImage.FromBundle("/Images/notifications"); } }
4740
public static UIImage Priority { get { return UIImage.FromBundle("/Images/priority"); } }
48-
public static UIImage Anonymous { get { return UIImage.FromBundle("/Images/anonymous"); } }
41+
public static UIImage Anonymous { get { return UIImage.FromBundle("/Images/anonymous"); } }
42+
43+
public static UIImage News { get { return UIImageHelper.FromFileAuto("Images/news"); } }
44+
public static UIImage Chart { get { return UIImageHelper.FromFileAuto("Images/chart"); } }
45+
public static UIImage Explore { get { return UIImageHelper.FromFileAuto("Images/explore"); } }
46+
public static UIImage Notifications { get { return UIImageHelper.FromFileAuto("Images/notifications"); } }
47+
public static UIImage Info { get { return UIImageHelper.FromFileAuto("Images/info"); } }
48+
public static UIImage Language { get { return UIImageHelper.FromFileAuto("Images/language"); } }
49+
public static UIImage Unlocked { get { return UIImageHelper.FromFileAuto("Images/unlocked"); } }
50+
public static UIImage Locked { get { return UIImageHelper.FromFileAuto("Images/locked"); } }
4951

5052
public static Uri GitHubRepoUrl
5153
{

CodeHub.iOS/Images/chart.png

656 Bytes
Loading

CodeHub.iOS/Images/chart@2x.png

1.17 KB
Loading

CodeHub.iOS/Views/App/MenuView.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ protected override void CreateMenuRoot()
4444
repoSection.Add(new MenuElement("Owned", () => ViewModel.GoToOwnedRepositoriesCommand.Execute(null), Images.Repo));
4545
//repoSection.Add(new MenuElement("Watching", () => NavPush(new WatchedRepositoryController(Application.Accounts.ActiveAccount.Username)), Images.RepoFollow));
4646
repoSection.Add(new MenuElement("Starred", () => ViewModel.GoToStarredRepositoriesCommand.Execute(null), Images.Star));
47-
repoSection.Add(new MenuElement("Explore", () => ViewModel.GoToExploreRepositoriesCommand.Execute(null), Images.Explore));
47+
repoSection.Add(new MenuElement("Trending", () => ViewModel.GoToTrendingRepositoriesCommand.Execute(null), Images.Chart));
48+
repoSection.Add(new MenuElement("Explore", () => ViewModel.GoToExploreRepositoriesCommand.Execute(null), Images.Explore));
4849
root.Add(repoSection);
4950

5051
if (ViewModel.PinnedRepositories.Count() > 0)
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
using System;
2+
using CodeFramework.iOS.Elements;
3+
using CodeFramework.ViewControllers;
4+
using CodeFramework.iOS.Utils;
5+
using CodeHub.Core.ViewModels.Repositories;
6+
using MonoTouch.UIKit;
7+
using System.Linq;
8+
9+
namespace CodeHub.iOS.Views.Repositories
10+
{
11+
public class RepositoriesTrendingView : ViewModelCollectionDrivenDialogViewController
12+
{
13+
public RepositoriesTrendingView()
14+
{
15+
EnableSearch = false;
16+
NoItemsText = "No Repositories".t();
17+
Title = "Trending".t();
18+
}
19+
20+
public override void ViewDidLoad()
21+
{
22+
base.ViewDidLoad();
23+
var vm = (RepositoriesTrendingViewModel)ViewModel;
24+
25+
BindCollection(vm.Repositories, repo =>
26+
{
27+
var description = vm.ShowRepositoryDescription ? repo.Description : string.Empty;
28+
var imageUrl = Images.GitHubRepoUrl;
29+
var sse = new RepositoryElement(repo.Name, repo.Stars, repo.Forks, description, repo.Owner, imageUrl) { ShowOwner = true };
30+
sse.Tapped += () => vm.GoToRepositoryCommand.Execute(repo);
31+
return sse;
32+
});
33+
34+
var button = new UIBarButtonItem("Time", UIBarButtonItemStyle.Plain, (s, e) =>
35+
{
36+
var index = vm.SelectedTime == null ? 0 : vm.Times.ToList().IndexOf(vm.SelectedTime);
37+
if (index < 0) index = 0;
38+
new PickerAlert(vm.Times.Select(x => x.Name).ToArray(), index, x => vm.SelectedTime = vm.Times[x]).Show();
39+
});
40+
41+
var button2 = new UIBarButtonItem("Language", UIBarButtonItemStyle.Plain, (s, e) =>
42+
{
43+
var index = vm.SelectedLanguage == null ? 0 : vm.Languages.ToList().IndexOf(vm.SelectedLanguage);
44+
if (index < 0) index = 0;
45+
new PickerAlert(vm.Languages.Select(x => x.Name).ToArray(), index, x => vm.SelectedLanguage = vm.Languages.ElementAt(x)).Show();
46+
47+
});
48+
49+
vm.Bind(x => x.SelectedTime, x => button.Title = x.Name, true);
50+
vm.Bind(x => x.SelectedLanguage, x => button2.Title = x.Name, true);
51+
52+
ToolbarItems = new UIBarButtonItem[]
53+
{
54+
new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace),
55+
button2,
56+
new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace),
57+
button,
58+
new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace)
59+
};
60+
}
61+
62+
public override void ViewWillAppear(bool animated)
63+
{
64+
if (ToolbarItems != null)
65+
NavigationController.SetToolbarHidden(false, animated);
66+
base.ViewWillAppear(animated);
67+
}
68+
69+
public override void ViewWillDisappear(bool animated)
70+
{
71+
base.ViewWillDisappear(animated);
72+
if (ToolbarItems != null)
73+
NavigationController.SetToolbarHidden(true, animated);
74+
}
75+
}
76+
}
77+

0 commit comments

Comments
 (0)