diff --git a/CodeHub.Core/CodeHub.Core.iOS.csproj b/CodeHub.Core/CodeHub.Core.iOS.csproj index da912607..ea2dff61 100644 --- a/CodeHub.Core/CodeHub.Core.iOS.csproj +++ b/CodeHub.Core/CodeHub.Core.iOS.csproj @@ -43,7 +43,6 @@ - diff --git a/CodeHub.Core/Factories/ILoginFactory.cs b/CodeHub.Core/Factories/ILoginFactory.cs index 9e71dfbc..a2ac6c0e 100755 --- a/CodeHub.Core/Factories/ILoginFactory.cs +++ b/CodeHub.Core/Factories/ILoginFactory.cs @@ -5,7 +5,7 @@ namespace CodeHub.Core.Factories { public interface ILoginFactory { - Task LoginWithToken(string clientId, string clientSecret, string code, string redirect, string requestDomain, string apiDomain, GitHubAccount existingAccount); + Task LoginWithToken(string clientId, string clientSecret, string code, string redirect, string requestDomain, string apiDomain); Task LoginAccount(GitHubAccount account); diff --git a/CodeHub.Core/Factories/LoginFactory.cs b/CodeHub.Core/Factories/LoginFactory.cs index 3d61a0ee..206ee9f2 100755 --- a/CodeHub.Core/Factories/LoginFactory.cs +++ b/CodeHub.Core/Factories/LoginFactory.cs @@ -3,6 +3,7 @@ using CodeHub.Core.Data; using GitHubSharp; using System.Threading.Tasks; +using System.Linq; namespace CodeHub.Core.Factories { @@ -16,7 +17,7 @@ public LoginFactory(IAccountsService accounts) _accounts = accounts; } - public async Task LoginWithToken(string clientId, string clientSecret, string code, string redirect, string requestDomain, string apiDomain, GitHubAccount account) + public async Task LoginWithToken(string clientId, string clientSecret, string code, string redirect, string requestDomain, string apiDomain) { var token = await Client.RequestAccessToken(clientId, clientSecret, code, redirect, requestDomain); var client = Client.BasicOAuth(token.AccessToken, apiDomain); @@ -24,9 +25,11 @@ public async Task LoginWithToken(string clientId, string clientSecret var username = info.Data.Login; //Does this user exist? + + var account = _accounts.FirstOrDefault(x => string.Equals(x.Username, username) && string.Equals(x.Domain, apiDomain)); var exists = account != null; - if (!exists) - account = new GitHubAccount { Username = username }; + account = account ?? new GitHubAccount { Username = username }; + account.OAuth = token.AccessToken; account.AvatarUrl = info.Data.AvatarUrl; account.Domain = apiDomain; diff --git a/CodeHub.Core/Services/AccountsService.cs b/CodeHub.Core/Services/AccountsService.cs index 89d72eeb..8ecb42e4 100755 --- a/CodeHub.Core/Services/AccountsService.cs +++ b/CodeHub.Core/Services/AccountsService.cs @@ -7,15 +7,15 @@ namespace CodeHub.Core.Services { - public abstract class AccountsService : IAccountsService where TAccount : class, IAccount, new() + public class AccountsService : IAccountsService { private readonly SQLiteConnection _userDatabase; private readonly IDefaultValueService _defaults; private readonly string _accountsPath; - public IAccount ActiveAccount { get; private set; } + public GitHubAccount ActiveAccount { get; private set; } - protected AccountsService(IDefaultValueService defaults, IAccountPreferencesService accountPreferences) + public AccountsService(IDefaultValueService defaults, IAccountPreferencesService accountPreferences) { _defaults = defaults; _accountsPath = accountPreferences.AccountsDir; @@ -25,16 +25,16 @@ protected AccountsService(IDefaultValueService defaults, IAccountPreferencesServ Directory.CreateDirectory(_accountsPath); _userDatabase = new SQLiteConnection(Path.Combine(_accountsPath, "accounts.db")); - _userDatabase.CreateTable(); + _userDatabase.CreateTable(); } - public IAccount GetDefault() + public GitHubAccount GetDefault() { int id; return !_defaults.TryGet("DEFAULT_ACCOUNT", out id) ? null : Find(id); } - public void SetDefault(IAccount account) + public void SetDefault(GitHubAccount account) { if (account == null) _defaults.Set("DEFAULT_ACCOUNT", null); @@ -42,7 +42,7 @@ public void SetDefault(IAccount account) _defaults.Set("DEFAULT_ACCOUNT", account.Id); } - public void SetActiveAccount(IAccount account) + public void SetActiveAccount(GitHubAccount account) { if (account != null) { @@ -54,12 +54,12 @@ public void SetActiveAccount(IAccount account) ActiveAccount = account; } - protected string CreateAccountDirectory(IAccount account) + protected string CreateAccountDirectory(GitHubAccount account) { return Path.Combine(_accountsPath, account.Id.ToString(CultureInfo.InvariantCulture)); } - public void Insert(IAccount account) + public void Insert(GitHubAccount account) { lock (_userDatabase) { @@ -67,7 +67,7 @@ public void Insert(IAccount account) } } - public void Remove(IAccount account) + public void Remove(GitHubAccount account) { lock (_userDatabase) { @@ -80,7 +80,7 @@ public void Remove(IAccount account) Directory.Delete(accountDir, true); } - public void Update(IAccount account) + public void Update(GitHubAccount account) { lock (_userDatabase) { @@ -88,23 +88,24 @@ public void Update(IAccount account) } } - public bool Exists(IAccount account) + public bool Exists(GitHubAccount account) { return Find(account.Id) != null; } - public IAccount Find(int id) + public GitHubAccount Find(int id) { lock (_userDatabase) { - var query = _userDatabase.Find(x => x.Id == id); + var query = _userDatabase.Find(x => x.Id == id); return query; } } - public IEnumerator GetEnumerator() + public IEnumerator GetEnumerator() { - return _userDatabase.Table().GetEnumerator(); + foreach (var account in _userDatabase.Table()) + yield return account; } IEnumerator IEnumerable.GetEnumerator() diff --git a/CodeHub.Core/Services/GitHubAccountsService.cs b/CodeHub.Core/Services/GitHubAccountsService.cs deleted file mode 100755 index 77d3a579..00000000 --- a/CodeHub.Core/Services/GitHubAccountsService.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using CodeHub.Core.Services; -using CodeHub.Core.Data; - -namespace CodeHub.Core.Services -{ - public class GitHubAccountsService : AccountsService - { - public GitHubAccountsService(IDefaultValueService defaults, IAccountPreferencesService accountPreferences) - : base(defaults, accountPreferences) - { - } - } -} diff --git a/CodeHub.Core/Services/IAccountsService.cs b/CodeHub.Core/Services/IAccountsService.cs index e3e45603..b9cfed5f 100755 --- a/CodeHub.Core/Services/IAccountsService.cs +++ b/CodeHub.Core/Services/IAccountsService.cs @@ -3,52 +3,52 @@ namespace CodeHub.Core.Services { - public interface IAccountsService : IEnumerable + public interface IAccountsService : IEnumerable { /// /// Gets the active account /// - IAccount ActiveAccount { get; } + GitHubAccount ActiveAccount { get; } /// /// Sets the active account /// /// - void SetActiveAccount(IAccount account); + void SetActiveAccount(GitHubAccount account); /// /// Gets the default account /// - IAccount GetDefault(); + GitHubAccount GetDefault(); /// /// Sets the default account /// - void SetDefault(IAccount account); + void SetDefault(GitHubAccount account); /// /// Insert the specified account. /// - void Insert(IAccount account); + void Insert(GitHubAccount account); /// /// Remove the specified account. /// - void Remove(IAccount account); + void Remove(GitHubAccount account); /// /// Update this instance in the database /// - void Update(IAccount account); + void Update(GitHubAccount account); /// /// Checks to see whether a specific account exists (Username comparison) /// - bool Exists(IAccount account); + bool Exists(GitHubAccount account); /// /// Find the specified account via it's username /// - IAccount Find(int id); + GitHubAccount Find(int id); } } \ No newline at end of file diff --git a/CodeHub.Core/ViewModels/Accounts/LoginViewModel.cs b/CodeHub.Core/ViewModels/Accounts/LoginViewModel.cs index 64ea6c57..97b2cbe6 100644 --- a/CodeHub.Core/ViewModels/Accounts/LoginViewModel.cs +++ b/CodeHub.Core/ViewModels/Accounts/LoginViewModel.cs @@ -43,8 +43,6 @@ public string LoginUrl } } - public bool IsEnterprise { get; private set; } - public GitHubAccount AttemptedAccount { get; private set; } public string WebDomain { get; set; } @@ -62,63 +60,25 @@ public LoginViewModel(ILoginFactory loginFactory, IFeaturesService featuresServi public void Init(NavObject navObject) { - IsEnterprise = navObject.IsEnterprise; - WebDomain = navObject.WebDomain; - - if (WebDomain == null && !IsEnterprise) - { - WebDomain = GitHubSharp.Client.AccessTokenUri; - } + WebDomain = navObject.WebDomain ?? GitHubSharp.Client.AccessTokenUri; if (navObject.AttemptedAccountId >= 0) { - AttemptedAccount = this.GetApplication().Accounts.Find(navObject.AttemptedAccountId) as GitHubAccount; - - //This is a hack to get around the fact that WebDomain will be null for Enterprise users since the last version did not contain the variable - if (WebDomain == null && IsEnterprise) - { - try - { - WebDomain = AttemptedAccount.Domain.Substring(0, AttemptedAccount.Domain.IndexOf("/api")); - } - catch - { - //Doh! - } - } + AttemptedAccount = this.GetApplication().Accounts.Find(navObject.AttemptedAccountId); } } public async Task Login(string code) { - string apiUrl; - if (IsEnterprise) - { - apiUrl = WebDomain; - if (!apiUrl.StartsWith("http://") && !apiUrl.StartsWith("https://")) - apiUrl = "https://" + apiUrl; - if (!apiUrl.EndsWith("/")) - apiUrl += "/"; - if (!apiUrl.Contains("/api/")) - apiUrl += "api/v3/"; - - apiUrl = apiUrl.TrimEnd('/'); - } - else - { - apiUrl = GitHubSharp.Client.DefaultApi; - } - LoginData loginData = null; bool shouldPromptPush = false; try { IsLoggingIn = true; - var account = AttemptedAccount; - loginData = await _loginFactory.LoginWithToken(ClientId, ClientSecret, code, RedirectUri, WebDomain, apiUrl, account); + loginData = await _loginFactory.LoginWithToken(ClientId, ClientSecret, code, RedirectUri, WebDomain, GitHubSharp.Client.DefaultApi); - if (!_featuresService.IsPushNotificationsActivated && !IsEnterprise) + if (!_featuresService.IsPushNotificationsActivated) { try { @@ -157,7 +117,6 @@ public async Task Login(string code) public class NavObject { public string Username { get; set; } - public bool IsEnterprise { get; set; } public string WebDomain { get; set; } public int AttemptedAccountId { get; set; } @@ -171,7 +130,6 @@ public static NavObject CreateDontRemember(GitHubAccount account) return new NavObject { WebDomain = account.WebDomain, - IsEnterprise = !string.Equals(account.Domain, GitHubSharp.Client.DefaultApi), Username = account.Username, AttemptedAccountId = account.Id }; diff --git a/CodeHub.Core/ViewModels/App/StartupViewModel.cs b/CodeHub.Core/ViewModels/App/StartupViewModel.cs index 430242dc..0e23dba8 100644 --- a/CodeHub.Core/ViewModels/App/StartupViewModel.cs +++ b/CodeHub.Core/ViewModels/App/StartupViewModel.cs @@ -38,6 +38,17 @@ protected async override void Startup() if (account.DontRemember) { ShowViewModel(); + + //Hack for now + if (isEnterprise) + { + ShowViewModel(new Accounts.AddAccountViewModel.NavObject { AttemptedAccountId = account.Id }); + } + else + { + ShowViewModel(Accounts.LoginViewModel.NavObject.CreateDontRemember(account)); + } + return; } diff --git a/CodeHub.iOS/Elements/IssueElement.cs b/CodeHub.iOS/Elements/IssueElement.cs index 79042c7f..95f2f324 100755 --- a/CodeHub.iOS/Elements/IssueElement.cs +++ b/CodeHub.iOS/Elements/IssueElement.cs @@ -53,7 +53,7 @@ protected override NSString CellKey { public override UITableViewCell GetCell (UITableView tv) { var cell = tv.DequeueReusableCell(CellKey) as IssueCellView ?? IssueCellView.Create(); - cell.Bind(Title, Status, Priority, Assigned, LastUpdated, Id, Kind); + cell.Bind(Title, Status, Priority, Assigned, LastUpdated, Id, Kind); return cell; } diff --git a/CodeHub.iOS/Elements/SplitViewElement.cs b/CodeHub.iOS/Elements/SplitViewElement.cs index 69dd76ba..a9b29083 100644 --- a/CodeHub.iOS/Elements/SplitViewElement.cs +++ b/CodeHub.iOS/Elements/SplitViewElement.cs @@ -144,16 +144,22 @@ public SplitButton(UIImage image, string text = null) _text.MinimumScaleFactor = 0.7f; this.Add(_text); } + + private static bool IsPad = UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad; + public override void LayoutSubviews() { base.LayoutSubviews(); + var offset = IsPad ? 24f : 18f; + var rightOffset = IsPad ? 16f : 14f; + var height = (this.Bounds.Height - 24f); - _image.Frame = new CGRect(15, 12, height, height); + _image.Frame = new CGRect(offset, 12, height, height); var textHeight = (int)Math.Ceiling(TextFont.LineHeight) + 1; var textY = (this.Bounds.Height / 2) - (textHeight / 2); - _text.Frame = new CGRect(_image.Frame.Right + 10f, textY, (int)Math.Floor(this.Bounds.Width) - (_image.Frame.Right + 10f + _image.Frame.Left), textHeight); + _text.Frame = new CGRect(_image.Frame.Right + rightOffset, textY, (int)Math.Floor(this.Bounds.Width) - (_image.Frame.Right + rightOffset + _image.Frame.Left), textHeight); } } } diff --git a/CodeHub.iOS/Info.plist b/CodeHub.iOS/Info.plist index ac6220d1..d3d3f47a 100755 --- a/CodeHub.iOS/Info.plist +++ b/CodeHub.iOS/Info.plist @@ -21,7 +21,7 @@ CFBundleIdentifier com.dillonbuchanan.codehub CFBundleShortVersionString - 2.4.0 + 2.5.0 UIStatusBarTintParameters UINavigationBar @@ -55,7 +55,7 @@ UIInterfaceOrientationLandscapeRight CFBundleVersion - 2.4.0.1 + 2.5.0.1 UILaunchStoryboardName Launch NSAppTransportSecurity diff --git a/CodeHub.iOS/OcticonExtensions.cs b/CodeHub.iOS/OcticonExtensions.cs index 73bfa590..47af1d9c 100644 --- a/CodeHub.iOS/OcticonExtensions.cs +++ b/CodeHub.iOS/OcticonExtensions.cs @@ -9,17 +9,28 @@ namespace CodeHub { public static class OcticonExtensions { - private static readonly bool IsRetnia; + private static readonly nfloat Scale; static OcticonExtensions() { - IsRetnia = UIScreen.MainScreen.Scale > 1; + Scale = UIScreen.MainScreen.Scale; } public static UIImage ToImage(this Octicon @this, nfloat size, bool cache = true) { var cacheDir = NSFileManager.DefaultManager.GetUrls(NSSearchPathDirectory.CachesDirectory, NSSearchPathDomain.User)[0].Path; - var fileName = string.Format("octicon-{0}-{1}{2}.png", (int)@this.CharacterCode, size, IsRetnia ? "@2x" : string.Empty); + + string extension = string.Empty; + if (Scale > 1 && Scale < 3) + { + extension = "@2x"; + } + else if (Scale >= 3) + { + extension = "@3x"; + } + + var fileName = string.Format("octicon-{0}-{1}{2}.png", (int)@this.CharacterCode, size, extension); var combinedPath = Path.Combine(cacheDir, fileName); if (File.Exists(combinedPath)) diff --git a/CodeHub.iOS/Utilities/PickerAlert.cs b/CodeHub.iOS/Utilities/PickerAlert.cs index eaef0fd6..4fbec20f 100644 --- a/CodeHub.iOS/Utilities/PickerAlert.cs +++ b/CodeHub.iOS/Utilities/PickerAlert.cs @@ -71,6 +71,10 @@ public override void LayoutSubviews() { base.LayoutSubviews(); Frame = Superview.Bounds; + + + _pickerView.Frame = new CGRect(0, 44f, Frame.Width, _pickerView.Frame.Height); + _pickerView.SetNeedsLayout(); } diff --git a/CodeHub.iOS/ViewControllers/DialogViewController.cs b/CodeHub.iOS/ViewControllers/DialogViewController.cs index a0a2bbb9..759b576e 100644 --- a/CodeHub.iOS/ViewControllers/DialogViewController.cs +++ b/CodeHub.iOS/ViewControllers/DialogViewController.cs @@ -655,6 +655,12 @@ public event EventHandler ViewDissapearing { } } + public override void ViewDidLoad() + { + base.ViewDidLoad(); + TableView.CellLayoutMarginsFollowReadableWidth = false; + } + public override void ViewWillDisappear (bool animated) { base.ViewWillDisappear (animated); diff --git a/CodeHub.iOS/Views/Accounts/AccountsView.cs b/CodeHub.iOS/Views/Accounts/AccountsView.cs index 149de635..5f224625 100644 --- a/CodeHub.iOS/Views/Accounts/AccountsView.cs +++ b/CodeHub.iOS/Views/Accounts/AccountsView.cs @@ -77,7 +77,7 @@ protected List PopulateAccounts() /// Called when an account is deleted /// /// Account. - protected void AccountDeleted(IAccount account) + protected void AccountDeleted(GitHubAccount account) { //Remove the designated username var thisAccount = account; diff --git a/CodeHub.iOS/Views/Accounts/LoginView.cs b/CodeHub.iOS/Views/Accounts/LoginView.cs index 5fb2ad4a..5e9752d2 100755 --- a/CodeHub.iOS/Views/Accounts/LoginView.cs +++ b/CodeHub.iOS/Views/Accounts/LoginView.cs @@ -1,7 +1,6 @@ using System; using CodeHub.iOS.Views; using CodeHub.Core.ViewModels.Accounts; -using UIKit; using MvvmCross.Platform; using CodeFramework.iOS.Utils; using Foundation; @@ -27,11 +26,7 @@ public override void ViewDidLoad() { base.ViewDidLoad(); - if (!ViewModel.IsEnterprise || ViewModel.AttemptedAccount != null) - LoadRequest(); - var hud = this.CreateHud(); - ViewModel.Bind(x => x.IsLoggingIn, x => { if (x) @@ -39,40 +34,8 @@ public override void ViewDidLoad() else hud.Hide(); }); - } - - public override void ViewDidAppear(bool animated) - { - base.ViewDidAppear(animated); - - if (ViewModel.IsEnterprise && string.IsNullOrEmpty(ViewModel.WebDomain)) - { - Stuff(); - } - } - private void Stuff() - { - var alert = new UIAlertView(); - alert.Title = "Enterprise URL"; - alert.Message = "Please enter the webpage address for the GitHub Enterprise installation"; - alert.CancelButtonIndex = alert.AddButton("Cancel"); - var okButton = alert.AddButton("Ok"); - alert.AlertViewStyle = UIAlertViewStyle.PlainTextInput; - alert.Clicked += (sender, e) => { - if (e.ButtonIndex == okButton) - { - var txt = alert.GetTextField(0); - ViewModel.WebDomain = txt.Text; - LoadRequest(); - } - if (e.ButtonIndex == alert.CancelButtonIndex) - { - ViewModel.GoBackCommand.Execute(null); - } - }; - - alert.Show(); + LoadRequest(); } protected override bool ShouldStartLoad(WKWebView webView, WKNavigationAction navigationAction) @@ -107,13 +70,8 @@ protected override void OnLoadError(NSError e) base.OnLoadError(e); //Frame interrupted error - if (e.Code == 102 || e.Code == -999) - return; - - if (ViewModel.IsEnterprise) - MonoTouch.Utilities.ShowAlert("Error", "Unable to communicate with GitHub with given Url. " + e.LocalizedDescription, Stuff); - else - MonoTouch.Utilities.ShowAlert("Error", "Unable to communicate with GitHub. " + e.LocalizedDescription); + if (e.Code == 102 || e.Code == -999) return; + MonoTouch.Utilities.ShowAlert("Error", "Unable to communicate with GitHub. " + e.LocalizedDescription); } private void LoadRequest() @@ -121,10 +79,9 @@ private void LoadRequest() try { //Remove all cookies & cache - foreach (var c in Foundation.NSHttpCookieStorage.SharedStorage.Cookies) - Foundation.NSHttpCookieStorage.SharedStorage.DeleteCookie(c); - Foundation.NSUrlCache.SharedCache.RemoveAllCachedResponses(); - Web.LoadRequest(new Foundation.NSUrlRequest(new Foundation.NSUrl(ViewModel.LoginUrl))); + WKWebsiteDataStore.DefaultDataStore.RemoveDataOfTypes(WKWebsiteDataStore.AllWebsiteDataTypes, NSDate.FromTimeIntervalSince1970(0), () => { + Web.LoadRequest(new NSUrlRequest(new Foundation.NSUrl(ViewModel.LoginUrl))); + }); } catch (Exception e) { diff --git a/CodeHub.iOS/Views/Events/BaseEventsView.cs b/CodeHub.iOS/Views/Events/BaseEventsView.cs index fabb6faa..3afaefa0 100644 --- a/CodeHub.iOS/Views/Events/BaseEventsView.cs +++ b/CodeHub.iOS/Views/Events/BaseEventsView.cs @@ -42,6 +42,7 @@ protected BaseEventsView() public override void ViewDidLoad() { base.ViewDidLoad(); + TableView.CellLayoutMarginsFollowReadableWidth = false; TableView.SeparatorInset = CodeHub.iOS.TableViewCells.NewsCellView.EdgeInsets; BindCollection(((BaseEventsViewModel)ViewModel).Events, CreateElement); } diff --git a/CodeHub.iOS/Views/Issues/BaseIssuesView.cs b/CodeHub.iOS/Views/Issues/BaseIssuesView.cs index ecde2b38..daad5b80 100644 --- a/CodeHub.iOS/Views/Issues/BaseIssuesView.cs +++ b/CodeHub.iOS/Views/Issues/BaseIssuesView.cs @@ -18,6 +18,12 @@ protected BaseIssuesView() { Root.UnevenRows = true; Title = "Issues".t(); + } + + public override void ViewDidLoad() + { + base.ViewDidLoad(); + TableView.CellLayoutMarginsFollowReadableWidth = false; } protected MonoTouch.Dialog.Element CreateElement(IssueModel x)