Anul 3 Semestrul 1
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import { call, put, takeEvery, takeLatest } from 'redux-saga/effects';
|
||||
|
||||
import { Drug } from '@/redux/features/drug/drug';
|
||||
import { deleteDrug, editDrug, getDBConnection, getDrugs, insertDrug, insertTempDrug } from '@/database/localdb';
|
||||
import { setErrorStatus } from '@/redux/features/errorstatus/errorStatusSlice';
|
||||
|
||||
export function* addDrug(action: { type: string, payload: Drug }): Generator<any, void, any> {
|
||||
try {
|
||||
const db = yield call(getDBConnection);
|
||||
const id = yield call(insertDrug, db, action.payload);
|
||||
yield call(insertTempDrug, db, { id: id, type: 1 });
|
||||
const { id: _, ...payloadWithoutId } = action.payload;
|
||||
yield put({ type: "drug/addDrug", payload: { id: id, ...payloadWithoutId } });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
yield put(setErrorStatus({ message: "There has been a Local Database Error", status: true }));
|
||||
}
|
||||
}
|
||||
|
||||
export function* removeDrug(action: { type: string, payload: number }): Generator<any, void, any> {
|
||||
try {
|
||||
const db = yield call(getDBConnection);
|
||||
yield call(deleteDrug, db, action.payload);
|
||||
yield call(insertTempDrug, db, { id: action.payload, type: 2 });
|
||||
yield put({ type: "drug/removeDrug", payload: action.payload });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
yield put(setErrorStatus({ message: "There has been a Local Database Error", status: true }));
|
||||
}
|
||||
}
|
||||
|
||||
export function* updateDrug(action: { type: string, payload: Drug }): Generator<any, void, any> {
|
||||
try {
|
||||
const db = yield call(getDBConnection);
|
||||
yield call(editDrug, db, action.payload);
|
||||
yield put({ type: "drug/updateDrug", payload: action.payload });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
yield put(setErrorStatus({ message: "There has been a Local Database Error", status: true }));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function* fetchDrugs(): Generator<any, void, any> {
|
||||
try {
|
||||
const db = yield call(getDBConnection);
|
||||
const drugs = yield call(getDrugs, db);
|
||||
yield put({ type: "drug/fetchDrugs", payload: drugs });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
yield put(setErrorStatus({ message: "There has been a Local Database Error", status: true }));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import { initDB } from "@/database/localdb";
|
||||
import { call, put, select, takeEvery } from "redux-saga/effects";
|
||||
import { SERVER_IP, SERVER_PORT } from "@/constants/Constants";
|
||||
import axios, { AxiosResponse } from "axios"
|
||||
import { addDrug, fetchDrugs, removeDrug, updateDrug } from "./localdbSaga";
|
||||
import { fetch, NetInfoState } from "@react-native-community/netinfo";
|
||||
import { setConnected, setOnline } from "@/redux/features/status/statusSlice";
|
||||
import { Status } from "@/redux/features/status/status";
|
||||
import { addDrugServer, checkConnection, fetchDrugsServer, removeDrugServer, updateDrugServer, webSocketSaga } from "./serverSaga";
|
||||
|
||||
|
||||
function* initialize() {
|
||||
yield call(initDB);
|
||||
yield call(checkConnection);
|
||||
console.log("Initialized");
|
||||
yield put({ type: 'drug/fetch' });
|
||||
yield webSocketSaga();
|
||||
}
|
||||
|
||||
|
||||
function* fetchOfflineOrOnline() {
|
||||
const status: Status = yield select(state => state.status);
|
||||
if (status.isConnected && status.isOnline) {
|
||||
yield call(fetchDrugsServer);
|
||||
} else {
|
||||
yield call(fetchDrugs);
|
||||
}
|
||||
}
|
||||
|
||||
function* addDrugOfflineOrOnline(action: { type: string, payload: any }) {
|
||||
const status: Status = yield select(state => state.status);
|
||||
if (status.isConnected && status.isOnline) {
|
||||
yield call(addDrugServer, action);
|
||||
} else {
|
||||
yield call(addDrug, action);
|
||||
}
|
||||
}
|
||||
|
||||
function* removeDrugOfflineOrOnline(action: { type: string, payload: number }) {
|
||||
const status: Status = yield select(state => state.status);
|
||||
if (status.isConnected && status.isOnline) {
|
||||
yield call(removeDrugServer, action);
|
||||
} else {
|
||||
yield call(removeDrug, action);
|
||||
}
|
||||
}
|
||||
|
||||
function* updateDrugOfflineOrOnline(action: { type: string, payload: any }) {
|
||||
const status: Status = yield select(state => state.status);
|
||||
if (status.isConnected && status.isOnline) {
|
||||
yield call(updateDrugServer, action);
|
||||
} else {
|
||||
yield call(updateDrug, action);
|
||||
}
|
||||
}
|
||||
|
||||
export function* rootSaga() {
|
||||
yield takeEvery('drug/initialize', initialize);
|
||||
yield takeEvery('drug/fetch', fetchOfflineOrOnline);
|
||||
yield takeEvery('drug/add', addDrugOfflineOrOnline);
|
||||
yield takeEvery('drug/remove', removeDrugOfflineOrOnline);
|
||||
yield takeEvery('drug/update', updateDrugOfflineOrOnline);
|
||||
yield takeEvery('status/checkConnection', checkConnection);
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
import { deleteDrugServer, editDrugServer, getDrugsServer, insertDrugServer, syncOfflineData } from "@/database/serverdb";
|
||||
import { Drug } from "@/redux/features/drug/drug";
|
||||
import { all, call, put, retry, select, take } from "redux-saga/effects";
|
||||
import { deleteDrug, deleteTempDrug, editDrug, getDBConnection, getTempDrugs, insertDrug, rehydrateLocalDB, TempDrug } from "@/database/localdb";
|
||||
import { SQLiteDatabase } from "expo-sqlite";
|
||||
import { Status } from "@/redux/features/status/status";
|
||||
import { SERVER_IP, SERVER_PORT } from "@/constants/Constants";
|
||||
import { setOnline, setConnected } from "@/redux/features/status/statusSlice";
|
||||
import { NetInfoState, fetch } from "@react-native-community/netinfo";
|
||||
import axios, { AxiosResponse } from "axios";
|
||||
import { io, Socket } from "socket.io-client";
|
||||
import { store } from "@/redux/store";
|
||||
import { EventChannel, eventChannel } from "redux-saga";
|
||||
import { PayloadAction } from "@reduxjs/toolkit";
|
||||
import getSocket from "@/database/socket";
|
||||
import { setErrorStatus } from "@/redux/features/errorstatus/errorStatusSlice";
|
||||
import ReconnectingWebSocket from "reconnecting-websocket";
|
||||
|
||||
|
||||
export function* fetchDrugsServer() {
|
||||
try {
|
||||
const drugs: Drug[] = yield call(() => getDrugsServer());
|
||||
console.log(drugs);
|
||||
yield call(rehydrateLocalDB, drugs);
|
||||
yield put({ type: "drug/fetchDrugs", payload: drugs });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
yield put(setErrorStatus({ message: "There has been a Network Error", status: true }));
|
||||
}
|
||||
}
|
||||
|
||||
export function* addDrugServer(action: { type: string, payload: Drug }) {
|
||||
try {
|
||||
const drug: Drug = yield call(() => insertDrugServer(action.payload));
|
||||
const db: SQLiteDatabase = yield call(getDBConnection);
|
||||
console.log(drug);
|
||||
yield call(() => insertDrug(db, drug));
|
||||
yield put({ type: "drug/addDrug", payload: drug });
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error);
|
||||
yield put(setErrorStatus({ message: "There has been a Network Error", status: true }));
|
||||
}
|
||||
}
|
||||
|
||||
export function* removeDrugServer(action: { type: string, payload: number }) {
|
||||
try {
|
||||
yield call(() => deleteDrugServer(action.payload));
|
||||
const db: SQLiteDatabase = yield call(getDBConnection);
|
||||
yield call(() => deleteDrug(db, action.payload));
|
||||
yield put({ type: "drug/removeDrug", payload: action.payload });
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error);
|
||||
yield put(setErrorStatus({ message: "There has been a Network Error", status: true }));
|
||||
}
|
||||
}
|
||||
|
||||
export function* updateDrugServer(action: { type: string, payload: Drug }) {
|
||||
try {
|
||||
yield call(() => editDrugServer(action.payload));
|
||||
const db: SQLiteDatabase = yield call(getDBConnection);
|
||||
yield call(() => editDrug(db, action.payload));
|
||||
yield put({ type: "drug/updateDrug", payload: action.payload });
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error);
|
||||
yield put(setErrorStatus({ message: "There has been a Network Error", status: true }));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function* checkConnection() {
|
||||
try {
|
||||
yield put(setOnline(false));
|
||||
yield put(setConnected(false));
|
||||
const internetConnection: NetInfoState = yield call(fetch);
|
||||
if (!internetConnection.isConnected) {
|
||||
console.error("No internet connection");
|
||||
return;
|
||||
}
|
||||
yield put(setOnline(true));
|
||||
console.log("Internet connection available");
|
||||
const response: AxiosResponse = yield call(axios.get, `http://${SERVER_IP}:${SERVER_PORT}/`, { timeout: 5000, validateStatus: () => true });
|
||||
if (!(response.status === 200)) {
|
||||
console.error("Connection to server failed");
|
||||
return;
|
||||
}
|
||||
console.log("Connection to server successful");
|
||||
yield put(setConnected(true));
|
||||
} catch (e: any) {
|
||||
console.error(e);
|
||||
yield put(setErrorStatus({ message: "There has been a Network Error", status: true }));
|
||||
}
|
||||
}
|
||||
|
||||
export function webSocketChannel() {
|
||||
const socket = getSocket();
|
||||
return eventChannel((emit) => {
|
||||
console.log("Websocket saga started");
|
||||
socket.onopen = () => {
|
||||
console.log("Connected to WebSocket server!");
|
||||
emit({ type: "connect" });
|
||||
};
|
||||
|
||||
socket.onmessage = (event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
console.log("Received message:", data);
|
||||
emit({ type: data.event, payload: data.data });
|
||||
}
|
||||
|
||||
socket.onclose = () => {
|
||||
console.log("Disconnected from server.");
|
||||
emit({ type: "disconnect" });
|
||||
};
|
||||
|
||||
return () => {
|
||||
socket.close();
|
||||
};
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
export function* webSocketSaga() {
|
||||
const channel: EventChannel<PayloadAction> = yield call(webSocketChannel);
|
||||
const socket: ReconnectingWebSocket = yield call(getSocket);
|
||||
socket.reconnect();
|
||||
while (true) {
|
||||
const action: PayloadAction<Drug | { id: number } | void> = yield take(channel);
|
||||
console.log(action);
|
||||
const db: SQLiteDatabase = yield call(getDBConnection);
|
||||
switch (action.type) {
|
||||
|
||||
case "connect":
|
||||
console.log("Connected to server via WebSocket");
|
||||
yield put({ type: "status/checkConnection" });
|
||||
const tempData: TempDrug[] = yield call(getTempDrugs, db);
|
||||
yield call(() => syncOfflineData(tempData));
|
||||
yield call(() => fetchDrugsServer());
|
||||
yield call(deleteTempDrug, db);
|
||||
break;
|
||||
case "itemAdded":
|
||||
yield call(() => insertDrug(db, action.payload as Drug));
|
||||
yield put({ type: "drug/addDrug", payload: action.payload as Drug });
|
||||
break;
|
||||
case "itemUpdated":
|
||||
yield call(() => editDrug(db, action.payload as Drug));
|
||||
yield put({ type: "drug/updateDrug", payload: action.payload as Drug });
|
||||
break;
|
||||
case "itemDeleted":
|
||||
yield call(() => deleteDrug(db, (action.payload as { id: number }).id));
|
||||
yield put({ type: "drug/removeDrug", payload: (action.payload as { id: number }).id });
|
||||
break;
|
||||
case "disconnect":
|
||||
console.log("Disconnected from server. Reconnecting...");
|
||||
yield put({ type: "status/checkConnection" });
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user