Toasts and Alerts
komunikácia s používateľom pomocou Toast
-u a Alert
dialógu, ukončenie aplikácie, zistenie platformy
Záznam z prednášky
Introduction
(slide) stále pracujeme na baterke
- už nám síce pracuje (a čo je najdôležitejšie - svieti), ale to nie je všetko
- musíme ošetriť napr. prípady, kedy bude aplikácia spustená na zariadení, ktoré nie je vybavené bleskom a teda svietiť nebude
- a taktiež musíme vyriešiť situáciu, keď aplikácia bude spustená na Android-e, ale nebude mať práva na prístup ku blesku
- a popri tom by bolo dobré komunikovať s používateľom a informovať ho o všetkom, k čomu došlo
Device doesn’t have a Torch
Prípad, kedy zariadenie nie je vybavené bleskom, bude zastupovať emulátor. Pozrime sa teda na spustenie aplikácie na ňom.
Ak aplikáciu spustíme, tak sa spustí normálne. Ak sa však pokúsime baterku zasvietiť, skončíme s hláškou
Possible Unhandled Promise Rejection
a so správouError: Bad argument passed to camera service
.Táto chyba priamo súvisí s kamerou, kedy dochádza k požiadavke o jej ovládanie na zariadení, ktoré ale nemá blesk.
Fragment kódu, ktorý slúži na ovládanie blesku vo funkcii
toggleState()
teda obaľme do volaniatry-catch
tak, ako je to uvedené v dokumentácii modulureact-native-torch
. To znamená, že z funkcie musíme spraviť asynchrónnu funkciu a počkáme si na výsledok volaniaTorch.switchState()
pomocou kľúčového slovaawait
:const toggleState = async function () { try { await Torch.switchState(!isOn); setIsOn(!isOn); catch (e) { } console.log(e); }; }
Notifying the User
V kóde sme síce situáciu o neexistencii blesku vyriešili bez toho, aby beh aplikácie zlyhal, musíme však o vzniknutej situácii informovať aj používateľa. Na to nám totiž rozhodne nebude stačiť vypisovanie do konzoly cez
console.log()
.Na to samozrejme môžeme použiť niekoľko spôsobov.
Toast
(slide) React Native’s ToastAndroid API exposes the Android platform’s ToastAndroid module as a JS module. It provides the method
show(message, duration)
which takes the following parameters:- message A string with the text to toast
- duration The duration of the toast—either
ToastAndroid.SHORT
orToastAndroid.LONG
Upravíme kód:
// import ToastAndroid first import { ToastAndroid } from "react-native"; const toggleState = async function () { try { await Torch.switchState(!isOn); setIsOn(!isOn); catch (e) { } .show( ToastAndroid"No camera available. Go and buy a device \ with some and come back later.", .SHORT ToastAndroid; ) }; }
Toto však funguje len na Android-e. Aby sme to použili správne, môžeme si overiť platformu pomocou modulu
Platform
:// import Platform first import { Platform } from "react-native"; const toggleState = async function () { try { await Torch.switchState(!isOn); setIsOn(!isOn); catch (e) { } if(Platform.OS === 'android'){ .show( ToastAndroid"No camera available. Go and buy a device \ with some and come back later.", .SHORT ToastAndroid; )else{ }console.log('No camera available. Go and buy \ a device with some and come back later.') } }; }
Ak chceme, aby aplikácia fungovala multiplatformne, tak
Toast
asi nie je najlepší nápad, aj keď vyzerá dobre ;) Existujú však rozšírenia, pomocou ktorých je možné správanie Toast-u zabezpečiť aj na iných platformách. Napríklad react-native-simple-toast alebo react-native-toast-message.
Alert
(slide) Launches an alert dialog with the specified title and message.
Poznáme zo štandardného JavaScript-u v prehliadači, ale v React Native reprezentuje API, ktoré funguje na platformách Android aj iOS. Existuje však rozdiel v jeho používaní na jednotlivých platformách. O tom sa dočítate v dokumentácii.
Obecne sa
Alert
skladá z:- titulku / nadpisu,
- správy, a
- voliteľne zo zoznamu tlačidiel s možnosťou vlastného ošetrenia ich stlačenia
Jednoduchý
Alert
pre náš prípad môže vyzerať nasledovne:// update the import for Alert import { Alert } from "react-native"; const toggleState = async function () { try { await Torch.switchState(!isOn); setIsOn(!isOn); catch (e) { } .alert( Alert'Error', 'No camera available. Go and buy a device \ with some and come back later.' ; ) }; }
Exit App
Používateľa sme teda síce upozornili, takže teraz môže klikať a šťukať a bude mu zobrazovať len
Alert
dialóg. To je však celkom trápne, nakoľko vlastne na existencii blesku stojí celá naša aplikácia. Vhodnejšie by bolo napríklad aplikáciu rovno vypnúť, keď príde na to, že blesk nemá.Priama podpora pre vypnutie aplikácie v React Native však nie je. Túto funkcionalitu nám teda zabezpečí externý modul s názvom react-native-exit-app. Nainštalujeme ho príkazom:
$ npm install react-native-exit-app --save
a zlinkujeme s projektom príkazom:
$ react-native link react-native-exit-app
Upozornenie
Je pravdepodobné, že bude potrebné znovu zostaviť celý projekt. Preto najprv vojdite do priečinku
android/
a spustite príkaz:$ ./gradlew clean
Následne sa vráťte do koreňového priečinku a spustite aplikáciu príkazom:
$ npx react-native run-android
Jej použitie je následovne veľmi jednoduché - na vhodnom mieste stačí zavolať:
import RNExitApp from 'react-native-exit-app'; ... .exitApp(); RNExitApp...
Upravíme teda kód našej aplikácie tak, že po kliknutí na tlačidlo v
Alert
dialógu dôjde k ukončeniu aplikácie pomocou tohto volania:const toggleState = async function () { try { await Torch.switchState(!isOn); setIsOn(!isOn); catch (e) { } .alert( Alert"Error", "No camera available. Go and buy a device \ with some and come back later.", [ {text: "Quit", onPress: function () { .exitApp(); RNExitApp, }, } ]; ) }; }
Test Before Run
- Aktuálne teda funguje všetko ako má. Ak sa však zamyslíme nad fungovaním, tak nie je veľmi praktické, aby používateľ aplikáciu musel spustiť a až po kliknutí na obrázok alebo tlačidlo došlo k vyhodnoteniu, či je alebo nie je blesk k dispozícii. Toto naozaj nie je UX, ktorý by sme chceli mať.
- Ak sa zamyslíme, tak vieme, že kód sa vykonáva v rámci funkcie zhora nadol, pričom funkcia musí vrátiť view komponentu. Ak teda na začiatku kódu vložíme fragment, ktorým overíme, či máme alebo nemáme blesk k dispozícii, vyriešili by sme tento problém.
Conclusion
- Na to, aby sme problém so spustením špecifického kódu po spustení kontroléru vyriešili, potrebujeme poznať a porozumieť životnému cyklu kontajnera. A ten si predstavíme nabudúce.