esoftplay-event
Version:
event module on esoftplay framework
338 lines (304 loc) • 10.9 kB
text/typescript
// noPage
// useLibs
import { EventTms_homeProperty } from 'esoftplay/cache/event/tms_home/import';
import { LibCurl } from 'esoftplay/cache/lib/curl/import';
import { LibObject } from 'esoftplay/cache/lib/object/import';
import { LibToastProperty } from 'esoftplay/cache/lib/toast/import';
import { LibUtils } from 'esoftplay/cache/lib/utils/import';
import { UserClass } from 'esoftplay/cache/user/class/import';
import esp from 'esoftplay/esp';
import useGlobalState from 'esoftplay/global';
import { createTimeout, useInterval } from 'esoftplay/timeout';
import { initializeApp } from 'firebase/app';
import { createUserWithEmailAndPassword, getAuth, signInWithEmailAndPassword } from 'firebase/auth';
import { get, getDatabase, onValue, ref, set } from 'firebase/database';
import { collection, getCountFromServer, getDocs, orderBy, query, where } from 'firebase/firestore';
import { useLayoutEffect, useRef } from "react";
function readDeepObj(obj: any) {
return function (param?: string, ...params: string[]): any {
let out: any = obj
if (param) {
var _params = [param, ...params]
if (_params.length > 0)
for (let i = 0; i < _params.length; i++) {
out = out?.[_params[i]];
if (out == undefined) {
break;
}
}
}
return out;
}
}
function getBackup(path: string, onDone: (res: any) => void): any {
// let data = stateBackup.get();
// const paths = path.split('/');
// onDone(readDeepObj(data)(...paths))
}
var _installationID: any;
(async () => {
_installationID = await LibUtils.getInstallationID()
})();
function getEventPath() {
return "event" + (esp.isDebug("cc") ? "BBT" : "BBO")
}
function getRandomSuffix(time: number): number {
return Number(time + "" + (Math.floor(Math.random() * 9000) + 1000))
}
export const eventIdQueue = useGlobalState(0)
export const eventQueueConfig = useGlobalState<any>({})
const state = useGlobalState(0)
export const lastKeyInPages = useGlobalState<string[]>([])
export const userIdKeyReplacer = useGlobalState<any>({})
export default function useFirebaseSocket() {
const [status] = state.useState()
const userEmail = UserClass.state().useSelector(t => t?.email)
const userId = UserClass.state().useSelector(t => t?.id)
const app = useRef(initializeApp(esp.config().firebase, "BBOGATEv")).current
const db = useRef(getDatabase(app)).current
const auth = useRef(getAuth(app)).current
const isDirect = EventTms_homeProperty.state()
function initAppCustom() {
return esp.mod("firestore/index")().init("CUSTOM", esp.config().firebase)
}
useLayoutEffect(() => {
if (state.get() == 0 && userEmail && userId) {
signInAnonym()
initAppCustom()
}
}, [userEmail, userId])
function signInAnonym(cb?: () => void) {
const pass = LibUtils.shorten(userEmail + "" + userId)
const password = esp.mod("firestore/index")().generatePassword(pass, userEmail)
if (state.get() == 1) {
cb?.()
return
} else
doSign(userEmail, password, cb)
}
function doSign(email: string, password: string, cb?: () => void) {
signInWithEmailAndPassword(auth, email, password).then(() => {
state.set(1)
cb?.()
}).catch((err) => {
if (err.code == "auth/user-not-found") {
doRegisterFirebase(email, password, cb)
} else {
throw "ERROR : " + err.code
}
})
}
function doRegisterFirebase(email: string, password: string, cb?: () => void) {
createUserWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
state.set(1)
cb?.()
})
.catch((error) => {
if (error.code == "auth/email-already-in-use") {
doSign(email, password, cb)
} else {
throw "ERROR : " + error.code
}
});
}
function isInLocal(state: any[], code: string) {
const encodedCode = encodeURIComponent(code)
return state.findIndex(([url, post]) => (post.qr == encodedCode || post.user_qr == encodedCode)) == -1 ? false : true
}
// ini get yang di live
async function _get(path: string, gate_id: string, onDone: (res: any) => void) {
let hasDone = false
if (isDirect.get()) {
new LibCurl('gate_check/' + path + '?t=' + new Date().getTime(), { gate_id }, (res) => {
hasDone = true
onDone(res)
}, (res) => {
onDone(res)
hasDone = true
}, 1)
return
}
get(ref(db, path))
.then((sn) => {
hasDone = true
if (sn.exists()) {
onDone(sn.val())
} else {
onDone(null)
}
})
.catch((e) => {
// if (e && !hasDone) {
// getBackup(path, (res) => {
// if (res) {
// onDone(res)
// } else {
// onDone(null)
// }
// })
// }
})
}
function listenChangeTime(merchant_id: string, callback: (params: any) => void): () => void {
const onChildChange = onValue(ref(db, 'merchant_offline/' + merchant_id), (sn) => {
if (sn.exists()) {
callback(sn.val());
}
})
return () => onChildChange
}
async function _set(path: string, data: any, onDone?: (res: any) => void) {
const timeout = createTimeout()
if (state.get() == 1)
set(ref(db, path), data)
else
timeout.set(() => {
_set(path, data,)
timeout.clear()
}, 300);
}
function path(...paths: any[]): string {
return paths.join('/')
}
function addQueue(path: string, event_id: string, onSuccess?: () => void) {
const instance = initAppCustom()
if (userIdKeyReplacer.get()?.priority == 1) {
const coll = collection(instance.db, [getEventPath(), path, event_id].join('/'));
const q = query(coll, orderBy('t', 'asc'), where("t", "==", userIdKeyReplacer.get().t));
getDocs(q).then((doc) => {
if (doc.size == 0) {
LibToastProperty.show(esp.lang("lib/firebase_socket", "priority_queue_used"))
userIdKeyReplacer.set(LibObject.set(userIdKeyReplacer.get(), 0)('priority'))
addQueue(path, event_id, onSuccess)
} else if (doc.size == 1) {
// console.log("SIJI")
doc.forEach((d) => {
userIdKeyReplacer.set(LibObject.set(userIdKeyReplacer.get(), d.id)('id'))
updateQueueExp(path, event_id)
new LibCurl('event_booking_waiting_allotment_use', { event_id: event_id })
if (onSuccess) onSuccess?.()
})
} else {
LibToastProperty.show("Antrian lebih dari 1", doc.size)
}
// console.log("SIZE", doc.size)
})
} else {
// console.log("ora")
if (userIdKeyReplacer.get()?.id)
esp.mod("firestore/index")().deleteDocument?.(instance.db, [getEventPath?.(), path, event_id, userIdKeyReplacer.get()?.id], () => { }, (e) => { })
const ctime = getDateTimebyGmt7().getTime()
const time = getRandomSuffix(ctime)
const data = { t: ctime, s: time }
// console.log(data)
esp.mod("firestore/index")().addCollection?.(instance.db, [getEventPath?.(), path, event_id], data, (dt) => {
// console.log("KENE",)
userIdKeyReplacer.set?.({
id: dt.id,
...data
})
if (onSuccess) onSuccess?.()
}, (err) => {
// console.log(err)
})
}
}
function getDateTimebyGmt7() {
const ori = new Date()
// const gmt = setTimeOffset(ori)
return ori
}
// get weather function
function getQueue(path: string, event_id: string, _limit: number, cb: (idx: number, key: string) => void) {
const instance = initAppCustom()
const coll = collection(instance.db, [getEventPath(), path, event_id].join('/'));
const q = query(coll, orderBy('s', 'asc'), where("s", "<", userIdKeyReplacer.get().s));
getCountFromServer(q).then((v) => {
cb(v.data().count, userIdKeyReplacer.get().id)
}).catch((e) => {
getQueue(path, event_id, _limit, cb)
console.log({ e })
})
// /* cleanup */
// const cdate = getDateTimebyGmt7().getTime()
// if (!cdate) {
// LibToastProperty.show(esp.lang("lib/firebase_socket", "something_wrong_1"))
// return
// }
// if (!_limit) {
// LibToastProperty.show(esp.lang("lib/firebase_socket", "something_wrong_2"))
// return
// }
// if (!userIdKeyReplacer?.get()?.s) {
// LibToastProperty.show(esp.lang("lib/firebase_socket", "something_wrong_3"))
// return
// }
// const exp = query(collection(instance.db, [getEventPath(), path, event_id].join('/')), where("t", "<", cdate - _limit), orderBy('t', 'asc'), limit(10));
// const batch = writeBatch(instance.db);
// getDocs(exp).then((expd) => {
// expd.forEach((doc) => {
// if (Number(doc.data().s) < Number(userIdKeyReplacer.get().s))
// batch.delete(doc.ref)
// // console.log(doc.data().t < cdate - limit, doc.data().t, cdate - limit, cdate - limit - doc.data().t)
// // console.log('->' + moment(new Date(Number(doc.data().t))).localeFormat('DD MMMM YYYY HH:mm:ss'))
// // console.log('-->' + moment(new Date(cdate - limit)).localeFormat('DD MMMM YYYY HH:mm:ss') + '\n\n')
// })
// batch.commit()
// })
// /* end cleanup */
}
function updateQueueExp(path: string, event_id: string) {
const instance = initAppCustom()
esp.mod("firestore/index")().updateDocument(instance.db, [getEventPath(), path, event_id, userIdKeyReplacer.get().id], [{ key: 't', value: getDateTimebyGmt7().getTime() }], () => { }, (e) => {
// updateQueueExp(path, event_id, key)
})
}
function doneQueue(path: string, event_id: string, key: string, cb: Function) {
if (key) {
const instance = initAppCustom()
esp.mod("firestore/index")().deleteDocument(instance.db, [getEventPath(), path, event_id, key], () => {
cb()
userIdKeyReplacer.reset()
}, () => {
console.warn()
})
}
}
function isInPricingQueueConfig(event_id: string) {
return eventQueueConfig.get(event_id) && eventQueueConfig.get(event_id).limit > 0
}
function useQueueConfigListener() {
function action() {
fetch(esp.config("events", "queue") + "?t=" + new Date().getTime(), { "method": "GET" })
.then(res => res.json())
.then((re) => {
eventQueueConfig.set(re)
});
}
const timeout = useInterval()
action()
timeout(() => {
action()
}, 10000)
}
return {
status,
auth,
db,
signInAnonymously: signInAnonym,
get: _get,
set: _set,
isInLocal,
// getQueueConfig,
isInPricingQueueConfig,
useQueueConfigListener,
// isInBookingQueueConfig,
addQueue,
getQueue,
doneQueue,
updateQueueExp,
listenChangeTime,
path
}
}