/// <summary> /// Builds the mobile package that can be archived for deployment. /// </summary> /// <param name="applicationId">The application identifier.</param> /// <param name="deviceType">The type of device to build for.</param> /// <returns>An update package for the specified application and device type.</returns> public static UpdatePackage BuildMobilePackage(int applicationId, DeviceType deviceType) { var site = SiteCache.Get(applicationId); string applicationRoot = GlobalAttributesCache.Value("PublicApplicationRoot"); var additionalSettings = site.AdditionalSettings.FromJsonOrNull <AdditionalSiteSettings>(); if (additionalSettings.IsNull()) { throw new Exception("Invalid or non-existing AdditionalSettings property on site."); } // // Get all the system phone formats. // var phoneFormats = DefinedTypeCache.Get(SystemGuid.DefinedType.COMMUNICATION_PHONE_COUNTRY_CODE) .DefinedValues .Select(dv => new MobilePhoneFormat { CountryCode = dv.Value, MatchExpression = dv.GetAttributeValue("MatchRegEx"), FormatExpression = dv.GetAttributeValue("FormatRegEx") }) .ToList(); // // Build CSS Styles // var settings = additionalSettings.DownhillSettings; settings.Platform = DownhillPlatform.Mobile; // ensure the settings are set to mobile var cssStyles = CssUtilities.BuildFramework(settings); // append custom css but parse it for downhill variables if (additionalSettings.CssStyle.IsNotNullOrWhiteSpace()) { cssStyles += CssUtilities.ParseCss(additionalSettings.CssStyle, settings); } // // Initialize the base update package settings. // var package = new UpdatePackage { ApplicationType = additionalSettings.ShellType ?? ShellType.Blank, ApplicationVersionId = ( int )(RockDateTime.Now.ToJavascriptMilliseconds() / 1000), CssStyles = cssStyles, LoginPageGuid = site.LoginPageId.HasValue ? PageCache.Get(site.LoginPageId.Value)?.Guid : null, ProfileDetailsPageGuid = additionalSettings.ProfilePageId.HasValue ? PageCache.Get(additionalSettings.ProfilePageId.Value)?.Guid : null, PhoneFormats = phoneFormats, TabsOnBottomOnAndroid = additionalSettings.TabLocation == TabLocation.Bottom }; // // Setup the appearance settings. // package.AppearanceSettings.BarBackgroundColor = additionalSettings.BarBackgroundColor; package.AppearanceSettings.MenuButtonColor = additionalSettings.MenuButtonColor; package.AppearanceSettings.ActivityIndicatorColor = additionalSettings.ActivityIndicatorColor; package.AppearanceSettings.FlyoutXaml = additionalSettings.FlyoutXaml; package.AppearanceSettings.LockedPhoneOrientation = additionalSettings.LockedPhoneOrientation; package.AppearanceSettings.LockedTabletOrientation = additionalSettings.LockedTabletOrientation; if (site.FavIconBinaryFileId.HasValue) { package.AppearanceSettings.LogoUrl = $"{applicationRoot}/GetImage.ashx?Id={site.FavIconBinaryFileId.Value}"; } // // Load all the layouts. // foreach (var layout in LayoutCache.All().Where(l => l.SiteId == site.Id)) { var mobileLayout = new MobileLayout { LayoutGuid = layout.Guid, Name = layout.Name, LayoutXaml = deviceType == DeviceType.Tablet ? layout.LayoutMobileTablet : layout.LayoutMobilePhone }; package.Layouts.Add(mobileLayout); } // // Load all the pages. // using (var rockContext = new RockContext()) { AddPagesToUpdatePackage(package, applicationRoot, rockContext, new[] { PageCache.Get(site.DefaultPageId.Value) }); } // // Load all the blocks. // foreach (var block in BlockCache.All().Where(b => b.Page != null && b.Page.SiteId == site.Id && b.BlockType.EntityTypeId.HasValue).OrderBy(b => b.Order)) { var blockEntityType = block.BlockType.EntityType.GetEntityType(); if (typeof(Rock.Blocks.IRockMobileBlockType).IsAssignableFrom(blockEntityType)) { var additionalBlockSettings = block.AdditionalSettings.FromJsonOrNull <AdditionalBlockSettings>() ?? new AdditionalBlockSettings(); var mobileBlockEntity = (Rock.Blocks.IRockMobileBlockType)Activator.CreateInstance(blockEntityType); mobileBlockEntity.BlockCache = block; mobileBlockEntity.PageCache = block.Page; mobileBlockEntity.RequestContext = new Net.RockRequestContext(); var attributes = block.Attributes .Select(a => a.Value) .Where(a => a.Categories.Any(c => c.Name == "custommobile")); var mobileBlock = new MobileBlock { PageGuid = block.Page.Guid, Zone = block.Zone, BlockGuid = block.Guid, RequiredAbiVersion = mobileBlockEntity.RequiredMobileAbiVersion, BlockType = mobileBlockEntity.MobileBlockType, ConfigurationValues = mobileBlockEntity.GetMobileConfigurationValues(), Order = block.Order, AttributeValues = GetMobileAttributeValues(block, attributes), PreXaml = block.PreHtml, PostXaml = block.PostHtml, CssClasses = block.CssClass, ShowOnTablet = additionalBlockSettings.ShowOnTablet, ShowOnPhone = additionalBlockSettings.ShowOnPhone, RequiresNetwork = additionalBlockSettings.RequiresNetwork, NoNetworkContent = additionalBlockSettings.NoNetworkContent, AuthorizationRules = string.Join(",", GetOrderedExplicitAuthorizationRules(block)) }; package.Blocks.Add(mobileBlock); } } // // Load all the campuses. // foreach (var campus in CampusCache.All().Where(c => c.IsActive ?? true)) { var mobileCampus = new MobileCampus { Guid = campus.Guid, Name = campus.Name }; if (campus.Location != null) { if (campus.Location.Latitude.HasValue && campus.Location.Longitude.HasValue) { mobileCampus.Latitude = campus.Location.Latitude; mobileCampus.Longitude = campus.Location.Longitude; } if (!string.IsNullOrWhiteSpace(campus.Location.Street1)) { mobileCampus.Street1 = campus.Location.Street1; mobileCampus.City = campus.Location.City; mobileCampus.State = campus.Location.State; mobileCampus.PostalCode = campus.Location.PostalCode; } } package.Campuses.Add(mobileCampus); } return(package); }