UWP Transparent title bar

In the last post I extended the view into the title bar on a UWP application, which looks great with the NavigationView or the likes.

However, if you then place a view, such as a SplitView, on the right of the screen the title bar buttons (minimize, maximize and close) will appear in a different colour (if using the default colours).

So we can make the button backgrounds transparent like this

var titleBar = ApplicationView.GetForCurrentView().TitleBar;
titleBar.ButtonBackgroundColor = Colors.Transparent;
titleBar.ButtonInactiveBackgroundColor = Colors.Transparent;

How to extend a UWP page into the titlebar

If you want your page/view to extend into the title bar area (in other words no longer having a title bar), then OnLaunched add the following

CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true;

and add this using clause

using Windows.ApplicationModel.Core;

Writing JavaScript templates using ejs

There are quite a few (as you’d probably expect) templating engines for use with JavaScript, such as Mustache and handlebars both of which use {{ }} syntax.

The syntax used is really not very important, what matters is the flexibility/functionality, but for nostalgia’s sake (as much as anything) this post will instead use ejs which uses syntax such as <%= %> which is very much like old ASP from my recollections (hence the nostalgia).

Note: I’m not endorsing ejs over any other engine, I just picked this to begin with, if/when I get time I will probably create posts covering using some other templating engines also.

Getting Started

We need to start by installing ejs, so run the following

yarn add ejs

We’re going to create a folder named templates (this is not a requirement of ejs) to store our .ejs files. So the template files will be saved with the .ejs extension.

Let’s just create a very standard Hello World app. so in the file templates/sample.ejs write the following

<%= message %>

Now let’s write the code to use ejs generate some output from our template and supply our data to the generator.

const ejs = require("ejs");

ejs.renderFile("./templates/sample.ejs", {
    message: "Hello World",
  },
  {},
  (err: any, result: string) => {
    if(err != null) {
      console.log(err);
    }
    // use the results of the template combined
    // with the supplied model
    console.log(result);
});

Here we show the basic usage pattern, which uses the asynchronous renderFile function. This takes the template file (we can ofcourse also supply the template as a string using the render function). The second argument is a “model” of the data being passed into the template engine and ofcourse the key’s related to the variable names used within the template file. The third argument supplies any options to the template engine, in this example I’m not applying any options. Finally, as this function is asynchronous, we will get an error or result or the processing of the template.

More…

That was simple enough but we’re not going to want to just output simple values like this, so let’s take a look at some more capabilities.

