fieldnotes/src/store/sagas/wifi-networks.js

168 lines
4.9 KiB
JavaScript

import { all, put, takeLatest, call, take } from 'redux-saga/effects';
import {
WIFI_ENABLED_REQUEST, WIFI_ENABLED_FAILURE, WIFI_ENABLED_SUCCESS,
TOGGLE_WIFI_REQUEST, TOGGLE_WIFI_SUCCESS, TOGGLE_WIFI_FAILURE,
NOTIFICATION_LEVEL_ERROR, addNotification,
SCAN_WIFI_NETWORKS_FAILURE, SCAN_WIFI_NETWORKS_REQUEST, SCAN_WIFI_NETWORKS_SUCCESS, CONNECT_WIFI_NETWORK_FAILURE, CONNECT_WIFI_NETWORK_REQUEST, CONNECT_WIFI_NETWORK_SUCCESS, NOTIFICATION_LEVEL_SUCCESS, GET_WIFI_NETWORK_SSID_FAILURE, GET_WIFI_NETWORK_SSID_SUCCESS, GET_WIFI_NETWORK_SSID_REQUEST, connectionChanged, CONNECTION_CHANGED,
} from "../actions";
import wifi from 'react-native-android-wifi';
import NetInfo from '@react-native-community/netinfo';
import { eventChannel } from 'redux-saga';
export function* wifiNetworksSaga() {
yield all([
takeLatest(WIFI_ENABLED_REQUEST, isWifiEnabledSaga),
takeLatest(TOGGLE_WIFI_REQUEST, toggleWifiSaga),
takeLatest(SCAN_WIFI_NETWORKS_REQUEST, scanWifiNetworksSaga),
takeLatest(CONNECT_WIFI_NETWORK_REQUEST, connectToWiFiNetworkSaga),
takeLatest(GET_WIFI_NETWORK_SSID_REQUEST, getWifiNetworkSSIDSaga),
connectionStatusSaga(),
]);
}
function* isWifiEnabledSaga() {
try {
const enabled = yield isWifiEnabled();
yield put({ type: WIFI_ENABLED_SUCCESS, enabled });
} catch(err) {
yield put({ type: WIFI_ENABLED_FAILURE, err });
}
}
function* toggleWifiSaga({ enabled }) {
try {
yield toggleWifi(enabled);
yield put({ type: TOGGLE_WIFI_SUCCESS, enabled });
} catch(err) {
yield put({ type: TOGGLE_WIFI_FAILURE, err, enabled });
yield put(addNotification(NOTIFICATION_LEVEL_ERROR, "Impossible d'activer la connexion WiFi !."));
}
}
function* scanWifiNetworksSaga() {
try {
const results = yield scanWifiNetworks();
yield put({ type: SCAN_WIFI_NETWORKS_SUCCESS, networks: JSON.parse(results)});
} catch(err) {
yield put({ type: SCAN_WIFI_NETWORKS_FAILURE, err });
yield put(addNotification(NOTIFICATION_LEVEL_ERROR, "La récupération des points d'accès WiFi a échoué !"));
}
}
function* connectToWiFiNetworkSaga({ ssid, password, timeout }) {
try {
const isEnabled = yield isWifiEnabled();
if (!isEnabled) {
yield toggleWifi(true);
}
yield connectToWiFiNetwork(ssid, password, timeout);
yield put({ type: CONNECT_WIFI_NETWORK_SUCCESS, ssid, password });
yield put(addNotification(NOTIFICATION_LEVEL_SUCCESS, "Connexion réussie."));
} catch(err) {
yield put({ type: CONNECT_WIFI_NETWORK_FAILURE, err, ssid, password });
yield put(addNotification(NOTIFICATION_LEVEL_ERROR, "Impossible de se connecter au réseau WiFi !"));
}
}
function* getWifiNetworkSSIDSaga() {
try {
const ssid = yield getWifiNetworkSSID();
yield put({ type: GET_WIFI_NETWORK_SSID_SUCCESS, ssid });
} catch(err) {
yield put({ type: GET_WIFI_NETWORK_SSID_FAILURE, err });
}
}
function connectionStatus() {
return eventChannel(emitter => {
const connectionChangeHandler = state => {
emitter({ type: state.type });
};
NetInfo.addEventListener(connectionChangeHandler);
return () => {
NetInfo.removeEventListener(connectionChangeHandler);
}
});
}
function* connectionStatusSaga() {
const chan = yield call(connectionStatus)
try {
while (true) {
let change = yield take(chan);
yield put(connectionChanged(change.type));
}
} finally {
console.log('connection status channel terminated')
}
}
function isWifiEnabled() {
return new Promise((resolve, reject) => {
try {
wifi.isEnabled(resolve);
} catch (err) {
reject(err);
}
});
}
function toggleWifi(enabled) {
return new Promise((resolve, reject) => {
try {
wifi.setEnabled(enabled);
resolve(enabled);
} catch (err) {
reject(err);
}
});
}
function scanWifiNetworks() {
return new Promise((resolve, reject) => {
wifi.reScanAndLoadWifiList(resolve, reject);
});
}
function connectToWiFiNetwork(ssid, password, timeout) {
return new Promise((resolve, reject) => {
let timedOut = false;
let timeoutId;
const connectionChangeHandler = evt => {
if (evt.type !== 'wifi') return;
cleanup();
return resolve();
};
const cleanup = () => {
clearTimeout(timeoutId);
NetInfo.removeEventListener('connectionChange', connectionChangeHandler);
};
timeoutId = setTimeout(() => {
cleanup();
timedOut = true;
return reject(new Error('Could not connect.'));
}, timeout);
NetInfo.addEventListener('connectionChange', connectionChangeHandler);
wifi.findAndConnect(ssid, password, (found) => {
cleanup();
if (timedOut) return;
if (!found) return reject(new Error("Network not found !"));
return resolve();
});
});
}
function getWifiNetworkSSID() {
return new Promise((resolve, reject) => {
try {
wifi.getSSID(resolve);
} catch(err) {
reject(err);
}
});
}