Home — Dashboard Principal
Tela central do app após o login. Exibe uma grade de atalhos para todos os módulos disponíveis ao usuário, com visibilidade controlada por permissões. Inclui rastreamento de localização para motoristas, badge de notificações e botões de contato com a Monisat.
Layout e Grid de Atalhos
Android — HomeFragment + HomeAdapter
A grade é um RecyclerView com GridLayoutManager. O número de colunas é responsivo:
| Dispositivo | Colunas |
|---|---|
| Telefone (padrão) | 2 colunas |
Tablet (sw600dp) | 3 colunas |
Cada botão é representado pela classe interna ButtonData do HomeAdapter:
data class ButtonData(
val id: Int,
val text: String,
val image: Int, // drawable resource
var isVisible: Boolean
)
A ordem dos botões é persistida em SharedPreferences("button_layout"), permitindo que o usuário reorganize os atalhos. Botões invisíveis ficam ao final da lista mas não aparecem na UI.
iOS — HomeViewController
Cards são renderizados dinamicamente em um UIScrollView com grade de 2 colunas via addVisibleCards(). Cada card é modelado pelo struct:
struct ScreenInfo {
let id: Int
let name: String
let image: UIImage?
let backgroundColor: UIColor
var isVisible: Bool
var permScreenName: String // chave de permissão
var isEnabled: Bool // false = "em breve" / manutenção
}
Alterações de visibilidade são propagadas via protocolo ScreenInfoDelegate → screenVisibilityChanged(atIndex:isVisible:).
Módulos e Navegação
| Módulo | Android (destino nav) | iOS (segue) | Perm Android | Perm iOS |
|---|---|---|---|---|
| Grid de Viagens | nav_grid_trip | gridSegue | 52, 53, 54 | VEI_V |
| Viagens (cadastro) | nav_trips_buttons | navCadTripSegue | 1, 8, 93, 94 | EMP |
| Mapa / Rastreamento | nav_map | mapSegue | 1, 8 | VEI |
| Veículos | nav_grid | vehiclesSegue | 1, 8 | RAS_C |
| Minhas Viagens | nav_trip_menu_driver | driverSegue | 1, 8, 99 | CHE_C |
| Desconsideração | nav_disregard | navDisregard | 1, 8 | USE |
| Checklist | nav_checklist | buttonsSegue | 1, 8, 141 | CHE_C |
| Relatórios | nav_report | — | 1, 115 | — |
| Jornada | nav_journey | — | 1, 8, 99 | — |
isEnabled = false o card exibe o overlay "Em Breve" e não navega. No Android o mesmo efeito é obtido via botão de "Coming Soon" (HomeAdapter.addComingSoonButton()).
Controle de Permissões
Android
As permissões são lidas de SharedPreferences("DATA"), chave "perms_user" (JSON array de strings). O HomeFragment itera os botões e chama adapter.updateVisibility() com base nos códigos presentes:
// Exemplos de verificação
permissionsJson.contains("52") // acesso ao Grid
permissionsJson.contains("141") // acesso ao Checklist
permissionsJson.contains("115") // acesso a Relatórios
iOS
Permissões são lidas do UserDefaults como strings nomeadas. configButtons() percorre o array screens e define isVisible em cada ScreenInfo:
// Chaves de permissão iOS "VEI_V" → Grid de veículos "EMP" → Viagens / cadastro "RAS_C" → Veículos "VEI" → Mapa "CHE_C" → Checklist / Minhas Viagens "USE" → Desconsideração
Papéis de usuário
| Papel | Acesso |
|---|---|
| master | Todos os módulos disponíveis conforme permissões da empresa |
| motorista | Apenas "Minhas Viagens" (nav_trip_menu_driver / driverSegue) |
| responsavel | Subconjunto configurável de módulos |
SharedPreferences("user_id"), chave "user_role". Motoristas recebem onResume() acionando os serviços de localização automaticamente.
Localização em Tempo Real (Motoristas)
Android — FusedLocationProviderClient
Para usuários com papel motorista, o HomeFragment.onResume() solicita permissões de localização em foreground e background. A localização é enviada ao backend via serviço de background.
// Verificação de papel no onResume
if (userRole == "motorista") {
requestForegroundLocationPermission()
requestBackgroundLocationPermission()
}
iOS — CLLocationManager + WebSocket
O HomeViewController implementa CLLocationManagerDelegate e URLSessionWebSocketDelegate. A localização é transmitida em tempo real via WebSocket:
// Servidor WebSocket
wss://socket.monisat.online:6001 // produção
// Payload enviado
struct UserLocationData: Codable {
var lat: CLLocationDegrees
var lng: CLLocationDegrees
var time: CLong // Unix timestamp
var battery: Int // nível de bateria (%)
var interval: Double // intervalo de envio (segundos)
var speed: Double // velocidade (m/s)
}
O WebSocketService mantém resiliência com reconexão automática (exponential backoff) e cache local de localizações para períodos offline (saveInCacheLocation(_:) → sendCachedLocations() ao reconectar).
Badge de Notificações
Ambas as plataformas exibem um badge numérico no atalho de notificações indicando mensagens não lidas.
| Plataforma | Implementação | Fonte dos dados |
|---|---|---|
| Android | Badge na TextView do botão Notificações no header | Firebase FCM + contagem local |
| iOS | fetchAndUpdateNotificationBadge() chamado no viewWillAppear | Elasticsearch (POST /usuario_notificacao/_search) |
Carrossel PagFriday (iOS)
O iOS exibe um carrossel de conteúdo promocional acima da grade de módulos, modelado por:
struct PagFridayNews {
// dados do item promocional exibido no carrossel
}
O container (pagFridayContainer) é inserido no topo do UIScrollView e atualizado via chamada à API. Se não houver conteúdo, o container é ocultado.
Botões de Contato
Ambas as plataformas exibem dois botões fixos no rodapé da Home para contato com o suporte Monisat:
| Botão | Ação | Android | iOS |
|---|---|---|---|
| Ligar para Monisat | tel: intent / URL | ic_phone_contact | Ícone de telefone |
| Converse com a Monisat | Deep link WhatsApp | ic_whatsapp_contact | Ícone WhatsApp |
No Android os botões ficam em um MaterialCardView separado por um divisor vertical. Um AlertDialog de confirmação é exibido antes de abrir o discador ou o WhatsApp.
Diálogo de Saída (Android)
O HomeFragment intercepta o botão físico de voltar (OnBackPressedCallback) e exibe um AlertDialog perguntando se o usuário deseja sair do app. Não há comportamento equivalente no iOS (o app fica em background pelo sistema operacional).
API utilizada
https://api.monisat.online/searchTrips/{company_id}
HomeViewModel para buscar resumo de viagens da empresa. Autenticação via Client-Id / User-Id / Token nos headers. O company_id é lido de SharedPreferences("DATA").
api.monisat.online). A migração para api.monisystem.com/v1 ainda não foi aplicada ao HomeViewModel.https://elastic.monisat.online:443/usuario_notificacao/_search
SharedPreferences relevantes (Android)
| Nome do arquivo | Chave | Uso |
|---|---|---|
DATA | perms_user | JSON array de permissões do usuário |
DATA | company_id | Empresa selecionada (usada na chamada à API) |
user_id | user_role | Papel do usuário: master / motorista / responsavel |
button_layout | (serializado) | Ordem e visibilidade dos botões da grade |