react-nativemobx-state-treemapbox

DroneLogbook - Application mobile companion

By Amaury CIVIER
Picture of the author
Published on
Role
Main mobile developer
Dronelogbook mobile application presentation
Dronelogbook mobile application presentation
Dronelogbook mobile application main screen
Dronelogbook mobile application main screen

Présentation

As a freelance developer, I had the opportunity to design and develop the DroneLogbook companion mobile application. DroneLogbook is a platform that simplifies drone operations for businesses and individuals conducting professional drone missions. The platform provides tools to manage personnel (pilots, observers, trainers, etc.), drone fleets, mission planning, and more.

Main Features of the Mobile Application

The DroneLogbook mobile app is primarily designed for drone pilots to simplify mission management, as well as drone and equipment management:

  • Create a flight mission with defined airspace boundaries.
  • Declare a flight in the airspace via LAANC
  • Manage entries for drones, equipment, missions, locations, documents, and more.
  • Provide weather information.
  • Offline-oriented application functionality.
  • Display airspace regulations for surrounding areas.
  • Sync drone logs (compatible with DJI, Autel, Skydio).
  • Push notifications.
  • Multi-language support (English, French, Slovenian, German, Italian).

Technical Choices

React-Native & Typescript

The mobile app was developed with React-Native, offering high performance for both iOS and Android with a shared codebase. Additionally, Mapbox works exceptionally well within the React-Native ecosystem.

Mapbox

Mapbox provides an interactive map in the mobile app with customizable map layers, allowing users to display airspaces on the map. Mapbox is also used for inputting the flight zone during a drone mission.

Drizzle

The application, being offline-first, includes an embedded SQLite database. Drizzle simplifies the management of the local database, including migrations and SQL query typing.

Technical Challenges

Offline-Oriented Application

The mobile application, designed for use during drone flight missions, addresses the challenge of potential network unavailability by offering offline functionality with a data synchronization mechanism.

To achieve this, each database table that can be modified and synchronized with the server includes the syncableItems properties. These properties include a GUID (allowing the mobile app to generate its own unique IDs), a flag to indicate if the object should be deleted, the last synchronization date, and a flag to indicate if the object requires synchronization.

During synchronization, the mobile application sends only the objects with the syncStatus flag set to true to the server. The server then returns a list of objects that have been synchronized.

export const syncableItems = {
  syncGUID: text("syncGUID").primaryKey(),
  userId: integer("userId").notNull(),
  companyId: integer("companyId").notNull(),
  syncIsDeleted: integer("syncIsDeleted", { mode: "boolean" }).notNull(),
  syncLastModified: integer("syncLastModified", { mode: "timestamp" }),
  syncStatus: integer("syncStatus", { mode: "boolean" }),
};

// Usage example:
export const drones = sqliteTable("drones", {
  ...syncableItems,
  active: integer("active").notNull().$type<ItemStatus>(),
  professionnal: integer("professionnal", { mode: "boolean" }), 
  name: text("name"), 
  brand: text("brand"), 
  model: text("model"), 
  // ...
})

White Labeling

DroneLogbook also provides a white-label service, allowing other companies to use its platform with custom branding. To facilitate adding new white-label clients, I implemented a configuration system for each app variant. This system enables specifying logos, colors, servers, map styles, etc., for each configuration, while maintaining the same codebase for all variants.

Example configuration file:

API_URL=https://www.dronelogbook.com
ASSETS_PATH=dlbmobile
PRIMARY_COLOR=#7FB514
LAUNCH_SCREEN=LaunchScreenDLBMobile
APP_PRODUCT_NAME="DLBMobile"
CUSTOM_MAP_STYLE=mapbox://styles/...
Variations de l'application
Variations de l'application

In addition to cosmetic differences, certain app behaviors can also vary based on the desired configuration. To avoid adding complexity to the application, dependency injection is used to specify which component should be applied for a given configuration.

// main.tsx
const DashboardContext = React.createContext<(props:any) => JSX.Element>(DefaultDashboardComponent)

export default function MyApp() {
  // Get the correct dashboard component depending of the configuration
  const dashboardComponent = getDashboardContextByConfiguration()
  return (
    <DashboardContext.Provider value={dashboardComponent}>
      <ExampleScreen />
    </DashboardContext.Provider>
  )
}

// example-screen.tsx
function ExampleScreen() {
  // Specific dashboard configuration is retrieve here, example screen is not award of which Dashboard component is used here
  const Dashboard = useContext(DashboardContext);

  <Screen>
    <Dashboard />
  </Screen>
}

DevOPS

To simplify the maintenance and deployment of the application and its white-label versions (three white-label brands, each with an iOS and Android app, totaling six apps to build and deploy on the stores), a pipeline was created using AppCenter. This pipeline enables automatic deployment of all applications simultaneously with every change in the codebase.

AppCenter Pipeline Diagram
AppCenter Pipeline Diagram
Made with Next.js & Tailwind