Poolsuite FM Player in NativeScript, Part 1: Project setup + UI

Twitter Post 1024x512 px
This entry is part 1 of 3 in the series Unofficial Android version of PoolSuite FM with NativeScript

Hi folks, I’m a big fan of PoolSuite FM. Unfortunately, there isn’t an Android version available yet. Why don’t we create our own Android version of PoolSuite FM, especially with the help of NativeScript?

In this tutorial series, our objective is to:

  • Create simple player controls.
  • Make requests, retrieve audio files, and play them. Yes, we’ll definitely play the music! 🎵
  • Allow users to switch stations and pause, resume, skip to the next track, or go back to the previous track.
  • Develop a cool, retro-style UI, which is a must-have.

Let’s call our app: PoolParty – Unofficial PoolSuite FM player for Android

In this Part 1 of the tutorial we will cover below main points:

  • Set up a new NativeScript project using the latest Vue 3 with HMR enabled.
  • Try to recreate the player’s UI layout of PoolSuite in NativeScript as simply as possible.

Before we begin, here’s a TL;DR: The full source code and any future updates can be found on GitHub at https://github.com/NewbieScripterRepo/PoolPartyFM.

By the end of this article, the source code for Part 1 will be available in the part-1-ui branch. Feel free to clone it and experiment. Don’t forget to star the repo to stay updated. Let’s get started.

1. Getting started with blank NativeScript Vue 3 project

NativeScript Vue 3 is currently in beta and actively being developed. It will soon be the next major version for NativeScript Vue. Let’s set up our PoolParty project using Vue 3 with the following command:

ns create poolparty --template @nativescript-vue/template-blank@rc

After command is finished. You should end up with having a nice and clean project like this, with Vue and Tailwind in place.

The newly created project can run on both iOS and Android devices immediately, provided your devices are connected. Use:

ns run android
ns run ios

For the sake of simplicity in this series, let’s set aside the iOS version and focus on our primary goal of creating an unofficial PoolSuite for Android.

Even though it is still in beta, I really enjoy working with Vue 3, mainly due to its support for hot module reloading (HMR). Proper hot reloading during development allows me to create UI more enjoyably and greatly improves the developer experience.

1.1. Clean up unnecssary files

Since this app will only have one screen, clean up the project by removing the default Details.vue file. Delete all the content from Home.vue and use it as the base for our app.

Crafting a Android version of Poolsuite FM Player in NativeScript

1.2. Get the FontAwesome Icons

We are going to use icons alot through out UI. Thanks to @nativescript-community/fonticon package, this make using fonticon alot easier in NativeScript app. Reference to my other article on how to add FontAwesome to your project here.

Now we have a good starting point for our cool app.

2. Crafting the Player UI

We are now ready to code. Our target would be trying to mimic the retro style of PoolSuite.

Poolsuite FM Player
Poolsuite FM on iOS

In the scope of this project, our must have components would be:

  • A cool retro action bar with “PoolParty” in the title.
  • A cool channel selector
  • A cool progress bar with waveform (not sure how to do yet)
  • A play control

We will have to leave out the PoolCam part, so don’t be sad. Let’s tackle the other UI one by one.

2.1. The action bar

If you isolated the top part of the original PoolSuite FM’s UI, you will see it consist of two parts: a small retro image above the action bar then the action bar with title itself.

Poolsuite FM Player header

