Application Redesign - Inside Look



Mobius bike is a bike and scooter rental service developed for Tallinn (geographic expansion is currently planned).

The first release hypothesis is “a bike rental application will be in demand in the European market”. In December 2019, the main hypothesis was revised and now it sounded like this: “can the bike and scooter rental service get maximum distribution due to convenience for the end user and franchisee?” In order to answer this question, it was necessary to implement the following:

  • carry out work on optimizing the structure of the application (both internal - backend, and external - design and frontend) to introduce a new type of transport and possible scaling in the future
  • make the rental conditions adjustable in the admin panel

Lyubov Nikiforuk - project manager




Key screens of the Mobius bike application before redesign

One of my first tasks as a product designer was to prepare layouts for introducing a new type of transport - electric scooters. Having finished with the layouts, I decided to make some changes to the design and UX applications and make a small redesign concept. Showed new layouts to the team. I got a feedback: the guys gave advice and shared their opinions. As a result, a number of key screens were typed.

The planned two-month code refactoring was approaching and we decided to show the new design to the customer in order to optimize the code for the new interface, unless, of course, the customer agrees to the redesign. We presented layouts, explained how a new design can simplify interaction with the application and what benefits it will bring to the business. And already in the process of presentation, we realized that the design "went". The redesign was approved, and now we started refactoring with a new interface and redesigned UX.



Variants of the key screens that were created during the redesign process

Organization of work


Since we did not have a clearly defined technical task and our service developed along with the business, we had to decide how we would carry out the work: what tasks to take in the first place, how to track progress and evaluate the result. Most of all, the agile method suited our tasks. The duration of each sprint we determined in two weeks. Every day we held stand-ups - discussed current problems, shared ideas, solved problems. At the end of each sprint, a demo was carried out - they showed the client the results of the work done for the sprint.



Agile in all its glory



Test scooter in our office

Navigation


The first thing we decided to change was navigation through the application. Instead of a “burger,” we made a lower tab menu (bottom navigation). You've probably noticed that many applications are switching to this type of navigation. And this is understandable, since the tab menu simplifies access to the main sections of the application, even if a person holds the phone with one hand. But this is not the only reason for using this type of navigation. The application is developed on React Native, so we had to consider the features of this platform:

(). , , , , , , . . . ,

— front-end




— «». — (bottom navigation)

, , UI-kit


In addition to changing the navigation, we abandoned the scale controls on the application screen. Left the zoom with gestures. Replaced modal windows, dialogs and part of the screens with swipe-up screens. Again, because it is more convenient to use the application with one hand - such a screen can simply be "swiped" down and closed.



Examples of swipe-up screens in the Mobius bike application after the redesign

We also simplified the registration process in the application by logging in via Google and Facebook. In addition to linking bank cards, they added the ability to pay using Apple Pay and Google Pay.



The screen for entering the application and payment using Apple Pay

In order to make it easier to add new features to the application in the future, we created a library of components and described their application and principles of interaction.



Mobius bike UI-kit applications

Refactoring and switching to GraphQL


The main objectives of the redesign were:

  • create a more flexible and scalable system of components that would easily allow adding new functionality, for example, another type of transport, without compromising the appearance and general logic of interaction with the application
  • lighten and simplify the interface as much as possible
  • "Refresh" the appearance of the application


But besides updating the application interface, the visible side of the redesign, the transition from the RESTful API to GraphQL was a very important part.

To put it simply, GraphQL is a syntax that describes how a client (phone / application) receives data from a server using special queries. Depending on the request, the server gives this or that data.

Artyom Bukhtoyarov - DevOps / Backend Developer


GraphQL has three main characteristics:

  • allows the client to specify exactly what data he needs
  • facilitates aggregation of data from multiple sources
  • uses a type system to describe data


GraphQL acts as an adapter layer between the application interface and external services. This allows you to transfer the processing of many different requests to the back. That is, when you connect a new transport protocol, you will need to connect it on the back, and the layout will receive all the data in a unified form from GraphQL. Thus, we reduced the need for additional typesetting work when adding a new type of transport and reduced the number of processed requests in the application.

In addition, in the process of refactoring, we highlighted the following advantages of using GraphQL:

  • convenient documentation for the developer
  • a good solution for WebSocket, both for the backend and frontend
  • GraphQL makes it easier for developers to navigate the code structure
  • more flexible development, compared to the RESTful API, allows you to add something new faster and easier (in our case, this is a new type of transport)


It was funny when the very first bicycle lock from China determined its geo-location in China, although it was physically in St. Petersburg. And the software for this lock was encrypted and we had to look for a decryption method to make changes to the settings.

Initially, when we had only one type of transport, the server for connecting bicycles worked together with the main backend. Then, we took out the server for bicycle locks as an independent service that can be deployed on separate servers - this allowed us to reduce the load on the main server and provided additional opportunities for scaling. To transfer messages between services, we use RabbitMQ. And it was very convenient that he has a plugin for mqtt - the protocol on which our scooters work, which made it easy to add a new mode of transport.

