UNPKG

react-native-toast-hybrid

Version:

A toast that can be used for react-native, while available for native android, ios.

135 lines (134 loc) 3.87 kB
import { useRef, useEffect } from 'react'; import { BackHandler } from 'react-native'; import ToastHybrid from './NativeToast'; let defaultDuration = 2000; export default class Toast { static instances = new Set(); static config(options = {}) { defaultDuration = options.duration || defaultDuration; ToastHybrid.config(options); } static text(text, duration = defaultDuration) { new Toast().text(text, duration); } static info(text, duration = defaultDuration) { new Toast().info(text, duration); } static done(text, duration = defaultDuration) { new Toast().done(text, duration); } static error(text, duration = defaultDuration) { new Toast().error(text, duration); } static loading(text) { return new Toast().loading(text); } static hideAll() { Array.from(Toast.instances).forEach(t => t.hide()); } underlying = null; constructor() { Toast.instances.add(this); } ensure() { if (this.underlying !== null) { return this.underlying; } const underlying = ToastHybrid.createToast(); return underlying; } closed = false; timer = null; loading(text) { if (!this.closed) { this.clearTimeout(); this.underlying = this.ensure(); this.underlying.then(key => { this.clearTimeout(); ToastHybrid.loading(key, text); }); } return this; } clearTimeout() { if (this.timer !== null) { clearTimeout(this.timer); this.timer = null; } } text(text, duration = defaultDuration) { return this.show(ToastHybrid.text, text, duration); } show(fn, text, duration) { if (duration === 0) { if (this.underlying === null) { return this; } this.hide(); return this; } if (!this.closed) { this.clearTimeout(); this.underlying = this.ensure(); this.underlying.then(key => { if (!this.closed) { fn(key, text); this.clearTimeout(); this.timer = setTimeout(() => this.hide(), duration); } else { this.hide(); } }); } return this; } info(text, duration = defaultDuration) { return this.show(ToastHybrid.info, text, duration); } done(text, duration = defaultDuration) { return this.show(ToastHybrid.done, text, duration); } error(text, duration = defaultDuration) { return this.show(ToastHybrid.error, text, duration); } hide() { Toast.instances.delete(this); this.clearTimeout(); if (this.underlying !== null) { this.underlying.then(key => { ToastHybrid.hide(key); }); this.underlying = null; } } shutdown() { this.closed = true; this.hide(); } } export function useToast() { const toastRef = useRef(new Toast()); useEffect(() => { const toast = toastRef.current; toast.closed = false; return () => { toast.shutdown(); }; }, []); useEffect(() => { function handleHardwareBack() { const toast = toastRef.current; if (toast.underlying !== null) { toast.hide(); return true; } return false; } const subscription = BackHandler.addEventListener('hardwareBackPress', handleHardwareBack); return () => { subscription.remove(); }; }, []); return toastRef.current; }