Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  1. // This file creates and syncs msto
  2. // msto is a recursive proxy that synchronizes itself between all meeting participants
  3. // you can get a clone of the object by typing jc(msto) into your dev console
  4. if (!window.glob_mx ){
  5. window.glob_mx={}
  6. glob_mx.prom = {}
  7. glob_mx.event_handlers = {}
  8. glob_mx.cb = {
  9. init_db:{}
  10. }
  11. glob_mx.hook_cb = {
  12. }
  13. glob_mx.qxi_cb = {}
  14. glob_mx.qxi_test = {
  15. }
  16. glob_mx.filmstrip_handlers = {}
  17. //glob_mx.filmstrip_handlers = glob_mx.filmstrip_handlers || {}
  18. }
  19. function match(mx,m,o){
  20. var k,v,k2,v2
  21. var r = 0
  22. // clog("@",mx,m,o)
  23. for ([k,v] of Object.entries(m || {})){
  24. v2 = o[k]
  25. // clog("M~",k,typeof(v),typeof(v2),v,v2)
  26. if (typeof(v) == "string" && typeof(v2) == "string") {
  27. r += !(v==v2)
  28. } else if (Array.isArray(v) && Array.isArray(v2)){
  29. r += !(isSubset_arr(v,v2))
  30. } else if (Array.isArray(v) && typeof(v2) == "string"){
  31. // r += !(isSubset_arr(v2,v))
  32. r += !v.includes(v2)
  33. // clog("!!!!!!!!!!!!!",v,v2,isSubset_arr(v2,v))
  34. } else if (Array.isArray(v2) && typeof(v) == "string"){
  35. r += !(v2.includes(v))
  36. }
  37. if (r){
  38. return !r
  39. }
  40. }
  41. return !r
  42. }
  43. function isSubset(subset,superset){
  44. for (var elem of subset) {
  45. if (!superset.includes(elem)) {
  46. return false;
  47. }
  48. }
  49. return true;
  50. }
  51. function isSubset_arr(subset,superset){
  52. for (var elem of subset) {
  53. if (Array.isArray(elem)){
  54. if (!new Set(elem).intersection(superset).size){
  55. return false
  56. }
  57. } else if (!superset.includes(elem)) {
  58. return false;
  59. }
  60. }
  61. return true;
  62. }
  63. function dispatch_events(e,key){
  64. var k,v
  65. e.parsed.etype ? 1 : e.parsed.etype = "null"
  66. var mflag =0
  67. clog("dispatch_events??",e,key)
  68. for ([k,v] of Object.entries(glob_mx.event_handlers || {}) ) {
  69. clog("dispatch_events:",k)
  70. if (v.m){
  71. mflag = match({},v.m,e.parsed)
  72. mflag ? v.fn(e) : 1
  73. }
  74. }
  75. }
  76. function run_cbs(key){
  77. var k,v
  78. clog("RUN_CB??",key,glob_mx.cb[key])
  79. for ([k,v] of Object.entries(glob_mx.cb[key]|| {}) ) {
  80. clog("RUN_CB:",k)
  81. v()
  82. }
  83. }
  84. function run_hook_cbs(key,o){
  85. var k,v
  86. // clog("RUN_HOOK_CB??",key,glob_mx.hook_cb[key])
  87. for ([k,v] of Object.entries(glob_mx.hook_cb[key]|| {}) ) {
  88. // clog("RUN_HOOK_CB:",k)
  89. v(o)
  90. }
  91. }
  92. function wait(ms) {
  93. return new Promise(r => setTimeout(r, ms));
  94. }
  95. function attr_info(n){
  96. var k,v
  97. var ret ={}
  98. // clog(".")
  99. for (k in n.attributes){
  100. // clog(k)
  101. }
  102. // clog("~")
  103. for (k of n.attributes){
  104. // for (k of n.attributes){
  105. // clog(k)
  106. }
  107. // clog("--")
  108. for ([k,v] of Object.entries(n.attributes)){
  109. // clog(k,v,v+"+")
  110. // clog("+",[k,v],v)
  111. ret[v.name]= v.value
  112. // clog(typeof(k),typeof(v))
  113. }
  114. return ret
  115. }
  116. // ai.from.split((a0,a1,a2,a3)=>{clog({a0,a1,a2,a3});return "z"})
  117. // tmsgx3({type:"db_sync_request"})
  118. function mhndlr_rld(that,m){
  119. try {
  120. window.mx=m
  121. var n = m.querySelector(`code`)
  122. if (!n){return}
  123. var parsed = JSON.parse(n.innerHTML)
  124. var ai = attr_info(m)
  125. window.ai=ai
  126. // clog("FROM",ai.from == glob_mx.all_jids[0])
  127. // var id = ai.from.split().slice(-1)[0]
  128. var id = ai.from.split("/").pop()
  129. clog("mhndlr_rld2",m,parsed,n,n.dataset)
  130. var o = parsed.payload
  131. switch (parsed.type){
  132. case "set_msg":
  133. pf._set_recv(o.path,o.key,o.val)
  134. break;
  135. case "event":
  136. clog("~event~",parsed)
  137. dispatch_events({parsed,ai,m,that})
  138. break;
  139. case "msg_test":
  140. clog("msg_test",parsed)
  141. break;
  142. case "db_sync_request":
  143. // tmsgx3({type:"db_sync_response",payload:pf.root})
  144. tmsgx3({type:"db_sync_response",payload:pf.root},{to:ai.from})
  145. clog("db_sync_request",parsed)
  146. break;
  147. case "db_sync_response":
  148. if (id == glob_mx.local_id){
  149. clog( "db_sync_response ...")
  150. break
  151. }
  152. if (glob_mx.prom.init_db_resolve){
  153. glob_mx.prom.init_db_resolve({aaa:"dsr",pl:parsed.payload})
  154. }
  155. clog("db_sync_response",ai.from == glob_mx.local_id,ai.from,parsed)
  156. break;
  157. }
  158. /*
  159. if (parsed.type == "set_msg"){
  160. var o = parsed.payload
  161. pf._set_recv(o.path,o.key,o.val)
  162. }
  163. if (parsed.type == "msg_test"){
  164. clog("msg_test",parsed)
  165. }
  166. */
  167. } catch (err) {
  168. clog("mhndlr err:",err)
  169. }
  170. return true
  171. }
  172. isProxy = Symbol("isProxy")
  173. tlu = {
  174. object:"",
  175. string:true,
  176. number:true,
  177. undefined:true,
  178. boolean:true,
  179. }
  180. function type_info(o){
  181. var t
  182. var flags = {
  183. leaf:false,
  184. deep_not_prx:false,
  185. prx:false,
  186. isObj:false,
  187. isArr:false,
  188. els:false,
  189. }
  190. t = typeof(o)
  191. flags.t=t
  192. if (!(o === null)){
  193. flags.isArr = Array.isArray(o)
  194. flags.isObj = Object.prototype == o.__proto__
  195. }
  196. if (tlu[t] === true || o === null){
  197. flags.leaf = true
  198. } else if (t == "object" && o.__prx){
  199. flags.prx = true
  200. } else if (t == "object" && (flags.isArr || flags.isObj)){
  201. flags.prx = false
  202. flags.deep_not_prx = true
  203. } else {
  204. clog("ELSE")
  205. flags.els = true
  206. }
  207. return flags
  208. clog(t,flags)
  209. }
  210. function deep_prop(o,p){
  211. try {
  212. var arr = jc(p)
  213. var ret = o
  214. while (arr.length){
  215. // clog("deep_prop",arr,ret)
  216. ret = ret[arr.shift()]
  217. }
  218. // clog("deep_prop ret",ret)
  219. return ret
  220. } catch(err){console.error("DEEP_PROP ERR:",err)}
  221. }
  222. delete Proxy_Factory
  223. {
  224. class Proxy_Factory {
  225. constructor(o,n="dflt"){
  226. this.db = o
  227. this.n = n
  228. this.hidden_props = ["add_proxy","_set","walker","walker_start","prxy","_sett","_sett2"]
  229. this._pub_cb =[]
  230. this.__prx = true
  231. this.SymPrx = Symbol("SymPrx")
  232. }
  233. init(o){
  234. // clog("BP",this,this.baseProp,this.__proto__.baseProp,window.baseProp)
  235. this.root = o
  236. }
  237. sync(o){
  238. this.root = jc(o.root)
  239. o._pub_cb.push(this._set_recv.bind(this))
  240. }
  241. get prxy(){
  242. return this
  243. }
  244. _set(o,k,v,prx,a0){
  245. this.obj[k]=prx
  246. }
  247. _sett(o,k,v,prx,a0){
  248. clog("_SETT",this,arguments)
  249. }
  250. _sett2(o,k,v,prx,a0){
  251. clog("_SETT2",this,arguments)
  252. }
  253. set_pub(obj, prop, val,receiver){
  254. // clog("qia_pub",obj, prop, val,receiver)
  255. // clog("qia_pub2",this.n,obj.__path_arr, prop, jx(val))
  256. this._set_pub(obj.__path_arr, prop, jx(val))
  257. }
  258. _set_pub(path,key,val){
  259. var k,v
  260. // /*
  261. tmsgx({
  262. "type":"set_msg",
  263. "payload":{path,key,val},
  264. },"code")
  265. // */
  266. for (v of this._pub_cb){
  267. v(path,key,val)
  268. }
  269. }
  270. _set_recv(path,prop,val){
  271. // return
  272. var p = path
  273. var nprop =deep_prop(this.root,p)
  274. var dpth = nprop.__dpth
  275. if (tlu[typeof(val)]){
  276. nprop._set(nprop,prop,val,val)
  277. } else {
  278. nprop._set(nprop,prop,val,new Proxy(val,this))
  279. nprop[prop].add_proxy(nprop,prop,val,dpth+1)
  280. }
  281. // var tf = {}
  282. // this.walker(nprop[prop],tf,dpth+2)
  283. this.walker(nprop[prop],{},dpth+2)
  284. }
  285. set(obj, prop, val,receiver){
  286. // clog("prx_db set ",this,obj, prop, val,receiver,val.__prx)
  287. if (obj[prop] === val){
  288. return Reflect.set(...arguments)
  289. }
  290. this.set_pub(obj, prop, val,receiver)
  291. this.event_proc("set")
  292. if ("__prx" == prop){
  293. this.__prx=val
  294. return this.__prx
  295. }
  296. if (typeof(val) === "object" && val != null && !(val.__prx)){
  297. var ret = Reflect.set(...arguments)
  298. this.set_obj(obj, prop, val,receiver)
  299. return ret
  300. }
  301. return Reflect.set(...arguments)
  302. }
  303. get(obj, prop,receiver){
  304. // clog("prx_db get ...",prop==isProxy,this,obj, prop,receiver)
  305. if (this.hidden_props.includes(prop)){
  306. switch (prop){
  307. case "add_proxy":
  308. return this.add_proxy.bind(this)
  309. break;
  310. case "prxy":
  311. return this
  312. case "_set":
  313. // clog("_SET")
  314. // return this._set.bind({this})
  315. return this._set.bind({that:this,obj, prop,receiver})
  316. case "_sett":
  317. return this._sett.bind({that:this,obj, prop,receiver})
  318. case "_sett2":
  319. return this._sett2.bind({that:this})
  320. case "walker_start":
  321. return this.walker_start
  322. case "walker":
  323. return this.walker
  324. break;
  325. }
  326. }
  327. if (isProxy == prop){ return true }
  328. if ("__prx" == prop){ return this.__prx }
  329. return Reflect.get(...arguments)
  330. }
  331. add_proxy(o,k,v,dpth){
  332. // clog("~add_proxy~",o,k,v,dpth)
  333. // clog("~add_proxy~",o.__prx,o,k,v,dpth,xpath)
  334. var xpath = o.__path
  335. var apath = o.__path_arr
  336. this.event_proc("add_proxy")
  337. if (!apath){
  338. apath=[]
  339. }
  340. if (!xpath){
  341. xpath="ROOT!"
  342. }
  343. Object.defineProperty(v,"__path_arr",Object.assign({value:apath.concat(k),},this.baseProp))
  344. Object.defineProperty(v,"__path",Object.assign({value:xpath+":"+k,},this.baseProp))
  345. Object.defineProperty(v,"__dpth",Object.assign({value:dpth,},this.baseProp))
  346. }
  347. set_obj(obj, prop, val,receiver){
  348. var dpth = obj.__dpth
  349. var tf = {}
  350. this.walker(receiver,tf,dpth)
  351. }
  352. walker(o,tfo,dpth=0){
  353. clog("qia WALK",this)
  354. if (dpth > 7){
  355. console.error("MAX DEPTH")
  356. return
  357. }
  358. var k,v
  359. var tf
  360. for ([k,v] of Object.entries(o)){
  361. tf = type_info(v)
  362. if (tf.deep_not_prx){
  363. o._set(o,k,v,new Proxy(v,this.prxy))
  364. o[k].add_proxy(o,k,v,dpth)
  365. this.walker(o[k],tf,dpth+1)
  366. }
  367. }
  368. }
  369. walker_start(o,dpth){
  370. var tf = type_info(o)
  371. o.add_proxy({},[],o,-1)
  372. this.walker(o,tf,0)
  373. }
  374. event_proc(e){}
  375. }
  376. window.Proxy_Factory = Proxy_Factory
  377. Proxy_Factory.prototype.baseProp={
  378. writable: true,
  379. // enumerable: true,
  380. enumerable: false,
  381. configurable: true,
  382. }
  383. }
  384. function arr_match(m,o){
  385. var k,v
  386. var r = 0
  387. for ([k,v] of Object.entries(m || {})){
  388. if (o[k] != v.valueOf()){
  389. r += 1
  390. return !r
  391. }
  392. // for ([k,v] in m){
  393. // case
  394. clog(k,v)
  395. }
  396. return !r
  397. }
  398. permissions_def = {
  399. participants:{
  400. m:["participants"],
  401. fn(set_scope,match){
  402. clog("FN....",match.fp,match.fp[1] == window.glob_mx.local_id)
  403. if (match.fp[1] != window.glob_mx.local_id)
  404. throw "permission err"
  405. return
  406. },
  407. }
  408. }
  409. //
  410. // msto.my_data.prxy.__proto__.__proto__.set.call(msto.my_data.prxy,msto.participants,"abc2",{})
  411. permissions_def__set = {
  412. participants:{
  413. m:["participants"],
  414. fn(set_scope,match){
  415. clog("FN....",match.fp,match.fp[1] == window.glob_mx.local_id)
  416. if (match.fp[1] != window.glob_mx.local_id)
  417. // throw "permission err"
  418. return
  419. },
  420. }
  421. }
  422. {
  423. class Proxy_Permissions extends Proxy_Factory {
  424. constructor(a,a1){
  425. super(...arguments)
  426. }
  427. set(obj, prop, val,receiver){
  428. clog("PRX_PERM",obj.__path_arr,prop)
  429. var k,v
  430. var r
  431. var matched
  432. var fp = obj.__path_arr.concat(prop)
  433. for ([k,v] of Object.entries(permissions_def)){
  434. matched = arr_match(v.m,fp)
  435. if (matched){
  436. r = v.fn({that:this,obj, prop, val,receiver},{fp,k,v}) || {}
  437. }
  438. // if (r.return)
  439. }
  440. // case
  441. // if (obj.__path_arr && obj.__path_arr.length){}
  442. super.set(obj, prop, val,receiver)
  443. }
  444. _set(){
  445. clog("Proxy_Permissions _set")
  446. super._set(...arguments)
  447. }
  448. }
  449. window.Proxy_Permissions = Proxy_Permissions
  450. }
  451. msto_z = {
  452. // private_local:{},
  453. // participant_local:{},
  454. conference:{},
  455. participants:{
  456. },
  457. }
  458. function pfnf(o){
  459. return function(resolve, reject){
  460. o.resolve=resolve
  461. o.reject=reject
  462. // clog(arguments)
  463. }
  464. }
  465. function init_db_cb(){
  466. }
  467. function init_sync_participant(){
  468. }
  469. function init_db(objx){
  470. var obj
  471. if (objx.participants){
  472. obj = objx
  473. } else {
  474. obj = objx.pl
  475. }
  476. // var obj = obj.pl
  477. clog("INIT DB...",objx,obj)
  478. pf = new Proxy_Permissions({},"pf")
  479. msto_prx = new Proxy(obj,pf)
  480. window.msto_prx0 =msto_prx
  481. // msto_prx = new Proxy(msto_z,pf)
  482. pf.init(msto_prx)
  483. msto_prx.walker_start(msto_prx)
  484. pf.root.participants[glob_mx.local_id] = {}
  485. window.msto= {
  486. participants:pf.root.participants,
  487. conference:pf.root.conference,
  488. my_data:pf.root.participants[glob_mx.local_id],
  489. private_local:{},
  490. }
  491. // var k,v
  492. clog("RUN_CB...")
  493. run_cbs("init_db")
  494. }
  495. function init_mu(persistent_mods){
  496. // .role == "moderator"
  497. clog(">>>>>>>>>>>>>>>>>>>.. RUN_CB")
  498. var participants = get_participants()
  499. clog(participants)
  500. var local = get_local(participants)
  501. if (window.glob_mx.local_id && persistent_mods && local.role=="moderator"){
  502. // if window.glob_mx.local_id
  503. clog("no RUN_CB")
  504. return
  505. }
  506. window.glob_mx.local_id = local.id
  507. var k,v
  508. window.glob_mx.all_ids = []
  509. window.glob_mx.all_jids = []
  510. for (v of participants){
  511. window.glob_mx.all_ids.push(v.id)
  512. window.glob_mx.all_jids.push(`nnnx@conference.jfidev.com/${v.id}`)
  513. }
  514. var rr = {}
  515. var prom1 = new Promise(pfnf(rr));
  516. prom1.then(init_db)
  517. // setTimeout(rr.reject,2000,"RESP DB Timeout")
  518. // setTimeout(rr.resolve,4000,"RESP DB Timeout")
  519. // setTimeout(rr.resolve,4000,msto_z)
  520. // setTimeout(rr.resolve,4000,{aaa:"timedout",pl:msto_z})
  521. setTimeout(rr.resolve,5000,{aaa:"timedout",pl:msto_z})
  522. if (participants.length > 1){
  523. glob_mx.prom.init_db_resolve = rr.resolve
  524. tmsgx3({type:"db_sync_request"})
  525. } else {
  526. // glob_mx.prom.init_db_resolve(msto_z)
  527. rr.resolve(msto_z)
  528. // init_db()
  529. }
  530. }
  531. function create_db(){
  532. }
  533. function isident(){
  534. return JSON.stringify(pf.root) == JSON.stringify(pf2.root)
  535. }
  536. function init_mu_runner(){
  537. if (window.glob_mx.conf_joined){
  538. init_mu(...arguments)
  539. }
  540. }
  541. function init_mx2(){
  542. clog("INITMX3")
  543. window.glob_mx.conf_joined =1
  544. init_mu_runner()
  545. // add_handler_m(mhndlr)
  546. }
  547. ifn_obj.init_conf_join.push(init_mx2)
  548. // init_mu_runner("auto")
  549. init_mu_runner("")