Payment in the application. Initially, we planned to add bank cards in the application itself, but in the end we settled on a redirect option to the bank page and the whole process of adding a card is already taking place there. This method turned out to be much easier to implement.

Franchise and Administration


The service owner had certain requirements for the admin panel of the application. Since it is planned that the service will be sold as a franchise, each franchisee should be able to edit the cost of the trip, tariff parameters, subscriptions, etc.

Therefore, we redesigned the admin panel for the ability to connect new park owners. Added different roles - the owner of the park and the owner of the network. We made a whole section for adding and editing time-based tariffs, subscriptions and fines. In each city, the owner of the park will be able to set their own tariffs and change them. They also made it possible to moderate the changes by the network administrator. We expanded the structure of the admin panel to add new types of transport.

Problems


Of course, there were some difficulties. We refused to visualize the route in the history of trips, since. The GPS module in the bike lock does not always correctly transmit the coordinates. And instead of a beautiful route line, like on a Dribble shot, we got this:



Waiting for VS reality

There was a problem in the technical implementation of Google maps under React Native. The marker on the map needs to be constantly redrawn in order to change his position on the map. Redrawing vector graphics in large quantities is not optimized and therefore, with certain settings, everything was very slow. And we decided to replace vector markers on the map with raster ones in png format. This gave a significant increase in the speed of the application.

Many questions were around the implementation of the tariff system and subscription. We tried to provide different cases: what to do if the subscription ends during the trip, whether to give the opportunity to buy different subscriptions for one type of transport, whether it is worth doing auto-renewal of subscriptions, how to calculate the cost of the trip, and so on.

As a result, we settled on the following rating option: the travel time is divided into unequal segments and each time interval is charged separately. For example, the first 15 minutes of the trip cost € 2, if you ride for more than 15 minutes, but less than half an hour, then the cost of the trip is € 3.5, from 30 minutes to an hour - € 5, etc. And to make it easier for the user to navigate the tariffs, we decided to visualize the cost calculation and made it into a progress bar. Now the user can see how the cost of the trip changes in real time.



Costing visualization in the form of progress bar



Screens with tariffs and subscriptions

Some users found the option of not paying for the trip: they added a bank card, then deleted it and rode for free. When we found this, we began to block € 1 to check our solvency and removed the ability to remove the card during the trip or if there is an unpaid debt.

Also sometimes there were problems with completing the trip. To complete the bike ride you need to close the lock, which transfers information to the server. But the castle did not always transmit data on time. And in the end, people could accumulate debt of several hundred euros for supposedly unfinished trips. We decided that we would check large amounts manually and removed auto-recording for them. There were almost no complaints, since in Europe few people have SMS alerts. In Russia it would be different.

findings


Frontend


One of the main features of development on React Native is the tracking of component performance. To prevent a decrease in fps, it is worth:
  • monitor the number of renderers (redraws). A component should be redrawn only if the new data coming into it really needs to change the state of the interface
  • use native Animated animation from the standard React Native package using the useNativeDrive key in the animation config or the Reanimated package
  • review JS code of packages or components added to the project. Not all available packages may be optimized, or correctly using the features of React Native. Also in development on React Native it is worth considering differences of platforms. One and the same code on iOS and Android can work in completely different ways

The strength of React Native can be called its versatility. No need to have 2 different development teams on iOS and Android. Also, often, you can implement design concepts that are more difficult to develop on native platforms.

The weakness of React Native is not its full nativeness. You must constantly ensure that you do not overload JS-thread. The soreness of updating and installing native packages up to version 0.60 until autolinker was introduced.

Backend


Switching to GraphQL in most cases simplified the development of the API. It has become clearer for both the developer and the client.

GraphQL advantages:
  • it is possible to automatically document the API and it is very convenient
  • allows more flexible work with the API. The client selects only the data that he needs at the moment
  • out of the box support for web sockets, which was very important since we often update real-time data
  • we can easily write scalar types if necessary and reuse them later


GraphQL weaknesses:
  • harder to do features by type of pagination. I have to apply additional technologies
  • Out of the box there is no namespace. You need to take care of the separation of the API yourself. At the same time, there is support for deprecated fields, which further simplifies the life of the developer
  • you need to monitor the nesting levels for queries. You can write a request with a lot of nesting and then wait a long time for an answer


Interface


When working on a redesign, you need to remember that you should not do design for the sake of design. In our case, the new interface made it possible to simplify user interaction with the application, including if a person holds the phone with one hand. We took into account the features of React Native and, in order to reduce nesting, we switched from a “burger” to bottom navigation. It is also necessary to lay the possibility of scaling the structure of the application. Creating a component library and applying atomic design can help here.

We plan to introduce gamification (get nice bonuses for kilometers traveled), a dark theme, connecting to phone contacts and notifying friends traveling nearby and introducing new modes of transport. But most importantly, the redesign must be justified: to benefit the business and simplify the work with the application for the user.

All Articles