react-native-toast-hybrid
Version:
A toast that can be used for react-native, while available for native android, ios.
123 lines (122 loc) • 3.58 kB
JavaScript
import { useRef, useEffect } from 'react';
import { NativeModules, BackHandler } from 'react-native';
const { ToastHybrid } = NativeModules;
let defaultDuration = 2000;
export default class Toast {
constructor() {
this.underlying = null;
this.closed = false;
this.timer = null;
}
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);
}
ensure() {
if (this.underlying !== null) {
return this.underlying;
}
const underlying = ToastHybrid.create();
return underlying;
}
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 (!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() {
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;
}
BackHandler.addEventListener('hardwareBackPress', handleHardwareBack);
return () => {
BackHandler.removeEventListener('hardwareBackPress', handleHardwareBack);
};
}, []);
return toastRef.current;
}