Developer Docs - Mobile Docs - Custom Blocks
Okay, maybe all of this still isn't quite enough for what you need. Or maybe it works, but you are building such complicated entity commands and SQL queries in Lava that it's just not performant enough. Maybe you are just far more familiar with C# so you'd rather go that way. Possibly you want to build a plugin that provides a new block type with some settings for the admin to configure and then it magically does what it does.
Let's start with the most basic block configuration:
[DisplayName( "My Custom Block" )]
[Category( "Rock Solid Church > Mobile" )]
[Description( "A custom block to do magical things." )]
[IconCssClass( "fa fa-square" )]
public class MyCustomBlock : RockMobileBlockType
{
#region IRockMobileBlockType Implementation
int IRockMobileBlockType.RequiredMobileAbiVersion => 1;
string IRockMobileBlockType.MobileBlockType => "Rock.Mobile.Blocks.Content";
object IRockMobileBlockType.GetMobileConfigurationValues()
{
string content = "";
return new Rock.Mobile.Common.Blocks.Content.Configuration
{
Content = content
}
}
#endregion
}
But that is rather boring. Instead, lets have it render out something a bit more expressive.
object IRockMobileBlockType.GetMobileConfigurationValues()
{
string content = @"
";
return new Rock.Mobile.Common.Blocks.Content.Configuration
{
Content = content
}
}
[BlockAction]
public string GetCallbackContent( string command, Dictionary parameters)
[BlockAction]
public string Search( string term )
Either will achieve the same result, but the latter form might be easier to read in your code - especially if you have multiple commands being handled. The return type of these methods is a simple string that contains the XAML code used to render the UI. Let's use the latter form and build our search results:
[BlockAction]
public object Search( string term )
{
var searchClient = IndexContainer.GetActiveComponent();
var searchEntities = new List { EntityTypeCache.Get( SystemGuid.EntityType.GROUP.AsGuid() ) };
var results = searchClient.Search( term,
SearchType.Wildcard,
searchEntities,
"GroupTypeName^Serving Team",
5,
0,
out int totalResults );
var sb = new StringBuilder();
sb.AppendLine( "" );
foreach ( var result in results )
{
var button = $@"
";
sb.AppendLine( button );
}
sb.AppendLine( "" );
return new Rock.Mobile.Common.Blocks.Content.CallbackResponse
{
Content = sb.ToString()
};
}
[BlockAction]
public object ShowGroup( int groupId )
{
return new Rock.Mobile.Common.Blocks.Content.CallbackResponse
{
Content = ""
};
}
Dynamic Initial Content
What we described above will leave you with a block whose initial content is static, that is it never changes unless the admin deploys a new application bundle. That might work for you, but you probably want to change that content based on query string parameters and such. Let's modify our block so that it instructs the mobile application to be dynamic.
[DisplayName( "My Custom Block" )]
[Category( "Rock Solid Church > Mobile" )]
[Description( "A custom block to do magical things." )]
[IconCssClass( "fa fa-square" )]
public class MyCustomBlock : RockMobileBlockType
{
#region IRockMobileBlockType Implementation
int IRockMobileBlockType.RequiredMobileAbiVersion => 1;
string IRockMobileBlockType.MobileBlockType => "Rock.Mobile.Blocks.Content";
object IRockMobileBlockType.GetMobileConfigurationValues()
{
return new Rock.Mobile.Common.Blocks.Content.Configuration
{
Content = null,
DynamicContent = true
}
}
#endregion
[BlockAction]
public object GetInitialContent()
{
return new Rock.Mobile.Common.Blocks.Content.CallbackResponse
{
Content = ""
};
}
}