protected void Handle_LearnMore( ) { // don't process the link if there's no ReferenceURL if (string.IsNullOrWhiteSpace(NewsItem.ReferenceURL) == false) { // if this is an app-url, then let the task (which forwards it to the springboard) handle it. if (SpringboardViewController.IsAppURL(NewsItem.ReferenceURL) == true) { Task.HandleAppURL(NewsItem.ReferenceURL); } else { // copy the news item's relevant members. That way, if we're running in debug, // and they want to override the news item, we can do that below. string newsUrl = NewsItem.ReferenceURL; bool newsImpersonation = NewsItem.IncludeImpersonationToken; bool newsExternalBrowser = NewsItem.ReferenceUrlLaunchesBrowser; // If we're running a debug build, see if we should override the news #if DEBUG if (DebugConfig.News_Override_Item == true) { newsUrl = DebugConfig.News_Override_ReferenceURL; newsImpersonation = DebugConfig.News_Override_IncludeImpersonationToken; newsExternalBrowser = DebugConfig.News_Override_ReferenceUrlLaunchesBrowser; } #endif TaskWebViewController.HandleUrl(newsExternalBrowser, newsImpersonation, newsUrl, Task, this, false, false, false); } } }
public void RowClicked(int rowIndex) { if (rowIndex > -1) { ConnectLink linkEntry = null; // is this a getEngaged row? if (rowIndex < GetEngagedEntries.Count) { linkEntry = GetEngagedEntries[rowIndex]; } // did they pick something valid? if (linkEntry != null) { // GroupFinder is unique in that it doesn't use a webView. if (linkEntry.Title == ConnectStrings.Main_Connect_GroupFinder) { TaskUIViewController viewController = Storyboard.InstantiateViewController("GroupFinderViewController") as TaskUIViewController; Task.PerformSegue(this, viewController); } else { TaskWebViewController.HandleUrl(false, true, linkEntry.Url, Task, this, false, false, false); } } } }
public override bool OnBackPressed( ) { // if we're displaying a taskViewController, let it handle back. TaskWebViewController webViewController = ActiveViewController as TaskWebViewController; if (webViewController != null) { return(webViewController.OnBackPressed( )); } return(false); }
public override bool OnBackPressed( ) { // if we're displaying a taskViewController, let it handle back. TaskWebViewController webViewController = ActiveViewController as TaskWebViewController; if (webViewController != null) { webViewController.OnBackPressed( ); } // let the container know we're handling it, so that it doesn't need to. return(true); }
public void RowClicked( int rowIndex ) { if ( rowIndex > -1 ) { if ( rowIndex == 0 ) { TaskUIViewController viewController = Storyboard.InstantiateViewController( "GroupFinderViewController" ) as TaskUIViewController; Task.PerformSegue( this, viewController ); } else { TaskWebViewController viewController = new TaskWebViewController( LinkEntries[ rowIndex ].Url, Task ); Task.PerformSegue( this, viewController ); } } }
public override void MakeActive(TaskUINavigationController parentViewController, NavToolbar navToolbar, CGRect containerBounds) { base.MakeActive(parentViewController, navToolbar, containerBounds); MainPageVC = new TaskUIViewController(); MainPageVC.Task = this; MainPageVC.View.Bounds = containerBounds; // set our current page as root parentViewController.PushViewController(MainPageVC, false); // and immediately handle the URL string fullUrl = Rock.Mobile.Util.Strings.Parsers.AddParamToURL(AboutConfig.Url, string.Format(PrivateGeneralConfig.RockCampusContext, MobileApp.Shared.Network.RockMobileUser.Instance.GetRelevantCampus( ))); TaskWebViewController.HandleUrl(false, true, fullUrl, this, MainPageVC, false, true, false, false); }
public void RowClicked(int row) { if (row < News.Count) { // mark that they tapped this item. NewsAnalytic.Instance.Trigger(NewsAnalytic.Read, News[row].News.Title); if (News[row].News.SkipDetailsPage == true && string.IsNullOrEmpty(News[row].News.ReferenceURL) == false) { // if this is an app-url, then let the task (which forwards it to the springboard) handle it. if (SpringboardViewController.IsAppURL(News[row].News.ReferenceURL) == true) { Task.HandleAppURL(News[row].News.ReferenceURL); } else { // copy the news item's relevant members. That way, if we're running in debug, // and they want to override the news item, we can do that below. string newsUrl = News[row].News.ReferenceURL; bool newsImpersonation = News[row].News.IncludeImpersonationToken; bool newsExternalBrowser = News[row].News.ReferenceUrlLaunchesBrowser; // If we're running a debug build, see if we should override the news #if DEBUG if (DebugConfig.News_Override_Item == true) { newsUrl = DebugConfig.News_Override_ReferenceURL; newsImpersonation = DebugConfig.News_Override_IncludeImpersonationToken; newsExternalBrowser = DebugConfig.News_Override_ReferenceUrlLaunchesBrowser; } #endif TaskWebViewController.HandleUrl(newsExternalBrowser, newsImpersonation, newsUrl, Task, this, false, false, false); } } else { NewsDetailsUIViewController viewController = new NewsDetailsUIViewController(); viewController.NewsItem = News[row].News; Task.PerformSegue(this, viewController); } } }
public override void PerformAction(string command, string[] arguments) { base.PerformAction(command, arguments); switch (command) { // is this a goto command? case PrivateGeneralConfig.App_URL_Commands_Goto: { // make sure the argument is for us if (arguments[0] == Command_Keyword( ) && arguments.Length > 1) { // check for groupfinder, because we support that one. if (PrivateGeneralConfig.App_URL_Page_GroupFinder == arguments[1]) { // since we're switching to the read notes VC, pop to the main page root and // remove it, because we dont' want back history (where would they go back to?) ParentViewController.ClearViewControllerStack( ); // create and launch the group finder. It's fine to create it here because we always dynamically create this controller. TaskUIViewController viewController = Storyboard.InstantiateViewController("GroupFinderViewController") as TaskUIViewController; ParentViewController.PushViewController(viewController, false); } else { List <ConnectLink> engagedEntries = ConnectLink.BuildGetEngagedList( ); ConnectLink connectLink = engagedEntries.Where(e => e.Command_Keyword == arguments[1]).SingleOrDefault( ); if (connectLink != null) { // clear out the stack and push the main connect page onto the stack ParentViewController.ClearViewControllerStack( ); ParentViewController.PushViewController(MainPageVC, false); // now go to the requested URL (and do not animate it--that could allow a race condition if this action is called rapidly TaskWebViewController.HandleUrl(false, true, connectLink.Url, this, MainPageVC, false, false, false, false); } } } break; } } }
public override void TouchesEnded(NSSet touches, UIEvent evt) { Rock.Mobile.Util.Debug.WriteLine("Touches Ended"); // for base.TouchesEnded, we do not want to call that FIRST if we're destroying the notes and switching to another page within the App. // if the tutorial is showing, all we want to do is hide it. // If we process input, it's possible they'll tap thru it to a URL, which will // switch pages and cause a lot of user confustion if (TutorialShowing( )) { AnimateTutorialScreen(false); } else { UITouch touch = touches.AnyObject as UITouch; if (touch != null) { if (Note != null) { // should we visit a website? bool urlLaunchesExternalBrowser = false; bool urlUsesRockImpersonation = false; string activeUrl = Note.TouchesEnded(touch.LocationInView(UIScrollView).ToPointF( ), out urlLaunchesExternalBrowser, out urlUsesRockImpersonation); if (string.IsNullOrEmpty(activeUrl) == false) { // see if the task should handle it (as in its a redirect within the app) if (SpringboardViewController.IsAppURL(activeUrl) == true) { // HACK JHM 9-1-2017: We don't currently have the ability to transition from a landscape Note to a portrait Task. // Because of that, they either need to be on an iPad, or have their phone in portrait mode. This isn't ideal, // but without adding support for landscape->portrait, we don't have any other choice. if (SpringboardViewController.SupportsLandscapeWide( ) == true || SpringboardViewController.IsDevicePortrait( ) == true) { SaveNoteState(UIScrollView.ContentOffset.Y / ( nfloat )Math.Max(1, UIScrollView.ContentSize.Height)); DestroyNotes( ); // if the url uses the rock impersonation token, it's safe to assume they tapped the takeaway. if (urlUsesRockImpersonation) { MessageAnalytic.Instance.Trigger(MessageAnalytic.Takeaway, activeUrl); } Task.HandleAppURL(activeUrl); } } else { // cleanup the notes before leaving SaveNoteState(UIScrollView.ContentOffset.Y / ( nfloat )Math.Max(1, UIScrollView.ContentSize.Height)); DestroyNotes( ); // if not, it's either a websie or bible verse Task.NavToolbar.Reveal(true); Task.NavToolbar.SetBackButtonEnabled(true); if (App.Shared.BibleRenderer.IsBiblePrefix(activeUrl)) { BiblePassageViewController viewController = new BiblePassageViewController(activeUrl, Task); Task.PerformSegue(this, viewController); } else { TaskWebViewController.HandleUrl(urlLaunchesExternalBrowser, urlUsesRockImpersonation, activeUrl, Task, this, true, false, false); } } } } } // when a touch is released, re-enabled scrolling UIScrollView.ScrollEnabled = true; } // Process TouchesEnded AFTER handling locally- we need to do this // in case the Note above wants to switch to another activity within the app. base.TouchesEnded(touches, evt); }
public override void ViewDidLoad() { base.ViewDidLoad(); BlockerView = new UIBlockerView(View, View.Frame.ToRectF( )); View.BackgroundColor = Rock.Mobile.UI.Util.GetUIColor(ControlStylingConfig.BackgroundColor); ScrollView = new UIScrollViewWrapper(); ScrollView.Parent = this; ScrollView.Layer.AnchorPoint = CGPoint.Empty; ScrollView.Bounds = View.Bounds; //ScrollView.BackgroundColor = Rock.Mobile.UI.Util.GetUIColor( 0x0000FFFF ); View.AddSubview(ScrollView); UserNameField = new StyledTextField(); ScrollView.AddSubview(UserNameField.Background); UserNameField.Field.AutocapitalizationType = UITextAutocapitalizationType.None; UserNameField.Field.AutocorrectionType = UITextAutocorrectionType.No; ControlStyling.StyleTextField(UserNameField.Field, LoginStrings.UsernamePlaceholder, ControlStylingConfig.Font_Regular, ControlStylingConfig.Medium_FontSize); ControlStyling.StyleBGLayer(UserNameField.Background); UserNameField.Field.ShouldReturn += (textField) => { textField.ResignFirstResponder(); TryRockBind(); return(true); }; PasswordField = new StyledTextField(); ScrollView.AddSubview(PasswordField.Background); PasswordField.Field.AutocorrectionType = UITextAutocorrectionType.No; PasswordField.Field.SecureTextEntry = true; ControlStyling.StyleTextField(PasswordField.Field, LoginStrings.PasswordPlaceholder, ControlStylingConfig.Font_Regular, ControlStylingConfig.Medium_FontSize); ControlStyling.StyleBGLayer(PasswordField.Background); PasswordField.Field.ShouldReturn += (textField) => { textField.ResignFirstResponder(); TryRockBind(); return(true); }; // obviously attempt a login if login is pressed LoginButton = UIButton.FromType(UIButtonType.System); ScrollView.AddSubview(LoginButton); ControlStyling.StyleButton(LoginButton, LoginStrings.LoginButton, ControlStylingConfig.Font_Regular, ControlStylingConfig.Medium_FontSize); LoginButton.SizeToFit( ); LoginButton.TouchUpInside += (object sender, EventArgs e) => { if (RockMobileUser.Instance.LoggedIn == true) { RockMobileUser.Instance.LogoutAndUnbind( ); SetUIState(LoginState.Out); } else { TryRockBind(); } }; // if they forgot their password, kick them out to the forgot password page ForgotPasswordButton = UIButton.FromType(UIButtonType.System); ScrollView.AddSubview(ForgotPasswordButton); ControlStyling.StyleButton(ForgotPasswordButton, LoginStrings.ForgotPasswordButton, ControlStylingConfig.Font_Regular, ControlStylingConfig.Medium_FontSize); ForgotPasswordButton.SizeToFit( ); ForgotPasswordButton.TouchUpInside += (object sender, EventArgs e) => { TaskWebViewController.HandleUrl(true, true, LoginConfig.ForgotPassword_Url, null, null, false, false, false); }; AdditionalOptions = new UILabel( ); ScrollView.AddSubview(AdditionalOptions); ControlStyling.StyleUILabel(AdditionalOptions, ControlStylingConfig.Font_Regular, ControlStylingConfig.Small_FontSize); AdditionalOptions.Text = LoginStrings.AdditionalOptions; AdditionalOptions.TextColor = Rock.Mobile.UI.Util.GetUIColor(ControlStylingConfig.TextField_PlaceholderTextColor); AdditionalOptions.SizeToFit( ); OrSpacerLabel = new UILabel( ); ScrollView.AddSubview(OrSpacerLabel); ControlStyling.StyleUILabel(OrSpacerLabel, ControlStylingConfig.Font_Regular, ControlStylingConfig.Small_FontSize); OrSpacerLabel.TextColor = Rock.Mobile.UI.Util.GetUIColor(ControlStylingConfig.TextField_PlaceholderTextColor); OrSpacerLabel.Text = LoginStrings.OrString; OrSpacerLabel.SizeToFit( ); RegisterButton = UIButton.FromType(UIButtonType.System); ScrollView.AddSubview(RegisterButton); ControlStyling.StyleButton(RegisterButton, LoginStrings.RegisterButton, ControlStylingConfig.Font_Regular, ControlStylingConfig.Medium_FontSize); //RegisterButton.BackgroundColor = UIColor.Clear; RegisterButton.SizeToFit( ); RegisterButton.TouchUpInside += (object sender, EventArgs e) => { Springboard.RegisterNewUser( ); }; // setup the result LoginResult = new StyledTextField( ); ScrollView.AddSubview(LoginResult.Background); ControlStyling.StyleTextField(LoginResult.Field, "", ControlStylingConfig.Font_Regular, ControlStylingConfig.Small_FontSize); ControlStyling.StyleBGLayer(LoginResult.Background); LoginResult.Field.UserInteractionEnabled = false; LoginResult.Field.TextAlignment = UITextAlignment.Center; // setup the facebook button FacebookLogin = new UIButton( ); ScrollView.AddSubview(FacebookLogin); string imagePath = NSBundle.MainBundle.BundlePath + "/" + "facebook_login.png"; FBImageView = new UIImageView(new UIImage(imagePath)); FacebookLogin.SetTitle("", UIControlState.Normal); FacebookLogin.AddSubview(FBImageView); FacebookLogin.Layer.CornerRadius = 4; FBImageView.Layer.CornerRadius = 4; FacebookLogin.TouchUpInside += (object sender, EventArgs e) => { TryFacebookBind(); }; // If cancel is pressed, notify the springboard we're done. CancelButton = UIButton.FromType(UIButtonType.System); ScrollView.AddSubview(CancelButton); CancelButton.SetTitleColor(Rock.Mobile.UI.Util.GetUIColor(ControlStylingConfig.Label_TextColor), UIControlState.Normal); CancelButton.SetTitle(GeneralStrings.Cancel, UIControlState.Normal); CancelButton.SizeToFit( ); CancelButton.TouchUpInside += (object sender, EventArgs e) => { // don't allow canceling while we wait for a web request. if (LoginState.Trying != State) { Springboard.ResignModelViewController(this, null); } }; // set the title image for the bar if there's no safe area defined. (A safe area is like, say, the notch for iPhone X) nfloat safeAreaTopInset = 0; // Make sure they're on iOS 11 before checking for insets. This is only needed for iPhone X anyways, which shipped with iOS 11. if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0)) { safeAreaTopInset = UIApplication.SharedApplication.KeyWindow.SafeAreaInsets.Top; } // setup the fake header if they're not on a device with save zones (iphone x) if (safeAreaTopInset == 0) { HeaderView = new UIView( ); View.AddSubview(HeaderView); HeaderView.BackgroundColor = Rock.Mobile.UI.Util.GetUIColor(ControlStylingConfig.BackgroundColor); imagePath = NSBundle.MainBundle.BundlePath + "/" + PrivatePrimaryNavBarConfig.LogoFile_iOS; LogoView = new UIImageView(new UIImage(imagePath)); LogoView.SizeToFit( ); LogoView.Layer.AnchorPoint = CGPoint.Empty; HeaderView.AddSubview(LogoView); HeaderView.SizeToFit( ); } }
/// <summary> /// Handles taking a URL and either launching it externally or within a webView, with or without impersonation token info. (Showing an embedded web page OR launching Safari) /// </summary> public static void HandleUrl(bool launchExternalBrowser, bool includeImpersonationToken, string url, Task parentTask, UIViewController currController, bool disableIdleTimer, bool webViewControlsNavbar, bool webviewHidesNavbarOnScroll, bool animateSeguePresentation = true) { // run the url through our processor to see if it needs to be manipulated string processedUrl = Rock.Mobile.Util.URL.Override.ProcessURLOverrides(url); // see if it's external if (processedUrl.StartsWith(PrivateGeneralConfig.ExternalUrlToken, StringComparison.InvariantCultureIgnoreCase)) { // strip off the PrivateGeneralConfig.ExternalUrlToken and forward it processedUrl = processedUrl.Substring(PrivateGeneralConfig.ExternalUrlToken.Length); // and flag that we should launch externally, so that the rest of the function runs as normal launchExternalBrowser = true; } // do we launch them out of the app? if (launchExternalBrowser == true) { // should we get the impersonation token? if (includeImpersonationToken == true) { MobileAppApi.TryGetImpersonationToken( delegate(string impersonationToken) { // put the platform we're running string fullUrl = Rock.Mobile.Util.Strings.Parsers.AddParamToURL(processedUrl, PrivateGeneralConfig.MobilePlatform); // URL encode the value NSString encodedUrlString = fullUrl.UrlEncode( ); // if we got a token, append it NSUrl encodedUrl = null; if (string.IsNullOrEmpty(impersonationToken) == false) { encodedUrl = new NSUrl(encodedUrlString + "&" + impersonationToken); } else { encodedUrl = new NSUrl(encodedUrlString); } UIApplication.SharedApplication.OpenUrl(encodedUrl); }); } else { // first encode the url NSString encodedUrlString = processedUrl.UrlEncode( ); UIApplication.SharedApplication.OpenUrl(new NSUrl(encodedUrlString)); } } // they are using an embedded browser, so this is pretty simple else { TaskWebViewController viewController = new TaskWebViewController(processedUrl, parentTask, includeImpersonationToken, disableIdleTimer, webViewControlsNavbar, webviewHidesNavbarOnScroll); parentTask.PerformSegue(currController, viewController, animateSeguePresentation); } }
public CustomWebViewDelegate(TaskWebViewController parent) : base( ) { Parent = parent; }
void OnViewClicked( ) { // launch the view TaskWebViewController.HandleUrl(false, false, DiscGuideURL, Task, this, true, false, false); }
/// <summary> /// Handles taking a URL and either launching it externally or within a webView, with or without impersonation token info. (Showing an embedded web page OR launching Safari) /// </summary> public static void HandleUrl( bool launchExternalBrowser, bool includeImpersonationToken, string url, Task parentTask, UIViewController currController, bool disableIdleTimer, bool webViewControlsNavbar ) { // do we launch them out of the app? if ( launchExternalBrowser == true ) { // should we get the impersonation token? if ( includeImpersonationToken == true ) { MobileAppApi.TryGetImpersonationToken( delegate(string impersonationToken ) { // put the platform we're running string fullUrl = Rock.Mobile.Util.Strings.Parsers.AddParamToURL( url, PrivateGeneralConfig.MobilePlatform ); // build the full url with their preferred campus (since thats personal data) fullUrl = Rock.Mobile.Util.Strings.Parsers.AddParamToURL( fullUrl, string.Format( PrivateGeneralConfig.RockCampusContext, App.Shared.Network.RockMobileUser.Instance.GetRelevantCampus( ) ) ); // URL encode the value NSString encodedUrlString = fullUrl.UrlEncode( ); // if we got a token, append it NSUrl encodedUrl = null; if ( string.IsNullOrEmpty( impersonationToken ) == false ) { encodedUrl = new NSUrl( encodedUrlString + "&" + impersonationToken ); } else { encodedUrl = new NSUrl( encodedUrlString ); } UIApplication.SharedApplication.OpenUrl( encodedUrl ); } ); } else { // first encode the url NSString encodedUrlString = url.UrlEncode( ); UIApplication.SharedApplication.OpenUrl( new NSUrl( encodedUrlString ) ); } } // they are using an embedded browser, so this is pretty simple else { TaskWebViewController viewController = new TaskWebViewController( url, parentTask, includeImpersonationToken, disableIdleTimer, webViewControlsNavbar ); parentTask.PerformSegue( currController, viewController ); } }
public CustomWebViewDelegate( TaskWebViewController parent ) : base( ) { Parent = parent; }