Flutter Timer: Piva — Localization, Notification, Managing State - Part 1

Alper Efe Şahin
6 min readApr 19, 2022

--

Hello folks! After a long time, it’s time to do the middle Flutter app.

First things first, let’s start with, what is the Piva?

Flutter Timer: Piva

Let’s think about whether you are a student or a worker, it does not matter. It’s common that almost every person when they work, set time to evaluate their work time. Piva supplies this to you via Flutter. You just have to set a time, and that’s it. When the time is up, it’ll send notifications to you, even foreground and background (locked phone, switching apps, etc.).

Also If you need multiple languages, you can easily implement them, via the localization folder (right now the app has 2 languages, Turkish, and English).

Simple, but useful.

Some Gifs from the app:

Now, we can start to build our timer project.

Before starting our project, we need to get packages, used in the project.

pubspec.yaml

After getting the packages, we can create the architecture of folders for our app.

architecture of folders

Here we have lib. folder, and assets folder mainly. Simply, the assets folder holds our images. The lib. folder is a folder that holds the subfolders of our codes. Next, there are 3 more folders. If you heard about DDD architecture, or If you know it, you can pass this section, but If you do not, let’s dive in.

During my research, I realized that the ‘best’ architecture was Domain-Driven Design(DDD), and I encountered the Domain-Driven Design(DDD) tutorials published by Reso Coder and explained by Erkan Sahin. This architecture made a lot of sense. I’ll use Erkan Sahin’s words to explain them.

Reso Coder separates the app into four main layers.

Domain: The layer where your model classes, custom failure classes, and interfaces exist (e.g. user_model.dart).

Infrastructure: The layer that implements the interfaces you defined in the Domain layer (e.g. firebase_auth_service.dart).

Application: The business logic and state management are handled in this layer (e.g. auth_cubit.dart).

Presentation: The UI of your app. The presentation layer is where your Widgets reside (e.g. sign_in_page.dart).

We use only 3 folders from them. Application, infrastructure, and presentation layers, since we do not need the domain layer while creating our app.

Now, we can start diving into folders in order.

Application Folder

Piva Timer has 2 business logic, which is localization and timer. Localization is used for managing the language of the app, and the timer is used for managing the main idea of the app that timer.

Localization

First, create a cubit with a name localization. It’ll create automatically since we use “Freezed” package and the “BloC” extension from the VSCode. We have just one state, which is the language of the app, with the name appLanguage. The type of the appLanguage is Locale. So, when we change the value of the Locale, the app will change the language of the app. Also, we need to specify the default value, or we can set required the appLanguage. The default value of the appLanguage is the English language, so I set the value with “en”. It’s coming from the language code of the country.

localization_state.dart

When we set the state, now we need to run one important code, which provides generating code automatically.

flutter pub run build_runner build --delete-conflicting-outputs

Then, we’ll see such information message.

freezed information

It’ll create localization_cubit.freezed.dart file for us.

Next, we can organize the localization_cubit.dart file.

localization_cubit.dart

This business logic has only one function, which is updateAppLanguage. When we want to change the language of the app, we need to press the button to change it. In the cubit section, first, we control it, If the app language is English (default one), then do it in some other language (I have chosen Turkish, so I set the parameter with “tr”). Else (this means If it isn’t an English language), do it in English. So, we change the state using this function, that’s it for the localization part (If you have any questions, you can ask in the comments, or you can visit the localization documentation here).

Once we did localization, It’s time to do the business logic of the timer.

Timer

Let’s apply the same way above. Create a new cubit with a name timer. First, we need to set the state. It isn’t like localization, there are many states we need.

timer_state.dart
  • hourOfNumberPicker, minuteOfNumberPicker, and secondOfNumberPicker are necessary for numberpicker package. Here we’ll pick the time via NumberPicker widgets. You can set their default value to what you want.
  • isTimerStopped, isTimerReset, and isTimersDurationUp are the type of boolean. Using these values, we can control our timer. isTimerStopped is used for is the timer stop or not. If it’s stopped, then we can show the “Resume” string for the text of the button. isTimerReset is used for If the timer is reset, then show the starting point, which is setting the timer. If it’s not, then show the duration spent by the user, after starting.
  • durationOfTimer, and spentFocusedTime are necessary for our timer. Using these states, we can manage the time. These are actually the brains of the app since Piva leans on “timer”.

Now, you can ask about const TimerState._(); section of the code above. As I mentioned before, you can create special methods like SignUpState.loading(), etc.

Next, we can organize the timer_cubit.dart file.

timer_cubit.dart

Here we have lots of functions that are not the same as localization cubit. We have more logic. Luckily, the name of the functions is so explicit. So, we can understand what they do.

For instance, let’s handle resetTimer() function. When the user presses a button, then it will reset the value of the timer. Let’s handle one more function. updateHourOfNumberPicker() function. When the user changes the hour value of the timer, then the hour of the timer will change.

A significant section of the app, which is business logic, has been done. Part one is also done. This medium article has 3 parts. In the next part, I will explain the Infrastructure folder. And the last part will have the presentation folder of the app. You can read in order. Thanks for reading! See you in the other parts…

--

--