// create a copy constructor public RockNews( RockNews rhs ) { Title = rhs.Title; Description = rhs.Description; ReferenceURL = rhs.ReferenceURL; ReferenceUrlLaunchesBrowser = rhs.ReferenceUrlLaunchesBrowser; SkipDetailsPage = rhs.SkipDetailsPage; IncludeImpersonationToken = rhs.IncludeImpersonationToken; ImageURL = rhs.ImageURL; ImageName = rhs.ImageName; HeaderImageURL = rhs.HeaderImageURL; HeaderImageName = rhs.HeaderImageName; CampusGuids = rhs.CampusGuids; // note we copy the developer flags here, but don't set it in the default constructor Developer_Private = rhs.Developer_Private; Developer_StartTime = rhs.Developer_StartTime; Developer_EndTime = rhs.Developer_EndTime; Developer_ItemStatus = rhs.Developer_ItemStatus; }
// create a copy constructor public RockNews( RockNews rhs ) { Title = rhs.Title; Description = rhs.Description; ReferenceURL = rhs.ReferenceURL; ImageURL = rhs.ImageURL; ImageName = rhs.ImageName; HeaderImageURL = rhs.HeaderImageURL; HeaderImageName = rhs.HeaderImageName; CampusGuid = rhs.CampusGuid; }
public LaunchData( ) { //ALWAYS INCREMENT THIS IF UPDATING THE MODEL ClientModelVersion = 3; // Campuses = new List <Rock.Client.Campus>( ); PrayerCategories = new List <KeyValuePair <string, int> >( ); Genders = new List <string>( ); Genders.Add("Unknown"); Genders.Add("Male"); Genders.Add("Female"); // in debug builds, turn developer mode on by default #if DEBUG DeveloperModeEnabled = true; #endif News = new List <RockNews>( ); NoteDB = new NoteDB( ); // for the hardcoded news, leave OFF the image extensions, so that we can add them with scaling for iOS. UpgradeNewsItem = new RockNews( NewsConfig.UpgradeNews[0], NewsConfig.UpgradeNews[1], NewsConfig.UpgradeNews[2], true, false, false, "", NewsConfig.UpgradeNews[3], new List <System.Guid>( )); }
// create a copy constructor public RockNews(RockNews rhs) { Title = rhs.Title; Description = rhs.Description; ReferenceURL = rhs.ReferenceURL; ReferenceUrlLaunchesBrowser = rhs.ReferenceUrlLaunchesBrowser; SkipDetailsPage = rhs.SkipDetailsPage; IncludeImpersonationToken = rhs.IncludeImpersonationToken; ImageURL = rhs.ImageURL; ImageName = rhs.ImageName; CampusGuids = rhs.CampusGuids; // note we copy the developer flags here, but don't set it in the default constructor Developer_Private = rhs.Developer_Private; Developer_StartTime = rhs.Developer_StartTime; Developer_EndTime = rhs.Developer_EndTime; Developer_ItemStatus = rhs.Developer_ItemStatus; }
void GetNews( HttpRequest.RequestResult resultCallback ) { MobileAppApi.GetNews( delegate(System.Net.HttpStatusCode statusCode, string statusDescription, List<Rock.Client.ContentChannelItem> model ) { if ( Rock.Mobile.Network.Util.StatusInSuccessRange( statusCode ) == true ) { Rock.Mobile.Util.Debug.WriteLine( "Got news from Rock." ); // before comitting to this news, make sure there's at least one valid news item. if( model.Count > 0 && model[ 0 ].AttributeValues != null ) { // sort it by priority model.Sort( delegate(Rock.Client.ContentChannelItem x, Rock.Client.ContentChannelItem y ) { return x.Priority < y.Priority ? -1 : 1; } ); // clear existing news Data.News.Clear( ); // parse and take the new items foreach( Rock.Client.ContentChannelItem item in model ) { // it's possible rock sent us bad data, so guard against any incomplete news items if( item.AttributeValues != null ) { // we do this so we can store it on the stack and print it out if there's an exception. string currKey = ""; try { currKey = "FeatureImage"; string featuredGuid = item.AttributeValues[ currKey ].Value; string imageUrl = GeneralConfig.RockBaseUrl + "GetImage.ashx?Guid=" + featuredGuid; currKey = "PromotionImage"; string bannerGuid = item.AttributeValues[ currKey ].Value; string bannerUrl = GeneralConfig.RockBaseUrl + "GetImage.ashx?Guid=" + bannerGuid; currKey = "DetailsURL"; string detailUrl = item.AttributeValues[ currKey ].Value; currKey = "DetailsURLLaunchesBrowser"; bool detailUrlLaunchesBrowser = bool.Parse( item.AttributeValues[ currKey ].Value ); currKey = "IncludeImpersonationToken"; bool includeImpersonationToken = bool.Parse( item.AttributeValues[ currKey ].Value ); currKey = "MobileAppSkipDetailsPage"; bool mobileAppSkipDetailsPage = bool.Parse( item.AttributeValues[ currKey ].Value ); // take a list of the campuses that this news item should display for // (if the list is blank, we'll show it for all campuses) currKey = "Campuses"; List<Guid> campusGuids = new List<Guid>( ); if( item.AttributeValues[ currKey ] != null && string.IsNullOrEmpty( item.AttributeValues[ currKey ].Value ) == false ) { // this will be a comma-dilimited list of campuses to use for the news string[] campusGuidList = item.AttributeValues[ currKey ].Value.Split( ',' ); foreach( string campusGuid in campusGuidList ) { campusGuids.Add( Guid.Parse( campusGuid ) ); } } // jhm 11-30-15: Use the image guids, rather than news title, for the image. // This will ensure the image updates anytime it's changed in Rock! RockNews newsItem = new RockNews( item.Title, item.Content, detailUrl, mobileAppSkipDetailsPage, detailUrlLaunchesBrowser, includeImpersonationToken, imageUrl, featuredGuid.AsLegalFilename( ) + ".png",//item.Title.AsLegalFilename( ) + "_main.png", bannerUrl, bannerGuid.AsLegalFilename( ) + ".png",//item.Title.AsLegalFilename( ) + "_banner.png", campusGuids ); // handle developer fields // do a quick check and see if this should be flagged 'private' bool newsPublic = IsNewsPublic( item ); newsItem.Developer_Private = !newsPublic; newsItem.Developer_StartTime = item.StartDateTime; newsItem.Developer_EndTime = item.ExpireDateTime; newsItem.Developer_ItemStatus = item.Status; Data.News.Add( newsItem ); } catch( Exception e ) { // one of the attribute values we wanted wasn't there. Package up what WAS there and report // the error. We can then use process of elimination to fix it. Rock.Mobile.Util.Debug.WriteLine( string.Format( "News Item Exception. Attribute Value not found is: {0}. Full Exception {1}", currKey, e ) ); #if !DEBUG string attribValues = JsonConvert.SerializeObject( item.AttributeValues ); Exception reportException = new Exception( "News Item Exception. Attribute Value not found. Attribute Values found: " + attribValues, e ); Xamarin.Insights.Report( reportException ); #endif } } } } } else { Rock.Mobile.Util.Debug.WriteLine( "News request failed." ); } if ( resultCallback != null ) { resultCallback( statusCode, statusDescription ); } } ); }
/// <summary> /// Copies the hardcoded default news into the News list, /// so that there is SOMETHING for the user to see. Should only be done /// if there is no news available after getting launch data. /// </summary> public void CopyDefaultNews( ) { // COPY the general items into our own new list. foreach ( RockNews newsItem in DefaultNews ) { RockNews copiedNews = new RockNews( newsItem ); News.Add( copiedNews ); // also cache the compiled in main and header images so the News system can get them transparently #if __IOS__ string mainImageName; string headerImageName; if( UIKit.UIScreen.MainScreen.Scale > 1 ) { mainImageName = string.Format( "{0}/{1}@{2}x.png", Foundation.NSBundle.MainBundle.BundlePath, copiedNews.ImageName, UIKit.UIScreen.MainScreen.Scale ); headerImageName = string.Format( "{0}/{1}@{2}x.png", Foundation.NSBundle.MainBundle.BundlePath, copiedNews.HeaderImageName, UIKit.UIScreen.MainScreen.Scale ); } else { mainImageName = string.Format( "{0}/{1}.png", Foundation.NSBundle.MainBundle.BundlePath, copiedNews.ImageName, UIKit.UIScreen.MainScreen.Scale ); headerImageName = string.Format( "{0}/{1}.png", Foundation.NSBundle.MainBundle.BundlePath, copiedNews.HeaderImageName, UIKit.UIScreen.MainScreen.Scale ); } #elif __ANDROID__ string mainImageName = copiedNews.ImageName + ".png"; string headerImageName = copiedNews.HeaderImageName + ".png"; #endif // cache the main image MemoryStream stream = Rock.Mobile.IO.AssetConvert.AssetToStream( mainImageName ); stream.Position = 0; FileCache.Instance.SaveFile( stream, copiedNews.ImageName, FileCache.CacheFileNoExpiration ); stream.Dispose( ); // cache the header image stream = Rock.Mobile.IO.AssetConvert.AssetToStream( headerImageName ); stream.Position = 0; FileCache.Instance.SaveFile( stream, copiedNews.HeaderImageName, FileCache.CacheFileNoExpiration ); stream.Dispose( ); } }
void GetNews(HttpRequest.RequestResult resultCallback) { MobileAppApi.GetNews( delegate(System.Net.HttpStatusCode statusCode, string statusDescription, List <Rock.Client.ContentChannelItem> model) { if (Rock.Mobile.Network.Util.StatusInSuccessRange(statusCode) == true) { Rock.Mobile.Util.Debug.WriteLine("Got news from Rock."); // before comitting to this news, make sure there's at least one valid news item. if (model.Count > 0 && model[0].AttributeValues != null) { // sort it by priority model.Sort(delegate(Rock.Client.ContentChannelItem x, Rock.Client.ContentChannelItem y) { return(x.Priority < y.Priority ? -1 : 1); }); // clear existing news Data.News.Clear( ); // parse and take the new items foreach (Rock.Client.ContentChannelItem item in model) { // it's possible rock sent us bad data, so guard against any incomplete news items if (item.AttributeValues != null) { // we do this so we can store it on the stack and print it out if there's an exception. string currKey = ""; try { currKey = "FeatureImage"; string featuredGuid = item.AttributeValues[currKey].Value; string imageUrl = GeneralConfig.RockBaseUrl + "GetImage.ashx?Guid=" + featuredGuid; currKey = "DetailsURL"; string detailUrl = item.AttributeValues[currKey].Value; currKey = "DetailsURLLaunchesBrowser"; bool detailUrlLaunchesBrowser = bool.Parse(item.AttributeValues[currKey].Value); currKey = "IncludeImpersonationToken"; bool includeImpersonationToken = bool.Parse(item.AttributeValues[currKey].Value); currKey = "MobileAppSkipDetailsPage"; bool mobileAppSkipDetailsPage = bool.Parse(item.AttributeValues[currKey].Value); // take a list of the campuses that this news item should display for // (if the list is blank, we'll show it for all campuses) currKey = "Campuses"; List <Guid> campusGuids = new List <Guid>( ); if (item.AttributeValues[currKey] != null && string.IsNullOrEmpty(item.AttributeValues[currKey].Value) == false) { // this will be a comma-dilimited list of campuses to use for the news string[] campusGuidList = item.AttributeValues[currKey].Value.Split(','); foreach (string campusGuid in campusGuidList) { campusGuids.Add(Guid.Parse(campusGuid)); } } // Use the image guids, rather than news title, for the image. // This will ensure the image updates anytime it's changed in Rock! RockNews newsItem = new RockNews(item.Title, item.Content, detailUrl, mobileAppSkipDetailsPage, detailUrlLaunchesBrowser, includeImpersonationToken, imageUrl, featuredGuid.AsLegalFilename( ) + ".bin", campusGuids); // handle developer fields // do a quick check and see if this should be flagged 'private' bool newsPublic = IsNewsPublic(item); newsItem.Developer_Private = !newsPublic; newsItem.Developer_StartTime = item.StartDateTime; newsItem.Developer_EndTime = item.ExpireDateTime; newsItem.Developer_ItemStatus = item.Status; Data.News.Add(newsItem); } catch (Exception e) { // one of the attribute values we wanted wasn't there. Package up what WAS there and report // the error. We can then use process of elimination to fix it. Rock.Mobile.Util.Debug.WriteLine(string.Format("News Item Exception. Attribute Value not found is: {0}. Full Exception {1}", currKey, e)); // Xamarin Insights was able to report on exceptions. HockeyApp cannot as of Mar 2017. // When this functionality becomes available, we should implement it here in just Release Mode. // - CG } } } } } else { Rock.Mobile.Util.Debug.WriteLine("News request failed."); } if (resultCallback != null) { resultCallback(statusCode, statusDescription); } }); }
void GetPECampaign(int?personId, HttpRequest.RequestResult resultCallback) { MobileAppApi.GetPECampaign(personId, delegate(System.Net.HttpStatusCode statusCode, string statusDescription, JArray responseBlob) { if (Rock.Mobile.Network.Util.StatusInSuccessRange(statusCode) == true) { //attempt to parse the response into a single item. If this fails, we'll stop and return nothing. try { JObject campaignBlob = responseBlob.First?.ToObject <JObject>( ); JObject contentBlob = JObject.Parse(campaignBlob["ContentJson"].ToString( )); JObject mobileAppNewsFeedBlob = JObject.Parse(contentBlob[PrivateGeneralConfig.PersonalizationEngine_MobileAppNewsFeed_Key].ToString( )); // get the NAME of the campaign (different than the title displayed) - Note that we get this from CAMPAIGN blob. string campaignName = campaignBlob["Name"]?.ToString( ); // try getting values for each piece of the campaign string title = mobileAppNewsFeedBlob["title"]?.ToString( ); string body = mobileAppNewsFeedBlob["body"]?.ToString( ); string linkUrl = mobileAppNewsFeedBlob["link"]?.ToString( ); string skipDetailsPageStr = mobileAppNewsFeedBlob["skip-details-page"]?.ToString( ); string imgUrl = mobileAppNewsFeedBlob["img"]?.ToString( ); // now parse data as needed bool skipDetailsPage = false; bool.TryParse(skipDetailsPageStr, out skipDetailsPage); // make sure the detail url has a valid scheme / domain, and isn't just a relative url if (linkUrl?.StartsWith("/", StringComparison.CurrentCulture) == true) { linkUrl = GeneralConfig.RockBaseUrl + linkUrl; } // get the url for the image string imageUrl = GeneralConfig.RockBaseUrl + imgUrl; // For the image, we'll cache it using the campaign's title as the filename, plus a version number. // strip the query param for the imageUrl, and use the version argument to control the versioning of the file. // This way, we can cache the image forever, and only update the image when it's actually changed on the server. // Example: https://rock.ccv.church/images/share.jpg?v=0 will save to the device as "share0.bin" // If v=0 becomes v=1, that will then turn into a new filename on the device and cause it to update. Uri imageUri = new Uri(imageUrl); var queryParams = System.Web.HttpUtility.ParseQueryString(imageUri.Query); string imageVersion = queryParams.Get("v") ?? "0"; // build the image filename string imageCacheFileName = (campaignName ?? "campaign-img") + imageVersion + ".bin"; imageCacheFileName = imageCacheFileName.Replace(" ", "").ToLower( ); bool detailUrlLaunchesBrowser = false; bool includeImpersonationToken = true; RockNews newsItem = new RockNews(title, body, linkUrl, skipDetailsPage, detailUrlLaunchesBrowser, includeImpersonationToken, imageUrl, imageCacheFileName, new List <Guid>( )); //support all campuses Data.PECampaign = newsItem; } catch { //something about the response was bad. Rather than crash the entire app, let's just fail here. Rock.Mobile.Util.Debug.WriteLine(statusDescription = string.Format("Getting PE campaigned failed: {0}", statusCode)); statusCode = System.Net.HttpStatusCode.InternalServerError; } } if (resultCallback != null) { resultCallback(statusCode, statusDescription); } }); }