This application was done while the CPMDWithF course 2023 in the Innopolis University
This application provides smooth and entertaining way to view random jokes from the Chuck Norris Jokes API, search them, and then store favourite ones on the phone. The main screen's interface element is a stack of cards, which could be swiped away. Each card could be opened in the browser if double tapped. If you swipe a card to the right, it is then added to the favourites and persisted on the device's storage. The app is available in English and Tatar languages, but due to problems with localization support it is used when the system language is russian, and the region is set to Russia.
More images and a video are available by this link.
Here I will explain ordinary, hard or interesting code solutions made in this Flutter project.
This is a simple and mediocre part—it uses dio
, and JsonSerializable with a data model. The API class itself is a singleton, and has only two static methods for uploading the data.
I am using the Appinio Swiper, it provided the fancy swipable cards. However, there are some problems with reusable resources: some properties are shared incorrectly between cards, which leads to widgets having properties they don't have to have initially. For example, when each card in the deck was loading a joke via API on its own, the appinio_swiper
reused the joke text for all next cards, thus every card had the same text on it, though according to the terminal some new data was loaded by each card. This had changed responsibilities a bit, so that the jokes
widget started managing content for each card since then.
But there are still some problems with the library present. For example, each card has its own overlay with a provate property _isOverlayShown
, but when you make it true
, it seems like the current card only must change its value, but when you swipe the current card out, you discover all the other cards in the deck has the same value set to true
too. I have no explanations to this.
This state management approach is used for the main jokes screen. There is a whole controller class for the jokes screen, which holds a provider of the JokeCard
s list. The architecture used here is MVC, so the app has two view controllers: for the jokes cards screen, and for the jokes search screen.
The app is localized for the english and tatar.
The app uses Hive to store favourite jokes.
The text styles are stored in an enum
. Each has its own stylize
function which takes a color, and returns the text style. The main problem was to initialize a constant function, that could be taken by the enum
, and the only option is to create an auxiliary class with static methods, the enum
could reference to. The reason for creating such a complexe structure (instead of just const TextStyle style
) is to be independentant from colors while using the local text styles.
Well, these are just enums with constant properties.
The length of jokes could be very different, and sometimes it's too long to be shown with the default 36 dp size. So I used the AutoSizeText library to show long jokes with minimum 18 dp font size, which is much more than enough.
There are no such paramemeter as z-index
in Flutter, and it was surprising to realize that in order to make joke cards "higher" than the "Next" button, you have to make Flutter draw from the bottom. So I used a Column
, and provided its children bottom-up, and this is how cards are displayed over the Next button, when you drag them. This is a bit weird solution, because I thought this option exists only for the cases, when your interface details need to be shown bottom-up like in a message history.
Another case is to show the "Check you internet connection" message, when no cards are left in the deck. The library I used had an onEnd
callback, which couldn't consider cases when the user has no internet connection initially. The genius idea is to make this view persistent, but put under the cards. So when the cards end... there it is! The most natural and easy behavior.
Here is the download link