If we take a look at the Docs (https://ejs.co/#docs), Tags section we can see the tags for embedding our model data, let’s take a look at some of these in usage.

<%

The scriptlet tag is used for flow control and does not embed output into the template itself (as such). Instead it allow us to use conditionals such as if or loops such as for loops on our data model items.

type Names = <% for(let i = 0; i < names.length; i++) { %>
    | '<%= name[i].header %>'<% } %>;

In this example we’re code generating some types by taking an array of names from the model and creating a union of those header names.

Like-wise we might also use this tag for if statements within the <% %gt;

<%_

This will strip whitespace from before the tag. One of the problems we often find with templated code generation is how to control whitespace before and after the generated code. Hence this will remove the preceding whitespace.

<%=

This simply embeds an HTML escaped value into our template, in other words it simply replaces the tag with the value from message in this example below. Ofcourse message is a value stored in our data model.

<%= message %>

<%-

As per <%= but no escaping of values takes place.

<%#

Comment tags, just in case you wanted to add some comments/documentation to your template, this does not get output as part of the generated data.

<%%

Escapes the tag, i.e. outputs <%

%>

Standard end tag for use with the other start tags.

-%>

Trims the following newline.

_%>

Removes whitespace after the tag, again allows us to have some control of the whitespace following our generated output.

Custom Fonts in Xamarin Forms v4.5.0.530

In my previous post Custom Fonts in Xamarin Forms the section title Preview Feature is now working.

We’re use the Lobster-Regular.ttf file mentioned in the aforementioned post.

  • Add a Resources/Fonts folder to your shared project
  • Add your .otf or .ttf file to this Fonts folder
  • Set the Build Action to Embedded resource
  • In you AssemblyInfo.cs file add
    [assembly: ExportFont("Lobster-Regular.ttf")]
    
  • Now in your XAML you simply use
    <Label Text="Hello Xamarin.Forms"
       FontFamily="Lobster-Regular" />
    

That’s all there is to it.

You may still want to use the previous method for custom fonts if applying either different fonts to different devices, otherwise, this is such a simple and natural way to handle this task.

Tizen emulator “Extra package installation is failed. cert must be installed MANUALLY”

I started to see the warning/error displayed when starting the emulator “Extra package installation is failed. cert must be installed MANUALLY”. Nothing changed, that I was aware of, i.e. no new installations or the likes.

I found that if you go to (on Windows)

%USERPROFILE%/SamsungCertificate

then delete the Cert folder (probably a good idea to back up first), then open the emulator again (I also opened the cert manager, but I think the cert folder was recreated when the emulator started and no more warnings/errors) then everything worked again.

However this seems to be something that keeps happening, if I find out why I’ll update this post.

The “UNAVAILABLE: Trying to connect an http1.x server” gRPC error

I’m working with on C# client library using gRpc. This is not a web based library where there’s a need for envoy or other application to help work with HTTP2. Instead this was on a C# client using tcp/ip.

Everything was working fine on my machine until the machine was relocated (not that this specifically was the problem as I later found out others were having similar problems, some times intermittently) at which point I found that the client would exception with the message “UNAVAILABLE: Trying to connect an http1.x server”.

Note: if you turn on all exceptions within Visual Studio, you’ll firstly see an exception where grpc tries to get a Value from a Nullable when it’s null (this was the call to Native.grpcsharp_batch_context_recv_message_length). This is a red herring, it’s simple that the nullable is null which seems to be expected behaviour, maybe should be handled in the gRPC .NET library code.

Testing the client on another machine demonstrated the problem was seemingly network related, turns out it was HTTP proxy related to be precise.

This doesn’t seem to be too well documented from what I could tell, but setting the ChannelOption grpc.enable_http_proxy to 0 (see https://grpc.github.io/grpc/core/group__grpc__arg__keys.html) fixed the problem.

var channel = new ManagedChannel(
   host, 
   port, 
   ChannelCredentials.Insecure,
   new []{ new ChannelOption("grpc.enable_http_proxy", 0)} );

Controlling a Philips Hue

First off, the Philips Hue bridge exposes a web server, so take a look at the wireless connections on your network (see also How to develop for Hue) for other methods of locating your Hue bridge on the network.

Much of the information in this post is taken from How to develop for Hue?. More information is available if you register as a Philips Hue developer.

Once you’ve located your bridge IP address you can use a web browser to connect the CLIP API Debugger, i.e.

https://<bridge ip address>/debug/clip.html

The Hue bridge API

The first thing we need to do is a key for interacting with the device. The Hue actually calls this your username and it’s a randomly generated string, once we have this we have an authorise user.

So for example if you try to use any command without a key you’ll get a response along the following lines

[
  {
    "error": {
      "type": 1,
      "address": "/",
      "description": "unauthorized user"
    }
  }
]

Creating our user

To get our username and thus create an authorized user, we use the following API

  • Method: POST
  • Url: /api
  • Body: {“devicetype”:”my_hue_app#my_name”}

The “my_hue_app#my_name” appears to simply be a unique resource name. Before you run this command you should press the link button on the Hue bridge then execute this HTTP request.

If all works correctly you should get a response like this

[
  {
    "success": {
      "username": "sYA1egf8VZteeIWnXmlIdrxFE3uHgUr-jk2Vrt12"
    }
  }
]

Now we use the username value (i.e. sYA1egf8VZteeIWnXmlIdrxFE3uHgUr-jk2Vrt12) in our method calls going forward.

Getting more information

  • Method: GET
  • Url: /api/sYA1egf8VZteeIWnXmlIdrxFE3uHgUr-jk2Vrt12

This will return a JSON response (which it too large to include here) including information on the available lights, their state, brightness, hue etc. along with stored scenes.

Getting light information

  • Method: GET
  • Url: https:///api/sYA1egf8VZteeIWnXmlIdrxFE3uHgUr-jk2Vrt12/lights

If successful, this will return light specific information, such as state, name, brightness etc.

Getting light information for a specific light

If we want to just get information for a specific light, we use it’s ID, by simply appending it the the previous URL, for example we’ll get information for light 1

  • Method: GET
  • Url: https:///api/sYA1egf8VZteeIWnXmlIdrxFE3uHgUr-jk2Vrt12/lights/1

Turning a light on and off

To change the state of a light we append state to the previous URL, for example

  • Method: PUT
  • Url: https:///api/sYA1egf8VZteeIWnXmlIdrxFE3uHgUr-jk2Vrt12/lights/1/state
  • Body: {“on”:false}

We should get a response similar to the one below

[
  {
    "success": {
      "/lights/1/state/on": false
    }
  }
]

More than just on and off

  • Method: PUT
  • Url: https:///api/sYA1egf8VZteeIWnXmlIdrxFE3uHgUr-jk2Vrt12/lights/1/state
  • Body: {“on”:true, “sat”:254, “bri”:254,”hue”:10000}

After executing this, you’ll get a response similar to the following

[
  {
    "success": {
      "/lights/2/state/on": true
    }
  },
  {
    "success": {
      "/lights/2/state/hue": 10000
    }
  },
  {
    "success": {
      "/lights/2/state/sat": 254
    }
  },
  {
    "success": {
      "/lights/2/state/bri": 254
    }
  }
]

C#/.NET Libraries

There are also several .NET libraries for interacting with the Hue, that allows us a better API experience, such as

  • https://github.com/Q42/Q42.HueApi
  • https://github.com/cDima/Hue
  • https://github.com/qJake/SharpHue

References

Become a Philips Hue Developer to light up your ideas

Razor templates in your Xamarin application

I had a situation where I wanted to have a template file made up of HTML along with data supplied by my Xamarin application. There are several options to do this but a Razor template file would be a perfect fit, but how to embed one in my (non-Web) application?

Note: Whilst this post talks about a Xamarin application this should be usable in other types of application.

  • I created a Templates folder (not required for this to work) in my solution.
  • Within the Templates folder I add a new text file but saved with a .cshtml extension, for example EmployeeTemplate.cshtml. Visual Studio 2019 doesn’t have a specific template for Xamarin application, but just naming it with the correct extension works.
  • Select the file in the solution explorer and open it’s properties, set the Custom Tool to RazorTemplatePreprocessor.

Here’s a snippet of the contents within the Razor template file

<div class="row">
  <div>Date: @Model.DateEntered</div>
    <div>
      <div>Employee Number:</div>
      <div>@Model.OrderDetails.EmployeeNumber</div>
    </div>
</div>

Visual Studio will (due the use of the RazorTemplatePreprocessor Custom Tool) generate a .cs file that is a class that we can pass our model into and will process the template file and output a string representing the combination of the template with our model.

To generate our output string we simply use the following code

var template = new EmployeeTemplate() 
{ 
  Model = viewModel 
};

var result = template.GenerateString();

Text to Speech on mobile with Xamarin

Previously I looked at Speech synthesis in Windows with C# but what about speech synthesis on mobile.

Xamarin.Essentials has this covered with the TextToSpeechTextToSpeech class and is included by default when creating a Xamarin Forms mobile application.

It’s really simple to add text to speech capabilities, we simply write code such as

await TextToSpeech.SpeakAsync("Hello World");

As you can see by the use of the await keyword (and the standard Async suffix), the SpeakAsync method returns a task. It also accepts a cancellation token if you need to cancel mid utterance. There’s also an overload which accepts SpeechOptions which allows us to set the volume, pitch and locale.

The second TextToSpeech method is GetLocalesAsync which allows is to get a list of supported locales from the device that can then be used within the SpeakAsync method’s SpeechOptions.

await TextToSpeech.GetLocalesAsync();

Note: It’s fun listening to the attempts at different accents depending upon the locale.

Changing the date/time on the Tizen emulator

To set the date/time on the Tizen emulator

  • Obviously ensure you have the emulator running
  • Right mouse click on the emulator
  • Select Shell
  • Type su to switch to super user or you’ll get an “Operation not permitted” error
  • The default password is tizen
  • Type date –set=”27 Mar 2020 23:59:45″ and press enter
  • Tizen is a Linux based OS, hence we can use Linux commands in the shell.