We can recreate this easily in NativeScript with <ActionBar> element with help of a <GridLayout> inside.

  • For the background color let use: zinc-800, which is #27272a. It is slightly dark but not completely black .. sound elegant!
  • And for foreground color, let use: orange-100, which is #ffedd5. It is slightly yellowish.
  • (Find more about Tailwind color here: https://tailwindcss.com/docs/customizing-colors)

Here is how you do it.

<ActionBar class="bg-zinc-800">
  <GridLayout rows="37, 60" columns="40,*,40" width="100%">
    <Image
      class="bg-orange-100"
      src="~/assets/top.png"
      col="0"
      colSpan="3"
      row="0"
      height="37"
      width="100%"
      stretch="fill"
    />
    <Label
      class="text-center font-bold text-xs color-orange-100"
      col="1"
      row="1"
      text="Poolparty FM"
    />
    <Label
      class="fas font-bold text-xs color-orange-100"
      col="2"
      row="1"
      :text="$fonticon('fa-angle-right')"
    />
  </GridLayout>
</ActionBar>

Some may found it supprise that we can put other elements inside <ActionBar> element beside <ActionItem>, <NavigateButton>, etc.. You can read more at: https://docs.nativescript.org/ui/action-bar#customizing-the-actionbar

For the image, I drawn one myself you can find it at: https://github.com/NewbieScripterRepo/PoolPartyFM/blob/main/src/assets/top.png

Here is how it turned out:

Android version of Poolsuite FM Player in NativeScript - the header

Depend on your phone setting, you may notice that the statusbar color is white, not black like my screenshot above. That statusbar color on Android can be changed easily by editing ns_primary and ns_primaryDark in App_Resources/Android/src/main/res/values/colors.xml. I set both to #000

2.2. The channel selector & progress bar

Let’s analyze the original design: the layout can be replicated using a GridLayout with 3 columns and 2 rows.

  • In the first row, each column will contain a button.
  • In the second row, a large rectangular bar will serve as the progress bar. We’ll leave the waveform for future enhancement.
Android version of Poolsuite FM Player in NativeScript - Channel selector

Let’s define our grid as follow:

<GridLayout
  class="pt-3 bg-zinc-800 rounded"
  columns="80,*,80"
  rows="70, 70"
  height="auto"
>

The first row, we will define 3 buttons and put those in each column like this:

<Button
  class="fas text-xs bg-zinc-800"
  color="#fff"
  col="0"
  row="0"
  :text="$fonticon('fa-caret-left')"
/>

<Button
  class="text-sm border border-r-4 border-b-4 border-white rounded bg-zinc-800"
  color="#fff"
  col="1"
  row="0"
  height="40"
  text="$fonticon('fa-angle-left')"
>
  <FormattedString>
    <Span text="Channel: " />
    <Span class="font-bold" text="Poolsuite FM" />
    <Span text="    " />
    <Span class="fas text-xs" :text="$fonticon('fa-sort')" />
  </FormattedString>
</Button>

<Button
  class="fas text-xs bg-zinc-800"
  color="#fff"
  col="2"
  row="0"
  :text="$fonticon('fa-caret-right')"
/>

In web development, I’ve previously used a technique for creating a progress bar using two <div> elements. The outer <div> is set to position: relative, while the inner <div> is set to position: absolute with a different color. By adjusting the width of the inner <div>, you can create the progress effect.

In NativeScript, we can apply a similar approach by using an AbsoluteLayout with a StackLayout inside. This setup would achieve the desired progress bar effect. Here’s how it works:

<AbsoluteLayout colSpan="3" row="1" col="0" class="mt-3 bg-zinc-700">
  <StackLayout
    class="bg-zinc-600"
    height="70"
    top="0"
    left="0"
    :width="progress + '%'"
  />
</AbsoluteLayout>

And it turned out pretty well:

Poolparty: Channel selector and progress bar

2.3. The play control

Using the same technique with GridLayout, let’s define another grid with 4 columns and 3 rows to create the look and feel of the play control part. To distinguish it from the background, use a slightly different yellowish color, such as bg-amber-100.

<GridLayout
  class="bg-amber-100 border-4 border-black rounded-b"
  rows="80, 100, 90"
  columns="65,*,*,65"
>

First row, we are gonna have 2 buttons on left and right side which are Share button and Like button. And a center text area to display the current playing song. Which can be easiliy achieved like this:

<Button
  class="fas text-sm bg-transparent z-0"
  color="#000"
  col="0"
  row="0"
  :text="$fonticon('fa-arrow-up-from-bracket')"
/>
<Button
  class="fa text-sm bg-transparent z-0"
  color="#000"
  col="3"
  row="0"
  :text="$fonticon('fa-heart')"
/>

<StackLayout row="0" col="1" colSpan="2" class="py-2 color-black">
  <Label class="text-xs text-center" text="0:00 / 3:47" />
  <Label
    class="font-bold text-sm text-center"
    text="High Hopes [SOS Band Cover]"
  />
  <Label class="text-xs text-center" text="Basement Love" />
</StackLayout>

The second row, we will add 3 buttons which are prev song, play/resume and next song. Again <GridLayout> has our back.

<GridLayout
  class="mx-4 mt-8 border-2 border-r-8 border-b-8 border-black rounded"
  row="1"
  col="0"
  colSpan="4"
  columns="*,*,*"
  height="auto"
>
  <Button
    class="fas text-sm bg-transparent z-0 border-r-2 border-black"
    color="#000"
    col="0"
    row="0"
    :text="$fonticon('fa-step-backward')"
  />
  <Button
    class="fas text-sm bg-transparent z-0"
    color="#000"
    col="1"
    row="0"
    :text="$fonticon('fa-play')"
  />
  <Button
    class="fas text-sm bg-transparent z-0 border-l-2 border-black"
    color="#000"
    col="2"
    row="0"
    :text="$fonticon('fa-step-forward')"
  />
</GridLayout>

In the final row, we need to add two buttons: AirPlay and Sign In. While we won’t implement these functions in this tutorial, we’ll include them in the UI to capture the PoolSuite vibe.

<Button
  class="text-right text-sm pr-4 bg-transparent z-0"
  row="2"
  col="1"
>
  <FormattedString>
    <Span class="fa" :text="$fonticon('fa-paper-plane')" />
    <Span text=" Airplay" />
  </FormattedString>
</Button>

<Button
  class="text-left text-sm pl-4 bg-transparent z-0"
  row="2"
  col="2"
>
  <FormattedString>
    <Span class="fa" :text="$fonticon('fa-user')" />
    <Span text=" Sign in" />
  </FormattedString>
</Button>

And here is our final result:

Play control

To be continue …

This article is getting lengthy, so we will pause here for now. The basic UI we’ve created is a work in progress and doesn’t match the polished look of the original PoolSuite FM. In the next part, we’ll work on enhancing our UI to give it a cooler appearance. The next part will be available in a few days. If you’re eager to proceed, check out the latest source code on the GitHub repo.

Series NavigationAndroid PoolSuite FM in NativeScript, Part 2: Refining the UI >>

Leave a Reply