Browse Source

revert voicechat

Dele Olajide 3 tháng trước cách đây
mục cha
commit
2a7813ac26

+ 4 - 1
index.html

@@ -35,8 +35,11 @@
     <script src="packages/diagrams/abcjs.js"></script>
 	
     <link type="text/css" rel="stylesheet" media="screen" href="packages/voicechat/voicechat.css" />	
+    <script src="packages/voicechat/jquery-3.5.1.min.js"></script>	
+    <script src="packages/voicechat/hark.js"></script>	
+    <script src="packages/voicechat/lib-jitsi-meet.min.js"></script>	
     <script src="packages/voicechat/voicechat.js"></script>	
-
+	
     <link type="text/css" rel="stylesheet" media="screen" href="packages/adaptive-cards/adaptivecards.css" />	
     <script src="packages/adaptive-cards/adaptivecards.min.js"></script>
     <script src="packages/adaptive-cards/markdown-it.min.js"></script>

+ 0 - 9
packages/voicechat-old/voicechat.css

@@ -1,9 +0,0 @@
-.blink_me {
-  animation: blinker 1s linear infinite;
-}
-
-@keyframes blinker {
-  50% {
-    opacity: 0;
-  }
-}

+ 0 - 369
packages/voicechat-old/voicechat.js

@@ -1,369 +0,0 @@
-(function (root, factory) {
-    if (typeof define === 'function' && define.amd) {
-        define(["converse"], factory);
-    } else {
-        factory(converse);
-    }
-}(this, function (converse) {
-    let _converse, html, __, model, harker, connection, button, room, jitsiRoom, localTracks, remoteTracks = {}, recognition, recognitionActive, converseConn;
-
-	converse.plugins.add("voicechat", {
-		dependencies: [],
-
-		initialize: function () {
-            _converse = this._converse;
-            html = converse.env.html;
-            __ = _converse.__;
-
-			_converse.api.settings.extend({
-				voicechat: {
-					hosts: {
-						domain: 'beta.meet.jit.si',
-						muc: 'conference.beta.meet.jit.si'
-					},					
-					serviceUrl: 'https://beta.meet.jit.si/http-bind',
-					prefix: 'VC',					
-					transcribe: false,
-					transcribeLanguage: 'en-GB',
-					start:  __('Start Voice Chat'),
-					stop: __('Stop Voice Chat'),
-					started: __('has started speaking'),
-					stopped: __('has stopped speaking')					
-				}
-			});
-			
-			_converse.api.listen.on('connected', async function() {	
-				converseConn = await _converse.api.connection.get();
-			});				
-			
-            _converse.api.listen.on('getToolbarButtons', function(toolbar_el, buttons)
-            {
-				let style = "width:18px; height:18px; fill:var(--chat-color);";
-				if (toolbar_el.model.get("type") === "chatroom") {
-					style = "width:18px; height:18px; fill:var(--muc-color);";
-				}
-
-                buttons.push(html`
-                    <button class="btn plugin-voicechat" title="${_converse.api.settings.get('voicechat').start}" @click=${performAudio}/>
-						<svg style="${style}" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="volume-up" class="svg-inline--fa fa-volume-up fa-w-18" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M215.03 71.05L126.06 160H24c-13.26 0-24 10.74-24 24v144c0 13.25 10.74 24 24 24h102.06l88.97 88.95c15.03 15.03 40.97 4.47 40.97-16.97V88.02c0-21.46-25.96-31.98-40.97-16.97zm233.32-51.08c-11.17-7.33-26.18-4.24-33.51 6.95-7.34 11.17-4.22 26.18 6.95 33.51 66.27 43.49 105.82 116.6 105.82 195.58 0 78.98-39.55 152.09-105.82 195.58-11.17 7.32-14.29 22.34-6.95 33.5 7.04 10.71 21.93 14.56 33.51 6.95C528.27 439.58 576 351.33 576 256S528.27 72.43 448.35 19.97zM480 256c0-63.53-32.06-121.94-85.77-156.24-11.19-7.14-26.03-3.82-33.12 7.46s-3.78 26.21 7.41 33.36C408.27 165.97 432 209.11 432 256s-23.73 90.03-63.48 115.42c-11.19 7.14-14.5 22.07-7.41 33.36 6.51 10.36 21.12 15.14 33.12 7.46C447.94 377.94 480 319.54 480 256zm-141.77-76.87c-11.58-6.33-26.19-2.16-32.61 9.45-6.39 11.61-2.16 26.2 9.45 32.61C327.98 228.28 336 241.63 336 256c0 14.38-8.02 27.72-20.92 34.81-11.61 6.41-15.84 21-9.45 32.61 6.43 11.66 21.05 15.8 32.61 9.45 28.23-15.55 45.77-45 45.77-76.88s-17.54-61.32-45.78-76.86z"></path></svg>					
-                    </button>
-                `);
-
-                return buttons;
-            });			
-
-            _converse.api.listen.on('chatRoomViewInitialized', function (view)
-            {
-                console.debug("chatRoomViewInitialized", view);
-				stopVoiceChat();
-			});
-			
-            _converse.api.listen.on('chatBoxViewInitialized', function (view)
-            {
-                console.debug("chatBoxViewInitialized", view);
-				stopVoiceChat();
-			});
-			
-            _converse.api.listen.on('chatBoxClosed', function (model)
-            {
-                console.debug("chatBoxClosed", model);
-				stopVoiceChat();
-            });			
-			
-			console.log("voicechat plugin is ready");
-		}
-	});
-
-	function cyrb53(str, seed = 0) {
-		let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
-		for (let i = 0, ch; i < str.length; i++) {
-			ch = str.charCodeAt(i);
-			h1 = Math.imul(h1 ^ ch, 2654435761);
-			h2 = Math.imul(h2 ^ ch, 1597334677);
-		}
-		h1 = Math.imul(h1 ^ (h1>>>16), 2246822507) ^ Math.imul(h2 ^ (h2>>>13), 3266489909);
-		h2 = Math.imul(h2 ^ (h2>>>16), 2246822507) ^ Math.imul(h1 ^ (h1>>>13), 3266489909);
-		return 4294967296 * (2097151 & h2) + (h1>>>0);
-	}
-	
-	function performAudio(ev) {
-        ev.stopPropagation();
-        ev.preventDefault();
-		
-		if (converseConn) {
-			const toolbar_el = converse.env.utils.ancestor(ev.target, 'converse-chat-toolbar');	
-			model = toolbar_el.model;
-			const type = (model.get('type') == 'chatroom') ? 'groupchat' : 'chat';				
-			const target = model.get('jid');
-			const myself = Strophe.getBareJidFromJid(converseConn.jid);
-											
-			room = _converse.api.settings.get('voicechat').prefix.toLocaleLowerCase() + cyrb53((model.get('type') == 'chatroom') ? target : (myself < target ? myself + target : target + myself));
-			button = toolbar_el.querySelector('.plugin-voicechat');
-
-			console.debug("voicechat is clicked", model, room, button);
-
-			if (button.classList.contains('blink_me')) {
-				stopVoiceChat(model);						
-			} else {
-				startVoiceChat();						
-			}	
-		}			
-	}
-
-	function stopVoiceChat() {			
-		if (localTracks){
-			for (let i = 0; i < localTracks.length; i++) {
-				try {				
-					localTracks[i].dispose();
-				} catch (e) {};
-			}
-			localTracks = null;			
-		}
-		
-		if (jitsiRoom) {
-			jitsiRoom.leave();
-			jitsiRoom = null;
-		}
-		
-		if (connection) {
-			connection.disconnect();
-		}
-		let voiceChatAudio = document.getElementById('voicechat-audio');
-		if (voiceChatAudio) voiceChatAudio.innerHTML = "";	
-		
-		if (button && button.classList.contains('blink_me')) {
-			button.classList.remove('blink_me');
-			button.title = _converse.api.settings.get('voicechat').start;
-			model.sendMessage({body: '/me ' + _converse.api.settings.get('voicechat').stopped});			
-		}
-		
-		if (recognitionActive && recognition)
-		{
-			recognition.stop();
-			recognitionActive = false;
-		}
-		
-		if (harker) {
-			harker.stop();
-		}
-	}
-	
-	function startVoiceChat() {			
-		if (!localTracks) {		
-			JitsiMeetJS.init({disableAudioLevels: true});
-			
-			JitsiMeetJS.createLocalTracks({ devices: [ 'audio'] }).then(onLocalTracks).catch(error => {
-				console.error("startVoiceChat", error);
-			});			
-		} else {
-			goConnect();
-		}	
-	}
-	
-	function goConnect() {
-		const options = _converse.api.settings.get('voicechat');			
-		console.debug("goConnect", room, localTracks, options);		
-		connection = new JitsiMeetJS.JitsiConnection(null, null, options);
-		connection.addEventListener(JitsiMeetJS.events.connection.CONNECTION_ESTABLISHED,  onConnectionSuccess);
-		connection.addEventListener(JitsiMeetJS.events.connection.CONNECTION_FAILED,       onConnectionFailed);
-		connection.addEventListener(JitsiMeetJS.events.connection.CONNECTION_DISCONNECTED, onConnectionDisconnected);
-
-		JitsiMeetJS.mediaDevices.addEventListener(JitsiMeetJS.events.mediaDevices.DEVICE_LIST_CHANGED, onDeviceListChanged);
-		connection.connect();			
-	}
-	
-	function getLocalStream() {
-		return document.getElementById('localAudio0')?.srcObject;	
-	}	
-	
-	function onLocalTracks(tracks) {
-		localTracks = tracks;		
-		console.debug("onLocalTracks", room, localTracks);
-		
-		let voiceChatAudio = document.getElementById('voicechat-audio');
-		if (!voiceChatAudio) voiceChatAudio = newElement('div', 'voicechat-audio');
-		
-		for (let i = 0; i < localTracks.length; i++) 
-		{
-			if (localTracks[i].getType() === 'audio') {			
-				localTracks[i].addEventListener(JitsiMeetJS.events.track.TRACK_AUDIO_LEVEL_CHANGED,	audioLevel => console.debug(`Audio Level local: ${audioLevel}`));
-				localTracks[i].addEventListener(JitsiMeetJS.events.track.TRACK_MUTE_CHANGED, () => console.debug('local track muted'));
-				localTracks[i].addEventListener(JitsiMeetJS.events.track.LOCAL_TRACK_STOPPED,() => console.debug('local track stoped'));
-				localTracks[i].addEventListener(JitsiMeetJS.events.track.TRACK_AUDIO_OUTPUT_CHANGED, deviceId => {console.debug(`local track audio output device was changed to ${deviceId}`)	});
-
-				const localAudio = newElement('span', `local-audio-${i}`, `<audio autoplay='1' muted='true' id='localAudio${i}' />`);
-				voiceChatAudio.append(localAudio);
-				localTracks[i].attach($(`#localAudio${i}`)[0]);				
-			}
-			
-			if (i == 0) {
-
-				if (_converse.api.settings.get('voicechat').transcribe) {
-					setupSpeechRecognition();
-				}					
-
-				harker = hark(localTracks[i].stream, {interval: 100, history: 4 });
-
-				harker.on('speaking', () => {
-					
-					if (_converse.api.settings.get('voicechat').transcribe && model) {					
-						model.setChatState(_converse.COMPOSING);											
-					}
-				});
-
-				harker.on('stopped_speaking', () =>  {
-					
-					if (_converse.api.settings.get('voicechat').transcribe && model) {						
-						model.setChatState(_converse.PAUSED);												
-					}
-				});						
-			}
-		}
-		
-		goConnect();		
-	}
-
-	function onRemoteTrack(track) {
-		if (track.isLocal() || track.getType() === 'video') {
-			return;
-		}
-		let voiceChatAudio = document.getElementById('voicechat-audio');		
-		const participant = track.getParticipantId();
-
-		if (!remoteTracks[participant]) {
-			remoteTracks[participant] = [];
-		}
-		const idx = remoteTracks[participant].push(track);
-		console.debug("onRemoteTrack", room, remoteTracks);
-		
-		track.addEventListener(JitsiMeetJS.events.track.TRACK_AUDIO_LEVEL_CHANGED,	audioLevel => console.debug(`Audio Level remote: ${audioLevel}`));
-		track.addEventListener(JitsiMeetJS.events.track.TRACK_MUTE_CHANGED,	() => console.debug('remote track muted'));
-		track.addEventListener(JitsiMeetJS.events.track.LOCAL_TRACK_STOPPED, () => console.debug('remote track stoped'));
-		track.addEventListener(JitsiMeetJS.events.track.TRACK_AUDIO_OUTPUT_CHANGED,	deviceId =>	console.debug(`remote track audio output device was changed to ${deviceId}`));
-
-		const id = participant + track.getType() + idx;
-		const localAudio = newElement('span', `remote-audio-${participant}-${idx}`, `<audio autoplay='1' id='${participant}audio${idx}' />`);
-		voiceChatAudio.append(localAudio);		
-		track.attach($(`#${id}`)[0]);		
-	}
-	
-	function onDeviceListChanged(devices) {
-		console.info('onDeviceListChanged', devices);
-	}
-	
-	function onConnectionSuccess() {
-		console.debug("onConnectionSuccess", room);		
-		
-		jitsiRoom = connection.initJitsiConference(room, {});	
-		jitsiRoom.on(JitsiMeetJS.events.conference.TRACK_ADDED, onRemoteTrack);
-		jitsiRoom.on(JitsiMeetJS.events.conference.TRACK_REMOVED, track => {console.debug(`track removed!!!${track}`)	});
-		jitsiRoom.on(JitsiMeetJS.events.conference.CONFERENCE_JOINED, onConferenceJoined);
-		jitsiRoom.on(JitsiMeetJS.events.conference.USER_JOINED, id => {console.debug('user join'); remoteTracks[id] = []	});
-		jitsiRoom.on(JitsiMeetJS.events.conference.USER_LEFT, onUserLeft);
-		jitsiRoom.on(JitsiMeetJS.events.conference.TRACK_MUTE_CHANGED, track => {console.debug(`${track.getType()} - ${track.isMuted()}`)	});
-		jitsiRoom.on(JitsiMeetJS.events.conference.DISPLAY_NAME_CHANGED, (userID, displayName) => console.debug(`${userID} - ${displayName}`));
-		jitsiRoom.on(JitsiMeetJS.events.conference.TRACK_AUDIO_LEVEL_CHANGED, (userID, audioLevel) => console.debug(`${userID} - ${audioLevel}`));
-		jitsiRoom.on(JitsiMeetJS.events.conference.PHONE_NUMBER_CHANGED, () => console.debug(`${jitsiRoom.getPhoneNumber()} - ${jitsiRoom.getPhonePin()}`));
-		
-		jitsiRoom.join();
-	}
-
-	function onConnectionFailed() {
-		console.error('onConnectionFailed');
-	}
-
-	function onConnectionDisconnected() {
-		console.debug('onConnectionDisconnected!');
-		connection.removeEventListener(JitsiMeetJS.events.connection.CONNECTION_ESTABLISHED,  onConnectionSuccess);
-		connection.removeEventListener(JitsiMeetJS.events.connection.CONNECTION_FAILED,       onConnectionFailed);
-		connection.removeEventListener(JitsiMeetJS.events.connection.CONNECTION_DISCONNECTED, onConnectionDisconnected);
-	}
-
-	function onConferenceJoined() {
-		console.debug('onConferenceJoined!', jitsiRoom, localTracks);
-		
-		for (let i = 0; i < localTracks.length; i++) {
-			jitsiRoom.addTrack(localTracks[i]);
-		}
-		
-		if (button) {
-			button.classList.add('blink_me');	
-			button.title = _converse.api.settings.get('voicechat').stop;
-			model.sendMessage({body: '/me ' + _converse.api.settings.get('voicechat').started});			
-		}					
-	}
-
-	function onUserLeft(id) {
-		console.debug('onUserLeft', id);
-		
-		if (!remoteTracks[id]) {
-			return;
-		}
-		const tracks = remoteTracks[id];
-
-		for (let i = 0; i < tracks.length; i++) {
-			tracks[i].detach($(`#${id}${tracks[i].getType()}`));
-		}
-	}
-
-	function newElement(el, id, html, className) {
-		const ele = document.createElement(el);
-		if (id) ele.id = id;
-		if (html) ele.innerHTML = html;
-		if (className) ele.classList.add(className);
-		document.body.appendChild(ele);
-		return ele;
-	}
-	
-    function setupSpeechRecognition() {
-        console.debug("setupSpeechRecognition");
-
-        recognition = new webkitSpeechRecognition();
-        recognition.lang = _converse.api.settings.get('voicechat').transcribeLanguage;
-        recognition.continuous = true;
-        recognition.interimResults = false;
-
-        recognition.onresult = function(event)
-        {
-            console.debug("Speech recog event", event)
-
-            if (event.results[event.resultIndex].isFinal==true)
-            {
-                const transcript = event.results[event.resultIndex][0].transcript;
-                console.debug("Speech recog transcript", transcript);
-                if (model) model.sendMessage({'body': transcript});		
-				if (model) model.setChatState(_converse.ACTIVE);					
-			}
-        }
-
-        recognition.onspeechend  = function(event)
-        {
-            console.debug("Speech recog onspeechend", event);		
-        }
-
-        recognition.onstart = function(event)
-        {
-            console.debug("Speech to text started", event);
-            recognitionActive = true;			
-        }
-
-        recognition.onend = function(event)
-        {
-            console.debug("Speech to text ended", event);
-
-            if (recognitionActive)
-            {
-                console.debug("Speech to text restarted");
-                setTimeout(function() {recognition.start()}, 1000);
-            }
-        }
-
-        recognition.onerror = function(event)
-        {
-            console.debug("Speech to text error", event);
-        }
-
-        recognition.start();		
-    }	
-	
-}));

+ 0 - 0
packages/voicechat-old/callstats-ws.min.js → packages/voicechat/callstats-ws.min.js


+ 0 - 0
packages/voicechat-old/hark.js → packages/voicechat/hark.js


+ 0 - 0
packages/voicechat-old/jquery-3.5.1.min.js → packages/voicechat/jquery-3.5.1.min.js


+ 0 - 0
packages/voicechat-old/lib-jitsi-meet.min.js → packages/voicechat/lib-jitsi-meet.min.js


+ 0 - 0
packages/voicechat-old/lib-jitsi-meet.min.map → packages/voicechat/lib-jitsi-meet.min.map


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
packages/voicechat/ohun/_nuxt/0379545.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
packages/voicechat/ohun/_nuxt/27fa2ac.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
packages/voicechat/ohun/_nuxt/29a25cd.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
packages/voicechat/ohun/_nuxt/63409c8.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
packages/voicechat/ohun/_nuxt/768785d.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
packages/voicechat/ohun/_nuxt/7fa09b4.js


+ 0 - 50
packages/voicechat/ohun/_nuxt/LICENSES

@@ -1,50 +0,0 @@
-/*!
- * Vue.js v2.7.16
- * (c) 2014-2023 Evan You
- * Released under the MIT License.
- */
-
-/*!
- * cookie
- * Copyright(c) 2012-2014 Roman Shtylman
- * Copyright(c) 2015 Douglas Christopher Wilson
- * MIT Licensed
- */
-
-/*!
- * vuex v3.6.2
- * (c) 2021 Evan You
- * @license MIT
- */
-
-
-/*!
- * clipboard.js v2.0.11
- * https://clipboardjs.com/
- *
- * Licensed MIT © Zeno Rocha
- */
-
-/*!
- * vue-client-only v0.0.0-semantic-release
- * (c) 2021-present egoist <0x142857@gmail.com>
- * Released under the MIT License.
- */
-
-/*!
- * vue-i18n v8.28.2 
- * (c) 2022 kazuya kawaguchi
- * Released under the MIT License.
- */
-
-/*!
- * vue-no-ssr v1.1.1
- * (c) 2018-present egoist <0x142857@gmail.com>
- * Released under the MIT License.
- */
-
-/**
-  * vue-class-component v7.2.6
-  * (c) 2015-present Evan You
-  * @license MIT
-  */

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
packages/voicechat/ohun/_nuxt/af024c0.js


+ 0 - 969
packages/voicechat/ohun/_nuxt/bb6d73d.js

@@ -1,969 +0,0 @@
-(window.webpackJsonp = window.webpackJsonp || []).push([
-    [4], {
-        510: function(t, e, r) {
-            "use strict";
-            var n = r(2),
-                o = r(22),
-                c = r(23),
-                l = r(30),
-                d = r(17),
-                h = r(35),
-                f = r(5),
-                m = (r(10), r(15), r(41), r(13), r(19), r(14), r(4), r(68), r(16), r(62), r(59), r(1)),
-                v = r(44),
-                y = r(73),
-                k = r(239);
-
-            function _(t, e) {
-                var r = Object.keys(t);
-                if (Object.getOwnPropertySymbols) {
-                    var n = Object.getOwnPropertySymbols(t);
-                    e && (n = n.filter((function(e) {
-                        return Object.getOwnPropertyDescriptor(t, e).enumerable
-                    }))), r.push.apply(r, n)
-                }
-                return r
-            }
-
-            function O() {
-                try {
-                    var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], (function() {})))
-                } catch (t) {}
-                return (O = function() {
-                    return !!t
-                })()
-            }
-            var w = function(t, e, r, desc) {
-                    var n, o = arguments.length,
-                        c = o < 3 ? e : null === desc ? desc = Object.getOwnPropertyDescriptor(e, r) : desc;
-                    if ("object" === ("undefined" == typeof Reflect ? "undefined" : Object(f.a)(Reflect)) && "function" == typeof Reflect.decorate) c = Reflect.decorate(t, e, r, desc);
-                    else
-                        for (var i = t.length - 1; i >= 0; i--)(n = t[i]) && (c = (o < 3 ? n(c) : o > 3 ? n(e, r, c) : n(e, r)) || c);
-                    return o > 3 && c && Object.defineProperty(e, r, c), c
-                },
-                x = function(t) {
-                    function e() {
-                        return Object(o.a)(this, e), t = this, r = e, n = arguments, r = Object(d.a)(r), Object(l.a)(t, O() ? Reflect.construct(r, n || [], Object(d.a)(t).constructor) : r.apply(t, n));
-                        var t, r, n
-                    }
-                    return Object(h.a)(e, t), Object(c.a)(e, [{
-                        key: "title",
-                        get: function() {
-                            return ""
-                        }
-                    }, {
-                        key: "description",
-                        get: function() {
-                            return ""
-                        }
-                    }, {
-                        key: "appbar",
-                        get: function() {
-                            return {}
-                        }
-                    }, {
-                        key: "resetAppbar",
-                        value: function() {
-                            this.setAppbar({
-                                title: "",
-                                style: "",
-                                show: !0,
-                                back: !0,
-                                home: !1,
-                                dark: !0,
-                                color: "#111"
-                            })
-                        }
-                    }, {
-                        key: "setLang",
-                        value: function() {
-                            var t = "en",
-                                e = navigator.language;
-                            e.includes("zh") ? t = e.includes("zh-TW") || e.includes("zh-HK") ? "zhTW" : "zh" : e.includes("es") ? t = "es" : e.includes("ja") ? t = "ja" : e.includes("de") && (t = "de"), this.$i18n.locale = t, document.title = this.title
-                        }
-                    }, {
-                        key: "setPage",
-                        value: function() {
-                            this.setAppbar(function(t) {
-                                for (var e = 1; e < arguments.length; e++) {
-                                    var r = null != arguments[e] ? arguments[e] : {};
-                                    e % 2 ? _(Object(r), !0).forEach((function(e) {
-                                        Object(n.a)(t, e, r[e])
-                                    })) : Object.getOwnPropertyDescriptors ? Object.defineProperties(t, Object.getOwnPropertyDescriptors(r)) : _(Object(r)).forEach((function(e) {
-                                        Object.defineProperty(t, e, Object.getOwnPropertyDescriptor(r, e))
-                                    }))
-                                }
-                                return t
-                            }({
-                                title: this.title
-                            }, this.appbar)), setTimeout((function() {
-                                Object(k.b)()
-                            }), 50)
-                        }
-                    }, {
-                        key: "beforeDestroy",
-                        value: function() {
-                            this.resetAppbar()
-                        }
-                    }])
-                }(m.a);
-            w([Object(y.a)("app/SET_APPBAR")], x.prototype, "setAppbar", void 0), x = w([Object(v.a)({
-                head: function() {
-                    return {
-                        title: this.title,
-                        meta: [{
-                            hid: "theme-color",
-                            name: "theme-color",
-                            content: "#040C11"
-                        }]
-                    }
-                },
-                beforeRouteEnter: function(t, e, r) {
-                    r((function(t) {
-                        t.setLang(), t.setPage()
-                    }))
-                }
-            })], x), e.a = x
-        },
-        521: function(t, e, r) {
-            var content = r(585);
-            content.__esModule && (content = content.default), "string" == typeof content && (content = [
-                [t.i, content, ""]
-            ]), content.locals && (t.exports = content.locals);
-            (0, r(21).default)("015d88a7", content, !0, {
-                sourceMap: !1
-            })
-        },
-        522: function(t, e, r) {
-            var content = r(587);
-            content.__esModule && (content = content.default), "string" == typeof content && (content = [
-                [t.i, content, ""]
-            ]), content.locals && (t.exports = content.locals);
-            (0, r(21).default)("411f58bc", content, !0, {
-                sourceMap: !1
-            })
-        },
-        584: function(t, e, r) {
-            "use strict";
-            r(521)
-        },
-        585: function(t, e, r) {
-            var n = r(20)((function(i) {
-                return i[1]
-            }));
-            n.push([t.i, ".user-card[data-v-22a8cfb5]{background:rgba(0,0,0,.3);border-radius:20px;box-shadow:0 0 20px rgba(0,0,0,.3);overflow:hidden;position:relative;width:100%}.user-card .top[data-v-22a8cfb5]{justify-content:space-between;left:0;position:absolute;right:0;top:0}.user-card .top .nickname[data-v-22a8cfb5]{word-break:break-all}.user-card .canvas-wrapper[data-v-22a8cfb5]{height:100px}.user-card .canvas-wrapper .canvas[data-v-22a8cfb5]{border-radius:20px;height:100%;width:100%}", ""]), n.locals = {}, t.exports = n
-        },
-        586: function(t, e, r) {
-            "use strict";
-            r(522)
-        },
-        587: function(t, e, r) {
-            var n = r(20)((function(i) {
-                return i[1]
-            }));
-            n.push([t.i, ".mute-all-btn[data-v-7612d705]{bottom:0;box-shadow:0 0 20px hsla(0,0%,100%,.08);margin:0 16px 68px 0;position:absolute}.cards[data-v-7612d705]{display:flex;flex-direction:row;flex-wrap:wrap}.hint-box[data-v-7612d705]{background:linear-gradient(-15deg,hsla(0,0%,100%,.12),hsla(0,0%,100%,.1));border-radius:20px;color:hsla(0,0%,100%,.7)}.hint-box.empty-hint[data-v-7612d705]{background:linear-gradient(-15deg,#90f,#0057fa)!important}.hint-box.error-hint[data-v-7612d705]{background:linear-gradient(-15deg,#ec5700,#be1d00)!important}", ""]), n.locals = {}, t.exports = n
-        },
-        591: function(t, e, r) {
-            "use strict";
-            r.r(e);
-            var n = r(504),
-                o = r(227),
-                c = r(186),
-                l = r(589),
-                d = r(506),
-                h = r(225),
-                f = r(592),
-                m = (r(85), r(22)),
-                v = r(23),
-                y = r(30),
-                k = r(17),
-                _ = r(35),
-                O = r(5),
-                w = (r(33), r(41), r(61), r(45), r(158), r(36), r(13), r(4), r(68), r(62), r(82), r(59), r(44)),
-                x = r(73),
-                C = r(514),
-                j = r(510),
-                M = r(24),
-                P = (r(84), r(10), r(51), r(16), r(198)),
-                S = (r(25), r(52), {
-                    _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
-                    encode: function(input) {
-                        var t, e, r, n, o, c, l, output = "",
-                            i = 0;
-                        for (input = S._utf8_encode(input); i < input.length;) n = (t = input.charCodeAt(i++)) >> 2, o = (3 & t) << 4 | (e = input.charCodeAt(i++)) >> 4, c = (15 & e) << 2 | (r = input.charCodeAt(i++)) >> 6, l = 63 & r, isNaN(e) ? c = l = 64 : isNaN(r) && (l = 64), output = output + this._keyStr.charAt(n) + this._keyStr.charAt(o) + this._keyStr.charAt(c) + this._keyStr.charAt(l);
-                        return output
-                    },
-                    decode: function(input) {
-                        var t, e, r, n, o, c, output = "",
-                            i = 0;
-                        for (input = input.replace(/[^A-Za-z0-9+/=]/g, ""); i < input.length;) t = this._keyStr.indexOf(input.charAt(i++)) << 2 | (n = this._keyStr.indexOf(input.charAt(i++))) >> 4, e = (15 & n) << 4 | (o = this._keyStr.indexOf(input.charAt(i++))) >> 2, r = (3 & o) << 6 | (c = this._keyStr.indexOf(input.charAt(i++))), output += String.fromCharCode(t), 64 !== o && (output += String.fromCharCode(e)), 64 !== c && (output += String.fromCharCode(r));
-                        return output = S._utf8_decode(output)
-                    },
-                    _utf8_encode: function(t) {
-                        var e = "";
-                        t = t.replace(/\r\n/g, "\n");
-                        for (var r = 0; r < t.length; r++) {
-                            var n = t.charCodeAt(r);
-                            n < 128 ? e += String.fromCharCode(n) : n > 127 && n < 2048 ? (e += String.fromCharCode(n >> 6 | 192), e += String.fromCharCode(63 & n | 128)) : (e += String.fromCharCode(n >> 12 | 224), e += String.fromCharCode(n >> 6 & 63 | 128), e += String.fromCharCode(63 & n | 128))
-                        }
-                        return e
-                    },
-                    _utf8_decode: function(t) {
-                        var e, r, n, o = "",
-                            i = 0;
-                        for (e = r = 0; i < t.length;)(e = t.charCodeAt(i)) < 128 ? (o += String.fromCharCode(e), i++) : e > 191 && e < 224 ? (r = t.charCodeAt(i + 1), o += String.fromCharCode((31 & e) << 6 | 63 & r), i += 2) : (r = t.charCodeAt(i + 1), n = t.charCodeAt(i + 2), o += String.fromCharCode((15 & e) << 12 | (63 & r) << 6 | 63 & n), i += 3);
-                        return o
-                    }
-                }),
-                A = S,
-                R = {
-                    audio: !0,
-                    video: !1
-                },
-                N = {
-                    urls: "turn:35.235.85.40:443",
-                    username: "webrtc",
-                    credential: "turnpassword"
-                },
-                D = {
-                    iceServers: [],
-                    iceTransportPolicy: "relay",
-                    bundlePolicy: "max-bundle",
-                    rtcpMuxPolicy: "require",
-                    sdpSemantics: "unified-plan"
-                },
-                T = new(window.AudioContext || window.webkitAudioContext),
-                E = "",
-                $ = "",
-                U = "",
-                F = "",
-                I = "",
-                z = function(t, e, r, n, o, c) {},
-                B = function(t) {},
-                W = function(t) {},
-                J = function(t) {},
-                L = null,
-                H = !1;
-
-            function K(t, e, r, n, o, c, l) {
-                var d = r + ":" + A.encode(e);
-                F = encodeURIComponent(t), I = encodeURIComponent(d), $ = r, z = n, B = o, J = c, W = l, U = e, H = !0, X()
-            }
-
-            function V(t, e) {
-                return G.apply(this, arguments)
-            }
-
-            function G() {
-				
-				var urlParam = function (name)	{
-					var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href);
-					if (!results) { return undefined; }
-					return unescape(results[1] || undefined);
-				}
-				
-                return (G = Object(M.a)(regeneratorRuntime.mark((function t(e, r) {
-                    var n, o;
-                    return regeneratorRuntime.wrap((function(t) {
-                        for (;;) switch (t.prev = t.next) {
-                            case 0:
-                                return t.prev = 1, t.next = 2, fetch("https://" + urlParam("server"), {	// BAO
-                                    method: "POST",
-                                    mode: "cors",
-                                    cache: "no-cache",
-                                    credentials: "omit",
-                                    headers: {
-                                        "Content-Type": "application/json"
-                                    },
-                                    redirect: "follow",
-                                    referrerPolicy: "no-referrer",
-                                    body: JSON.stringify({
-                                        id: Object(P.b)(),
-                                        method: e,
-                                        params: r
-                                    })
-                                });
-                            case 2:
-                                return n = t.sent, t.abrupt("return", n.json());
-                            case 3:
-                                return t.prev = 3, o = t.catch(1), console.log("fetch error", e, r, o), t.next = 4, V(e, r);
-                            case 4:
-                                return t.abrupt("return", t.sent);
-                            case 5:
-                                return t.prev = 5, t.finish(5);
-                            case 6:
-                            case "end":
-                                return t.stop()
-                        }
-                    }), t, null, [
-                        [1, 3, 5, 6]
-                    ])
-                })))).apply(this, arguments)
-            }
-
-            function Z(t) {
-                return Q.apply(this, arguments)
-            }
-
-            function Q() {
-                return (Q = Object(M.a)(regeneratorRuntime.mark((function t(e) {
-                    var r, n;
-                    return regeneratorRuntime.wrap((function(t) {
-                        for (;;) switch (t.prev = t.next) {
-                            case 0:
-                                return t.next = 1, V("subscribe", [F, I, E]);
-                            case 1:
-                                if (!(r = t.sent).hasOwnProperty("error")) {
-                                    t.next = 2;
-                                    break
-                                }
-                                return console.log("try to reconnect", r.error.description), J && J(r.error).then((function() {
-                                    H && (console.log("reconnect in 0.5s"), setTimeout(Object(M.a)(regeneratorRuntime.mark((function t() {
-                                        return regeneratorRuntime.wrap((function(t) {
-                                            for (;;) switch (t.prev = t.next) {
-                                                case 0:
-                                                    return e.close(), t.next = 1, X();
-                                                case 1:
-                                                case "end":
-                                                    return t.stop()
-                                            }
-                                        }), t)
-                                    }))), 500))
-                                })), t.abrupt("return");
-                            case 2:
-                                if (!r.data || "offer" !== r.data.type) {
-                                    t.next = 6;
-                                    break
-                                }
-                                return console.log("subscribe offer", r.data), t.next = 3, e.setRemoteDescription(r.data);
-                            case 3:
-                                return t.next = 4, e.createAnswer();
-                            case 4:
-                                return n = t.sent, t.next = 5, e.setLocalDescription(n);
-                            case 5:
-                                return t.next = 6, V("answer", [F, I, E, JSON.stringify(n)]);
-                            case 6:
-                                setTimeout((function() {
-                                    Z(e)
-                                }), 3e3);
-                            case 7:
-                            case "end":
-                                return t.stop()
-                        }
-                    }), t)
-                })))).apply(this, arguments)
-            }
-
-            function X() {
-                return Y.apply(this, arguments)
-            }
-
-            function Y() {
-                return (Y = Object(M.a)(regeneratorRuntime.mark((function t() {
-                    var e, r, n, source, o, c, l, d, h, f, m;
-                    return regeneratorRuntime.wrap((function(t) {
-                        for (;;) switch (t.prev = t.next) {
-                            case 0:
-                                if (H) {
-                                    t.next = 1;
-                                    break
-                                }
-                                return t.abrupt("return");
-                            case 1:
-                                return t.prev = 1, t.next = 2, V("turn", [$]);
-                            case 2:
-                                e = t.sent, D.iceServers = e.data, t.next = 4;
-                                break;
-                            case 3:
-                                t.prev = 3, l = t.catch(1), console.log("failed to get server", l), D.iceServers = [N];
-                            case 4:
-                                return t.prev = 4, document.querySelectorAll(".peer").forEach((function(t) {
-                                    return t.remove()
-                                })), (L = new RTCPeerConnection(D)).createDataChannel("chat"), L.onicecandidate = function(t) {
-                                    var e = t.candidate;
-                                    V("trickle", [F, I, E, JSON.stringify(e)])
-                                }, L.ontrack = function(t) {
-                                    console.log("ontrack", t);
-                                    var e = t.streams[0],
-                                        r = decodeURIComponent(e.id),
-                                        n = r.split(":")[0],
-                                        o = r.split(":")[1];
-                                    try {
-                                        o = A.decode(o)
-                                    } catch (t) {
-                                        console.log("failed to decode name", o, t)
-                                    }
-                                    if (n !== $) {
-                                        t.track.onmute = function(t) {
-                                            if (B) {
-                                                var e = t.target.id;
-                                                console.log("onmute", e, t), B(e)
-                                            }
-                                        };
-                                        var c = T.createAnalyser();
-                                        if (c.fftSize = 256, c.minDecibels = -80, c.maxDecibels = -10, c.smoothingTimeConstant = .85, T.createMediaStreamSource(e).connect(c), z) {
-                                            var l = t.track.id;
-                                            z(L, e, c, l, n, o)
-                                        }
-                                    }
-                                }, t.prev = 5, t.next = 6, navigator.mediaDevices.getUserMedia(R);
-                            case 6:
-                                r = t.sent, t.next = 8;
-                                break;
-                            case 7:
-                                return t.prev = 7, d = t.catch(5), console.error(d), W && W(d), t.abrupt("return");
-                            case 8:
-                                return (n = T.createAnalyser()).fftSize = 256, n.minDecibels = -80, n.maxDecibels = -10, n.smoothingTimeConstant = .85, source = T.createMediaStreamSource(r), (o = T.createGain()).gain.value = .01, source.connect(n), n.connect(o), o.connect(T.destination), z && z(L, r, n, "me", $, U), T.resume(), r.getTracks().forEach((function(track) {
-                                    L.addTrack(track, r)
-                                })), h = L, t.next = 9, L.createOffer();
-                            case 9:
-                                return f = t.sent, t.next = 10, h.setLocalDescription.call(h, f);
-                            case 10:
-                                return t.next = 11, V("publish", [F, I, JSON.stringify(L.localDescription)]);
-                            case 11:
-                                if (c = t.sent, console.log(c), !c.data || "answer" !== c.data.sdp.type) {
-                                    t.next = 13;
-                                    break
-                                }
-                                return t.next = 12, L.setRemoteDescription(c.data.sdp);
-                            case 12:
-                                E = c.data.track, Z(L);
-                            case 13:
-                                t.next = 15;
-                                break;
-                            case 14:
-                                t.prev = 14, m = t.catch(4), W && W(m);
-                            case 15:
-                            case "end":
-                                return t.stop()
-                        }
-                    }), t, null, [
-                        [1, 3],
-                        [4, 14],
-                        [5, 7]
-                    ])
-                })))).apply(this, arguments)
-            }
-            var tt = {
-                onCopy: function(t) {
-                    t.$toast({
-                        message: t.$t("common.copy_succ_hint"),
-                        color: "info"
-                    })
-                },
-                onError: function(t) {}
-            };
-            r(542), r(547), r(548), r(550), r(558), r(560), r(561), r(562), r(564), r(565), r(566), r(567), r(568), r(569), r(570), r(571), r(573), r(574), r(575), r(576), r(577), r(578), r(579), r(580), r(581), r(582), r(583);
-
-            function et() {
-                try {
-                    var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], (function() {})))
-                } catch (t) {}
-                return (et = function() {
-                    return !!t
-                })()
-            }
-            var nt = function(t, e, r, desc) {
-                    var n, o = arguments.length,
-                        c = o < 3 ? e : null === desc ? desc = Object.getOwnPropertyDescriptor(e, r) : desc;
-                    if ("object" === ("undefined" == typeof Reflect ? "undefined" : Object(O.a)(Reflect)) && "function" == typeof Reflect.decorate) c = Reflect.decorate(t, e, r, desc);
-                    else
-                        for (var i = t.length - 1; i >= 0; i--)(n = t[i]) && (c = (o < 3 ? n(c) : o > 3 ? n(e, r, c) : n(e, r)) || c);
-                    return o > 3 && c && Object.defineProperty(e, r, c), c
-                },
-                at = function(t) {
-                    function e() {
-                        return Object(m.a)(this, e), t = this, r = e, n = arguments, r = Object(k.a)(r), Object(y.a)(t, et() ? Reflect.construct(r, n || [], Object(k.a)(t).constructor) : r.apply(t, n));
-                        var t, r, n
-                    }
-                    return Object(_.a)(e, t), Object(v.a)(e, [{
-                        key: "mounted",
-                        value: function() {
-                            var t = this;
-                            setTimeout((function() {
-                                "me" !== t.user.trackId && (t.$refs.audio.srcObject = t.user.stream);
-                                t.visualize(t.user.uid, t.user.analyser)
-                            }), 200)
-                        }
-                    }, {
-                        key: "editName",
-                        value: function() {
-                            this.$emit("edit-name", this.user)
-                        }
-                    }, {
-                        key: "handleMutable",
-                        value: function() {
-                            this.user.isMuted ? this.$emit("unmute", this.user) : this.$emit("mute", this.user)
-                        }
-                    }, {
-                        key: "visualize",
-                        value: function(t, e) {
-                            var canvas = this.$refs.canvas;
-                            canvas.width = canvas.width * window.devicePixelRatio, canvas.height = canvas.height * window.devicePixelRatio;
-                            var r = canvas.getContext("2d"),
-                                n = e.frequencyBinCount,
-                                o = new Float32Array(n),
-                                c = Object(P.a)(t),
-                                g = c[0],
-                                b = c[1];
-                            ! function t() {
-                                var c = canvas.width,
-                                    l = canvas.height;
-                                e.getFloatFrequencyData(o), r.fillStyle = "rgb(0, 0, 0)", r.fillRect(0, 0, c, l);
-                                for (var d = c / n * 3, h = 0, f = 0, i = 0; i < n; i++) {
-                                    h = 2 * (o[i] + 140);
-                                    var m = Math.floor(h + 64);
-                                    r.fillStyle = g % 3 == 0 ? "rgb(".concat(m, ",").concat(g, ",").concat(b, ")") : g % 3 == 1 ? "rgb(".concat(g, ",").concat(m, ",").concat(b, ")") : "rgb(".concat(g, ",").concat(b, ",").concat(m, ")"), (h = l / 7 + h / 256 * l * 6 / 7) < l / 7 && (h = l / 7), r.fillRect(f, l - h, d, h), f += d + 2
-                                }
-                                setTimeout((function() {
-                                    requestAnimationFrame(t)
-                                }), 50)
-                            }()
-                        }
-                    }])
-                }(w.d);
-            nt([Object(w.c)()], at.prototype, "user", void 0), nt([Object(w.c)()], at.prototype, "muted", void 0);
-            var ot = at = nt([w.a], at),
-                it = (r(584), r(57)),
-                ct = Object(it.a)(ot, (function() {
-                    var t = this,
-                        e = t._self._c;
-                    t._self._setupProxy;
-                    return t.user ? e("div", {
-                        staticClass: "user-card"
-                    }, [e("div", {
-                        staticClass: "top d-flex py-2 pl-4 pr-2"
-                    }, [e("div", {
-                        staticClass: "nickname font-weight-bold",
-                        on: {
-                            click: t.editName
-                        }
-                    }, [t._v("\n      " + t._s(t.user.nickname) + "\n    ")]), t._v(" "), e(n.a, {
-                        attrs: {
-                            icon: "",
-                            small: ""
-                        },
-                        on: {
-                            click: t.handleMutable
-                        }
-                    }, [e(h.a, {
-                        attrs: {
-                            color: this.user.isMuted ? "rgb(242, 72, 34)" : "#FFFFFF"
-                        }
-                    }, [t._v("\n        " + t._s(this.user.isMuted ? t.$icons.mdiMicrophoneOff : t.$icons.mdiMicrophone) + "\n      ")])], 1)], 1), t._v(" "), e("div", {
-                        staticClass: "canvas-wrapper"
-                    }, [e("canvas", {
-                        ref: "canvas",
-                        staticClass: "canvas"
-                    })]), t._v(" "), e("audio", {
-                        ref: "audio",
-                        attrs: {
-                            autoplay: ""
-                        }
-                    })]) : t._e()
-                }), [], !1, null, "22a8cfb5", null).exports;
-
-            function st() {
-                try {
-                    var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], (function() {})))
-                } catch (t) {}
-                return (st = function() {
-                    return !!t
-                })()
-            }
-            var ut = function(t, e, r, desc) {
-                    var n, o = arguments.length,
-                        c = o < 3 ? e : null === desc ? desc = Object.getOwnPropertyDescriptor(e, r) : desc;
-                    if ("object" === ("undefined" == typeof Reflect ? "undefined" : Object(O.a)(Reflect)) && "function" == typeof Reflect.decorate) c = Reflect.decorate(t, e, r, desc);
-                    else
-                        for (var i = t.length - 1; i >= 0; i--)(n = t[i]) && (c = (o < 3 ? n(c) : o > 3 ? n(e, r, c) : n(e, r)) || c);
-                    return o > 3 && c && Object.defineProperty(e, r, c), c
-                },
-                lt = {
-                    dictionaries: [C.a, C.c],
-                    separator: " ",
-                    length: 2
-                },
-                pt = function(t) {
-                    function e() {
-                        var t, r, n, o;
-                        return Object(m.a)(this, e), r = this, n = e, o = arguments, n = Object(k.a)(n), (t = Object(y.a)(r, st() ? Reflect.construct(n, o || [], Object(k.a)(r).constructor) : n.apply(r, o))).loading = !1, t.showNameDialog = !1, t.noMicPermission = !1, t.nickname = "", t.roomName = "", t.uid = "", t.participantMap = {}, t.participantTrackIdMap = {}, t.participants = [], t.streams = {}, t.pc = null, t.copyUtil = tt, t
-                    }
-                    return Object(_.a)(e, t), Object(v.a)(e, [{
-                        key: "isAllMuted",
-                        get: function() {
-                            for (var t = 0; t < this.participants.length; t++)
-                                if (!this.participants[t].isMuted) return !1;
-                            return !0
-                        }
-                    }, {
-                        key: "isWeChat",
-                        get: function() {
-                            return navigator.userAgent.toLowerCase().includes("micromessenger")
-                        }
-                    }, {
-                        key: "destination",
-                        get: function() {
-                            return window.location.href
-                        }
-                    }, {
-                        key: "validated",
-                        get: function() {
-                            return 0 !== this.nickname.trim().length
-                        }
-                    }, {
-                        key: "cardWidth",
-                        get: function() {
-                            var t = window.innerWidth;
-                            if (t < 460) {
-                                var e = Math.round((t - 24 - 40) / 2);
-                                return "".concat(e, "px")
-                            }
-                            return "200px"
-                        }
-                    }, {
-                        key: "isEmpty",
-                        get: function() {
-                            return 1 === this.participants.length
-                        }
-                    }, {
-                        key: "title",
-                        get: function() {
-                            return "#".concat(this.roomName)
-                        }
-                    }, {
-                        key: "genRandomChannelName",
-                        value: function() {
-                            var t = Object(C.d)(lt);
-                            this.nickname = t.slice(0, 1).toUpperCase() + t.slice(1)
-                        }
-                    }, {
-                        key: "mounted",
-                        value: function() {
-                            var t = this;
-                            setTimeout((function() {
-                                t.reload(), t.nickname && K(t.roomName, t.nickname, t.uid, t.onConnect, t.onDisconnect, t.onResume, t.onError)
-                            }), 100)
-                        }
-                    }, {
-                        key: "reload",
-                        value: function() {
-                            this.loading = !0;
-                            var t = this.$route.params.name;
-                            this.chat.rooms.hasOwnProperty(t) ? this.nickname = this.chat.rooms[t].nickname : this.showNameDialog = !0, this.uid = this.profile.uid || Object(P.b)(), this.setProfile({
-                                uid: this.uid
-                            }), this.roomName = location.hash.substring(1), this.setAppbar({	// BAO
-                                color: "rgba(0, 0, 0, 0.0)",
-                                home: !0,
-                                back: !1,
-                                title: "#".concat(this.roomName)
-                            }), this.loading = !1
-                        }
-                    }, {
-                        key: "join",
-                        value: function() {
-                            this.setNickname({
-                                room: this.roomName,
-                                nickname: this.nickname
-                            }), this.showNameDialog = !1, 0 === this.participants.length ? K(this.roomName, this.nickname, this.uid, this.onConnect, this.onDisconnect, this.onResume, this.onError) : window.location.reload()
-                        }
-                    }, {
-                        key: "onConnect",
-                        value: function(t, e, r, n, o, c) {
-                            this.pc = t, console.log(e, o, c), this.addParticipant(e, r, n, o, c), this.streams[o] = e, this.chat.mutes.hasOwnProperty(o) && this.muteOrUnmute(o, !0)
-                        }
-                    }, {
-                        key: "onDisconnect",
-                        value: function(t) {
-                            var e = this.removeParticipant(t);
-                            null !== e && delete this.streams[e.uid]
-                        }
-                    }, {
-                        key: "onError",
-                        value: function(t) {
-                            t && "NotAllowedError" === t.name ? (console.log("no permission"), this.noMicPermission = !0) : console.log(t)
-                        }
-                    }, {
-                        key: "onResume",
-                        value: function(t) {
-                            var e = this;
-                            return new Promise((function(r) {
-                                console.log("resume from connection", t), e.clearup(), r()
-                            }))
-                        }
-                    }, {
-                        key: "clearup",
-                        value: function() {
-                            console.log("clear up"), this.participants.splice(0, this.participants.length), this.participantTrackIdMap = {}, this.participantMap = {}, this.streams = {}
-                        }
-                    }, {
-                        key: "goHome",
-                        value: function() {
-                            L && L.close(), H = !1, console.log("stop: " + H), this.clearup()
-                        }
-                    }, {
-                        key: "test",
-                        value: function() {
-                            console.log(this.participantTrackIdMap), console.log(this.participantMap), console.log(this.participants)
-                        }
-                    }, {
-                        key: "findParticipant",
-                        value: function(t) {
-                            for (var e = 0; e < this.participants.length; e++)
-                                if (this.participants[e].uid === t) return {
-                                    user: this.participants[e],
-                                    index: e
-                                };
-                            return null
-                        }
-                    }, {
-                        key: "addParticipant",
-                        value: function(t, e, r, n, o) {
-                            var c = {
-                                stream: t,
-                                analyser: e,
-                                trackId: r,
-                                isMuted: !1,
-                                uid: n,
-                                nickname: o
-                            };
-                            this.participantMap.hasOwnProperty(n) || this.participants.push(c), console.log("addParticipant", n, o, r), this.participantMap[n] = c, this.participantTrackIdMap[r] = c
-                        }
-                    }, {
-                        key: "removeParticipant",
-                        value: function(t) {
-                            if (!this.participantTrackIdMap.hasOwnProperty(t)) return null;
-                            var e = this.participantTrackIdMap[t];
-                            if (e) {
-                                var r = this.findParticipant(e.uid);
-                                r && r.user && (console.log("removeParticipant", e, t), this.participants.splice(r.index, 1), delete this.participantMap[e.uid])
-                            }
-                            return delete this.participantTrackIdMap[t], e
-                        }
-                    }, {
-                        key: "editName",
-                        value: function(t) {
-                            t && this.uid === t.uid && (this.nickname = t.nickname, this.showNameDialog = !0)
-                        }
-                    }, {
-                        key: "muteAll",
-                        value: function() {
-                            for (var t = this.participants.map((function(t) {
-                                    return t.uid
-                                })), e = this.isAllMuted, r = 0; r < t.length; r++) this.muteOrUnmute(t[r], !e);
-                            e ? this.removeMutes(t) : this.addMutes(t)
-                        }
-                    }, {
-                        key: "muteUser",
-                        value: function(t) {
-                            this.muteOrUnmute(t.uid, !0), this.addMute(t.uid)
-                        }
-                    }, {
-                        key: "unmuteUser",
-                        value: function(t) {
-                            this.muteOrUnmute(t.uid, !1), this.removeMute(t.uid)
-                        }
-                    }, {
-                        key: "muteOrUnmute",
-                        value: function(t, e) {
-                            if (this.participantMap.hasOwnProperty(t)) {
-                                console.log("uid=".concat(t, ", mute=").concat(e));
-                                var r = this.findParticipant(t);
-                                r && r.user && (r.user.isMuted = e, this.participants.splice(r.index, 1, r.user), this.setStream(t, !e))
-                            }
-                        }
-                    }, {
-                        key: "setStream",
-                        value: function(t, e) {
-                            var r = this.streams[t];
-                            r && r.getTracks().length > 0 && (r.getTracks()[0].enabled = e)
-                        }
-                    }])
-                }(Object(w.b)(j.a));
-            ut([Object(x.b)((function(t) {
-                return t.app.profile
-            }))], pt.prototype, "profile", void 0), ut([Object(x.b)((function(t) {
-                return t.app.chat
-            }))], pt.prototype, "chat", void 0), ut([Object(x.a)("app/SET_NICKNAME")], pt.prototype, "setNickname", void 0), ut([Object(x.a)("app/SET_PROFILE")], pt.prototype, "setProfile", void 0), ut([Object(x.a)("app/SET_APPBAR")], pt.prototype, "setAppbar", void 0), ut([Object(x.a)("app/ADD_MUTE")], pt.prototype, "addMute", void 0), ut([Object(x.a)("app/REMOVE_MUTE")], pt.prototype, "removeMute", void 0), ut([Object(x.a)("app/ADD_MUTES")], pt.prototype, "addMutes", void 0), ut([Object(x.a)("app/REMOVE_MUTES")], pt.prototype, "removeMutes", void 0);
-            var ht = pt = ut([Object(w.a)({
-                    head: function() {
-                        return {
-                            title: this.title,
-                            meta: [{
-                                hid: "theme-color",
-                                name: "theme-color",
-                                content: "#040C11"
-                            }]
-                        }
-                    },
-                    components: {
-                        UserCard: ct
-                    }
-                })], pt),
-                ft = (r(586), Object(it.a)(ht, (function() {
-                    var t = this,
-                        e = this,
-                        r = e._self._c;
-                    e._self._setupProxy;
-                    return r("normal-page-layout", {
-                        on: {
-                            home: e.goHome
-                        }
-                    }, [r(l.a, {
-                        staticClass: "room-page"
-                    }, [r("f-loading", {
-                        attrs: {
-                            loading: e.loading,
-                            fullscreen: !0
-                        }
-                    }), e._v(" "), [e.isEmpty ? r("div", {
-                        staticClass: "hint-box empty-hint px-4 py-2 mx-2 mb-4"
-                    }, [r("h2", {
-                        staticClass: "body-1 font-weight-bold"
-                    }, [e._v(e._s(e.$t("room.empty_block_title")))]), e._v(" "), r("div", {
-                        staticClass: "body-2"
-                    }, [e._v("\n          " + e._s(e.$t("room.empty_block_text")) + "\n        ")]), e._v(" "), r(n.a, {
-                        directives: [{
-                            name: "clipboard",
-                            rawName: "v-clipboard:copy",
-                            value: e.destination,
-                            expression: "destination",
-                            arg: "copy"
-                        }, {
-                            name: "clipboard",
-                            rawName: "v-clipboard:success",
-                            value: function() {
-                                return e.copyUtil.onCopy(t)
-                            },
-                            expression: "() => copyUtil.onCopy(this)",
-                            arg: "success"
-                        }, {
-                            name: "clipboard",
-                            rawName: "v-clipboard:error",
-                            value: function() {
-                                return e.copyUtil.onError(t)
-                            },
-                            expression: "() => copyUtil.onError(this)",
-                            arg: "error"
-                        }],
-                        staticClass: "my-2",
-                        attrs: {
-                            small: "",
-                            outlined: ""
-                        }
-                    }, [e._v("\n          " + e._s(e.$t("common.copy_url")) + "\n        ")])], 1) : r("div", {
-                        staticClass: "hint-box caption px-4 py-2 mx-2 mb-4"
-                    }, [r(h.a, {
-                        attrs: {
-                            small: ""
-                        }
-                    }, [e._v(e._s(e.$icons.mdiHeadphones))]), e._v("\n        " + e._s(e.$t("room.earhub_block_text")) + "\n      ")], 1), e._v(" "), e.noMicPermission ? r("div", {
-                        staticClass: "hint-box error-hint px-4 py-2 mx-2 mb-4"
-                    }, [r("h2", {
-                        staticClass: "body-1 font-weight-bold"
-                    }, [e._v(e._s(e.$t("room.error_block_title")))]), e._v(" "), r("div", {
-                        staticClass: "body-2"
-                    }, [e._v("\n          " + e._s(e.$t("room.error_block_text")) + "\n        ")])]) : e._e(), e._v(" "), e.isWeChat ? r("div", {
-                        staticClass: "hint-box error-hint px-4 py-2 mx-2 mb-4"
-                    }, [r("h2", {
-                        staticClass: "body-1 font-weight-bold"
-                    }, [e._v(e._s(e.$t("room.wechat_error_block_title")))]), e._v(" "), r("div", {
-                        staticClass: "body-2"
-                    }, [e._v("\n          " + e._s(e.$t("room.wechat_error_block_text")) + "\n        ")])]) : e._e(), e._v(" "), r("div", {
-                        staticClass: "cards"
-                    }, e._l(e.participants, (function(t) {
-                        return r("div", {
-                            key: t.uid,
-                            staticClass: "user-card-wrapper ma-2",
-                            style: {
-                                width: e.cardWidth
-                            }
-                        }, [r("user-card", {
-                            attrs: {
-                                user: t
-                            },
-                            on: {
-                                mute: e.muteUser,
-                                unmute: e.unmuteUser,
-                                "edit-name": e.editName
-                            }
-                        })], 1)
-                    })), 0)]], 2), e._v(" "), r(d.a, {
-                        attrs: {
-                            "max-width": "290"
-                        },
-                        model: {
-                            value: e.showNameDialog,
-                            callback: function(t) {
-                                e.showNameDialog = t
-                            },
-                            expression: "showNameDialog"
-                        }
-                    }, [r(o.a, [r(c.c, {
-                        staticClass: "title-2"
-                    }, [e._v(e._s(e.$t("room.name_dialog_title")))]), e._v(" "), r(c.b, {
-                        staticClass: "mb-0"
-                    }, [r("div", {
-                        staticClass: "mb-4"
-                    }, [r(f.a, {
-                        attrs: {
-                            label: e.$t("room.name_dialog_placeholder"),
-                            "hide-details": !0
-                        },
-                        scopedSlots: e._u([{
-                            key: "append",
-                            fn: function() {
-                                return [r(n.a, {
-                                    attrs: {
-                                        icon: ""
-                                    },
-                                    on: {
-                                        click: e.genRandomChannelName
-                                    }
-                                }, [r(h.a, [e._v("\n                  " + e._s(e.$icons.mdiDice3) + "\n                ")])], 1)]
-                            },
-                            proxy: !0
-                        }]),
-                        model: {
-                            value: e.nickname,
-                            callback: function(t) {
-                                e.nickname = t
-                            },
-                            expression: "nickname"
-                        }
-                    })], 1)]), e._v(" "), r(c.a, {
-                        staticClass: "px-5 pb-5"
-                    }, [r(n.a, {
-                        attrs: {
-                            color: "primary",
-                            block: "",
-                            rounded: "",
-                            disabled: !e.validated
-                        },
-                        on: {
-                            click: e.join
-                        }
-                    }, [e._v("\n          " + e._s(e.$t("room.name_dialog_btn")) + "\n        ")])], 1)], 1)], 1), e._v(" "), r(n.a, {
-                        staticClass: "mute-all-btn",
-                        attrs: {
-                            color: "rgba(255, 255, 255, 0.2)",
-                            dark: "",
-                            small: "",
-                            absolute: "",
-                            bottom: "",
-                            right: "",
-                            fab: ""
-                        },
-                        on: {
-                            click: e.muteAll
-                        }
-                    }, [r(h.a, {
-                        attrs: {
-                            color: this.isAllMuted ? "rgb(242, 72, 34)" : "#FFFFFF"
-                        }
-                    }, [e._v("\n      " + e._s(this.isAllMuted ? e.$icons.mdiMicrophoneOff : e.$icons.mdiMicrophone) + "\n    ")])], 1)], 1)
-                }), [], !1, null, "7612d705", null));
-            e.default = ft.exports
-        }
-    }
-]);

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
packages/voicechat/ohun/_nuxt/c91b750.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
packages/voicechat/ohun/_nuxt/fa2e6c0.js


+ 0 - 10
packages/voicechat/ohun/_nuxt/manifest.73b6d069.json

@@ -1,10 +0,0 @@
-{
-  "name": "mornin",
-  "short_name": "mornin",
-  "description": "Mornin is an anonymous audio conferencing service",
-  "icons": [],
-  "start_url": "/?standalone=true",
-  "display": "standalone",
-  "background_color": "#ffffff",
-  "lang": "en"
-}

BIN
packages/voicechat/ohun/favicon.ico


BIN
packages/voicechat/ohun/favicon.png


+ 0 - 140
packages/voicechat/ohun/index.html

@@ -1,140 +0,0 @@
-<!doctype html>
-<html lang="en" data-n-head="%7B%22lang%22:%7B%221%22:%22en%22%7D%7D">
-  <head>
-    <meta data-n-head="1" charset="utf-8">
-    <meta data-n-head="1" name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
-    <meta data-n-head="1" data-hid="description" name="description" content="Mornin is an anonymous audio conferencing service">
-    <meta data-n-head="1" data-hid="mobile-web-app-capable" name="mobile-web-app-capable" content="yes">
-    <meta data-n-head="1" data-hid="theme-color" name="theme-color" content="#040C11">
-    <meta data-n-head="1" data-hid="apple-mobile-web-app-capable" name="apple-mobile-web-app-capable" content="yes">
-    <meta data-n-head="1" data-hid="application-name" name="application-name" content="Mornin">
-    <meta data-n-head="1" data-hid="apple-application-name" name="apple-application-name" content="Mornin">
-    <meta data-n-head="1" data-hid="apple-mobile-web-app-title" name="apple-mobile-web-app-title" content="Mornin">
-    <meta data-n-head="1" data-hid="og:title" name="og:title" content="Mornin">
-    <meta data-n-head="1" data-hid="og:site_name" name="og:site_name" content="Mornin">
-    <meta data-n-head="1" data-hid="charset" charset="utf-8">
-    <meta data-n-head="1" data-hid="author" name="author" content="Mornin">
-    <meta data-n-head="1" data-hid="og:type" name="og:type" property="og:type" content="website">
-    <meta data-n-head="1" data-hid="og:description" name="og:description" property="og:description" content="Mornin is an anonymous audio conferencing service">
-    <title>Mornin</title>
-    <link data-n-head="1" rel="icon" type="image/x-icon" href="/community-plugins/packages/voicechat/ohun/favicon.ico">
-    <link data-n-head="1" rel="apple-touch-icon" type="image/png" href="/community-plugins/packages/voicechat/ohun/favicon.png">
-    <link data-n-head="1" data-hid="shortcut-icon" rel="shortcut icon" href="/community-plugins/packages/voicechat/ohun/favicon.ico">
-    <link data-n-head="1" rel="manifest" href="/community-plugins/packages/voicechat/ohun/_nuxt/manifest.73b6d069.json" data-hid="manifest">
-  </head>
-  <body>
-    <div id="__nuxt">
-      <style>
-        #nuxt-loading {
-          background: #fff;
-          visibility: hidden;
-          opacity: 0;
-          position: absolute;
-          left: 0;
-          right: 0;
-          top: 0;
-          bottom: 0;
-          display: flex;
-          justify-content: center;
-          align-items: center;
-          flex-direction: column;
-          animation: nuxtLoadingIn 10s ease;
-          -webkit-animation: nuxtLoadingIn 10s ease;
-          animation-fill-mode: forwards;
-          overflow: hidden
-        }
-
-        @keyframes nuxtLoadingIn {
-          0% {
-            visibility: hidden;
-            opacity: 0
-          }
-
-          20% {
-            visibility: visible;
-            opacity: 0
-          }
-
-          100% {
-            visibility: visible;
-            opacity: 1
-          }
-        }
-
-        @-webkit-keyframes nuxtLoadingIn {
-          0% {
-            visibility: hidden;
-            opacity: 0
-          }
-
-          20% {
-            visibility: visible;
-            opacity: 0
-          }
-
-          100% {
-            visibility: visible;
-            opacity: 1
-          }
-        }
-
-        #nuxt-loading>div,
-        #nuxt-loading>div:after {
-          border-radius: 50%;
-          width: 5rem;
-          height: 5rem
-        }
-
-        #nuxt-loading>div {
-          font-size: 10px;
-          position: relative;
-          text-indent: -9999em;
-          border: .5rem solid #f5f5f5;
-          border-left: .5rem solid #fff;
-          -webkit-transform: translateZ(0);
-          -ms-transform: translateZ(0);
-          transform: translateZ(0);
-          -webkit-animation: nuxtLoading 1.1s infinite linear;
-          animation: nuxtLoading 1.1s infinite linear
-        }
-
-        #nuxt-loading.error>div {
-          border-left: .5rem solid #ff4500;
-          animation-duration: 5s
-        }
-
-        @-webkit-keyframes nuxtLoading {
-          0% {
-            -webkit-transform: rotate(0);
-            transform: rotate(0)
-          }
-
-          100% {
-            -webkit-transform: rotate(360deg);
-            transform: rotate(360deg)
-          }
-        }
-
-        @keyframes nuxtLoading {
-          0% {
-            -webkit-transform: rotate(0);
-            transform: rotate(0)
-          }
-
-          100% {
-            -webkit-transform: rotate(360deg);
-            transform: rotate(360deg)
-          }
-        }
-      </style>
-      <div id="nuxt-loading" aria-live="polite" role="status">
-        <div>Loading...</div>
-      </div>
-    </div>
-    <script src="./ohun.js"></script>
-    <script src="./_nuxt/c91b750.js"></script>
-    <script src="./_nuxt/29a25cd.js"></script>
-    <script src="./_nuxt/63409c8.js"></script>
-    <script src="./_nuxt/0379545.js"></script>
-  </body>
-</html>

+ 0 - 14
packages/voicechat/ohun/ohun.js

@@ -1,14 +0,0 @@
-window.addEventListener("error", (function() {
-  var e = document.getElementById("nuxt-loading");
-  e && (e.className += " error")
-}))
-		
-window.__NUXT__ = {
-	config: {
-	  _app: {
-		basePath: "/packages/voicechat/ohun/",
-		assetsPath: "/packages/voicechat/ohun/_nuxt/",
-		cdnURL: null
-	  }
-	}
-}

+ 0 - 114
packages/voicechat/ohun/sw.js

@@ -1,114 +0,0 @@
-const options = {"workboxURL":"https://cdn.jsdelivr.net/npm/workbox-cdn@5.1.4/workbox/workbox-sw.js","importScripts":[],"config":{"debug":false},"cacheOptions":{"cacheId":"mornin-prod","directoryIndex":"/","revision":"Is6ngRcTIG4h"},"clientsClaim":true,"skipWaiting":true,"cleanupOutdatedCaches":true,"offlineAnalytics":false,"preCaching":[{"revision":"Is6ngRcTIG4h","url":"/?standalone=true"}],"runtimeCaching":[{"urlPattern":"/_nuxt/","handler":"CacheFirst","method":"GET","strategyPlugins":[]},{"urlPattern":"/","handler":"NetworkFirst","method":"GET","strategyPlugins":[]}],"offlinePage":null,"pagesURLPattern":"/","offlineStrategy":"NetworkFirst"}
-
-importScripts(...[options.workboxURL, ...options.importScripts])
-
-initWorkbox(workbox, options)
-workboxExtensions(workbox, options)
-precacheAssets(workbox, options)
-cachingExtensions(workbox, options)
-runtimeCaching(workbox, options)
-offlinePage(workbox, options)
-routingExtensions(workbox, options)
-
-function getProp(obj, prop) {
-  return prop.split('.').reduce((p, c) => p[c], obj)
-}
-
-function initWorkbox(workbox, options) {
-  if (options.config) {
-    // Set workbox config
-    workbox.setConfig(options.config)
-  }
-
-  if (options.cacheNames) {
-    // Set workbox cache names
-    workbox.core.setCacheNameDetails(options.cacheNames)
-  }
-
-  if (options.clientsClaim) {
-    // Start controlling any existing clients as soon as it activates
-    workbox.core.clientsClaim()
-  }
-
-  if (options.skipWaiting) {
-    workbox.core.skipWaiting()
-  }
-
-  if (options.cleanupOutdatedCaches) {
-    workbox.precaching.cleanupOutdatedCaches()
-  }
-
-  if (options.offlineAnalytics) {
-    // Enable offline Google Analytics tracking
-    workbox.googleAnalytics.initialize()
-  }
-}
-
-function precacheAssets(workbox, options) {
-  if (options.preCaching.length) {
-    workbox.precaching.precacheAndRoute(options.preCaching, options.cacheOptions)
-  }
-}
-
-
-function runtimeCaching(workbox, options) {
-  const requestInterceptor = {
-    requestWillFetch({ request }) {
-      if (request.cache === 'only-if-cached' && request.mode === 'no-cors') {
-        return new Request(request.url, { ...request, cache: 'default', mode: 'no-cors' })
-      }
-      return request
-    },
-    fetchDidFail(ctx) {
-      ctx.error.message =
-        '[workbox] Network request for ' + ctx.request.url + ' threw an error: ' + ctx.error.message
-      console.error(ctx.error, 'Details:', ctx)
-    },
-    handlerDidError(ctx) {
-      ctx.error.message =
-        `[workbox] Network handler threw an error: ` + ctx.error.message
-      console.error(ctx.error, 'Details:', ctx)
-      return null
-    }
-  }
-
-  for (const entry of options.runtimeCaching) {
-    const urlPattern = new RegExp(entry.urlPattern)
-    const method = entry.method || 'GET'
-
-    const plugins = (entry.strategyPlugins || [])
-      .map(p => new (getProp(workbox, p.use))(...p.config))
-
-    plugins.unshift(requestInterceptor)
-
-    const strategyOptions = { ...entry.strategyOptions, plugins }
-
-    const strategy = new workbox.strategies[entry.handler](strategyOptions)
-
-    workbox.routing.registerRoute(urlPattern, strategy, method)
-  }
-}
-
-function offlinePage(workbox, options) {
-  if (options.offlinePage) {
-    // Register router handler for offlinePage
-    workbox.routing.registerRoute(new RegExp(options.pagesURLPattern), ({ request, event }) => {
-      const strategy = new workbox.strategies[options.offlineStrategy]
-      return strategy
-        .handle({ request, event })
-        .catch(() => caches.match(options.offlinePage))
-    })
-  }
-}
-
-function workboxExtensions(workbox, options) {
-  
-}
-
-function cachingExtensions(workbox, options) {
-  
-}
-
-function routingExtensions(workbox, options) {
-  
-}

+ 0 - 0
packages/voicechat-old/package.json → packages/voicechat/package.json


+ 0 - 0
packages/voicechat-old/readme.md → packages/voicechat/readme.md


+ 0 - 4
packages/voicechat/voicechat.css

@@ -1,7 +1,3 @@
-.conversejs .row > *, converse-bg .row > * {
-  flex-shrink: 1;
-}
-
 .blink_me {
   animation: blinker 1s linear infinite;
 }

+ 330 - 59
packages/voicechat/voicechat.js

@@ -5,94 +5,365 @@
         factory(converse);
     }
 }(this, function (converse) {
-    let _converse, html, __, converseConn, voicechatServer;
+    let _converse, html, __, model, harker, connection, button, room, jitsiRoom, localTracks, remoteTracks = {}, recognition, recognitionActive, converseConn;
 
 	converse.plugins.add("voicechat", {
 		dependencies: [],
 
 		initialize: function () {
-             _converse = this._converse;
+            _converse = this._converse;
             html = converse.env.html;
             __ = _converse.__;
-			
+
 			_converse.api.settings.extend({
-				voicechat_server: 'rpc.kraken.fm'
-			});			
+				voicechat: {
+					hosts: {
+						domain: 'beta.meet.jit.si',
+						muc: 'conference.beta.meet.jit.si'
+					},					
+					serviceUrl: 'https://beta.meet.jit.si/http-bind',
+					prefix: 'VC',					
+					transcribe: false,
+					transcribeLanguage: 'en-GB',
+					start:  __('Start Voice Chat'),
+					stop: __('Stop Voice Chat'),
+					started: __('has started speaking'),
+					stopped: __('has stopped speaking')					
+				}
+			});
+			
+			_converse.api.listen.on('connected', async function() {	
+				converseConn = await _converse.api.connection.get();
+			});				
 			
-            _converse.api.listen.on('getToolbarButtons', function(toolbar_el, buttons) {
-				voicechatServer = _converse.api.settings.get('voicechat_server');				
-                console.debug("getToolbarButtons", voicechatServer, toolbar_el.model);					
-				
+            _converse.api.listen.on('getToolbarButtons', function(toolbar_el, buttons)
+            {
+				let style = "width:18px; height:18px; fill:var(--chat-color);";
 				if (toolbar_el.model.get("type") === "chatroom") {
-					const voiceChatStart = __('Voice Chat');														
-					const color = "fill:var(--muc-color);";
-
-					buttons.push(html`
-						<button class="btn plugin-voicechat" title="${voiceChatStart}" @click=${performAudio}/>
-							<svg style="width:18px; height:18px; ${color}" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="volume-up" class="svg-inline--fa fa-volume-up fa-w-18" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M215.03 71.05L126.06 160H24c-13.26 0-24 10.74-24 24v144c0 13.25 10.74 24 24 24h102.06l88.97 88.95c15.03 15.03 40.97 4.47 40.97-16.97V88.02c0-21.46-25.96-31.98-40.97-16.97zm233.32-51.08c-11.17-7.33-26.18-4.24-33.51 6.95-7.34 11.17-4.22 26.18 6.95 33.51 66.27 43.49 105.82 116.6 105.82 195.58 0 78.98-39.55 152.09-105.82 195.58-11.17 7.32-14.29 22.34-6.95 33.5 7.04 10.71 21.93 14.56 33.51 6.95C528.27 439.58 576 351.33 576 256S528.27 72.43 448.35 19.97zM480 256c0-63.53-32.06-121.94-85.77-156.24-11.19-7.14-26.03-3.82-33.12 7.46s-3.78 26.21 7.41 33.36C408.27 165.97 432 209.11 432 256s-23.73 90.03-63.48 115.42c-11.19 7.14-14.5 22.07-7.41 33.36 6.51 10.36 21.12 15.14 33.12 7.46C447.94 377.94 480 319.54 480 256zm-141.77-76.87c-11.58-6.33-26.19-2.16-32.61 9.45-6.39 11.61-2.16 26.2 9.45 32.61C327.98 228.28 336 241.63 336 256c0 14.38-8.02 27.72-20.92 34.81-11.61 6.41-15.84 21-9.45 32.61 6.43 11.66 21.05 15.8 32.61 9.45 28.23-15.55 45.77-45 45.77-76.88s-17.54-61.32-45.78-76.86z"></path></svg>					
-						</button>
-					`);
+					style = "width:18px; height:18px; fill:var(--muc-color);";
 				}
-				
+
+                buttons.push(html`
+                    <button class="btn plugin-voicechat" title="${_converse.api.settings.get('voicechat').start}" @click=${performAudio}/>
+						<svg style="${style}" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="volume-up" class="svg-inline--fa fa-volume-up fa-w-18" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M215.03 71.05L126.06 160H24c-13.26 0-24 10.74-24 24v144c0 13.25 10.74 24 24 24h102.06l88.97 88.95c15.03 15.03 40.97 4.47 40.97-16.97V88.02c0-21.46-25.96-31.98-40.97-16.97zm233.32-51.08c-11.17-7.33-26.18-4.24-33.51 6.95-7.34 11.17-4.22 26.18 6.95 33.51 66.27 43.49 105.82 116.6 105.82 195.58 0 78.98-39.55 152.09-105.82 195.58-11.17 7.32-14.29 22.34-6.95 33.5 7.04 10.71 21.93 14.56 33.51 6.95C528.27 439.58 576 351.33 576 256S528.27 72.43 448.35 19.97zM480 256c0-63.53-32.06-121.94-85.77-156.24-11.19-7.14-26.03-3.82-33.12 7.46s-3.78 26.21 7.41 33.36C408.27 165.97 432 209.11 432 256s-23.73 90.03-63.48 115.42c-11.19 7.14-14.5 22.07-7.41 33.36 6.51 10.36 21.12 15.14 33.12 7.46C447.94 377.94 480 319.54 480 256zm-141.77-76.87c-11.58-6.33-26.19-2.16-32.61 9.45-6.39 11.61-2.16 26.2 9.45 32.61C327.98 228.28 336 241.63 336 256c0 14.38-8.02 27.72-20.92 34.81-11.61 6.41-15.84 21-9.45 32.61 6.43 11.66 21.05 15.8 32.61 9.45 28.23-15.55 45.77-45 45.77-76.88s-17.54-61.32-45.78-76.86z"></path></svg>					
+                    </button>
+                `);
+
                 return buttons;
-            });	
+            });			
 
-			_converse.api.listen.on('connected', async function() {
-				converseConn = await _converse.api.connection.get();					
-			});				
+            _converse.api.listen.on('chatRoomViewInitialized', function (view)
+            {
+                console.debug("chatRoomViewInitialized", view);
+				stopVoiceChat();
+			});
+			
+            _converse.api.listen.on('chatBoxViewInitialized', function (view)
+            {
+                console.debug("chatBoxViewInitialized", view);
+				stopVoiceChat();
+			});
+			
+            _converse.api.listen.on('chatBoxClosed', function (model)
+            {
+                console.debug("chatBoxClosed", model);
+				stopVoiceChat();
+            });			
 			
 			console.log("voicechat plugin is ready");
 		}
-	});	
+	});
+
+	function cyrb53(str, seed = 0) {
+		let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
+		for (let i = 0, ch; i < str.length; i++) {
+			ch = str.charCodeAt(i);
+			h1 = Math.imul(h1 ^ ch, 2654435761);
+			h2 = Math.imul(h2 ^ ch, 1597334677);
+		}
+		h1 = Math.imul(h1 ^ (h1>>>16), 2246822507) ^ Math.imul(h2 ^ (h2>>>13), 3266489909);
+		h2 = Math.imul(h2 ^ (h2>>>16), 2246822507) ^ Math.imul(h1 ^ (h1>>>13), 3266489909);
+		return 4294967296 * (2097151 & h2) + (h1>>>0);
+	}
 	
-    function performAudio(ev) {
+	function performAudio(ev) {
         ev.stopPropagation();
         ev.preventDefault();
+		
+		if (converseConn) {
+			const toolbar_el = converse.env.utils.ancestor(ev.target, 'converse-chat-toolbar');	
+			model = toolbar_el.model;
+			const type = (model.get('type') == 'chatroom') ? 'groupchat' : 'chat';				
+			const target = model.get('jid');
+			const myself = Strophe.getBareJidFromJid(converseConn.jid);
+											
+			room = _converse.api.settings.get('voicechat').prefix.toLocaleLowerCase() + cyrb53((model.get('type') == 'chatroom') ? target : (myself < target ? myself + target : target + myself));
+			button = toolbar_el.querySelector('.plugin-voicechat');
+
+			console.debug("voicechat is clicked", model, room, button);
+
+			if (button.classList.contains('blink_me')) {
+				stopVoiceChat(model);						
+			} else {
+				startVoiceChat();						
+			}	
+		}			
+	}
+
+	function stopVoiceChat() {			
+		if (localTracks){
+			for (let i = 0; i < localTracks.length; i++) {
+				try {				
+					localTracks[i].dispose();
+				} catch (e) {};
+			}
+			localTracks = null;			
+		}
+		
+		if (jitsiRoom) {
+			jitsiRoom.leave();
+			jitsiRoom = null;
+		}
+		
+		if (connection) {
+			connection.disconnect();
+		}
+		let voiceChatAudio = document.getElementById('voicechat-audio');
+		if (voiceChatAudio) voiceChatAudio.innerHTML = "";	
+		
+		if (button && button.classList.contains('blink_me')) {
+			button.classList.remove('blink_me');
+			button.title = _converse.api.settings.get('voicechat').start;
+			model.sendMessage({body: '/me ' + _converse.api.settings.get('voicechat').stopped});			
+		}
+		
+		if (recognitionActive && recognition)
+		{
+			recognition.stop();
+			recognitionActive = false;
+		}
+		
+		if (harker) {
+			harker.stop();
+		}
+	}
 	
-		const toolbar_el = converse.env.utils.ancestor(ev.target, 'converse-chat-toolbar');
-		const chatview = _converse.chatboxviews.get(toolbar_el.model.get('jid'));		
-		console.debug("performAudio", chatview, toolbar_el.model);
+	function startVoiceChat() {			
+		if (!localTracks) {		
+			JitsiMeetJS.init({disableAudioLevels: true});
+			
+			JitsiMeetJS.createLocalTracks({ devices: [ 'audio'] }).then(onLocalTracks).catch(error => {
+				console.error("startVoiceChat", error);
+			});			
+		} else {
+			goConnect();
+		}	
+	}
+	
+	function goConnect() {
+		const options = _converse.api.settings.get('voicechat');			
+		console.debug("goConnect", room, localTracks, options);		
+		connection = new JitsiMeetJS.JitsiConnection(null, null, options);
+		connection.addEventListener(JitsiMeetJS.events.connection.CONNECTION_ESTABLISHED,  onConnectionSuccess);
+		connection.addEventListener(JitsiMeetJS.events.connection.CONNECTION_FAILED,       onConnectionFailed);
+		connection.addEventListener(JitsiMeetJS.events.connection.CONNECTION_DISCONNECTED, onConnectionDisconnected);
+
+		JitsiMeetJS.mediaDevices.addEventListener(JitsiMeetJS.events.mediaDevices.DEVICE_LIST_CHANGED, onDeviceListChanged);
+		connection.connect();			
+	}
+	
+	function getLocalStream() {
+		return document.getElementById('localAudio0')?.srcObject;	
+	}	
+	
+	function onLocalTracks(tracks) {
+		localTracks = tracks;		
+		console.debug("onLocalTracks", room, localTracks);
+		
+		let voiceChatAudio = document.getElementById('voicechat-audio');
+		if (!voiceChatAudio) voiceChatAudio = newElement('div', 'voicechat-audio');
 		
-		const jid = toolbar_el.model.get("jid");
-		const id = toolbar_el.model.get("box_id");
-		const occupants = chatview.querySelector('.occupants');	
+		for (let i = 0; i < localTracks.length; i++) 
+		{
+			if (localTracks[i].getType() === 'audio') {			
+				localTracks[i].addEventListener(JitsiMeetJS.events.track.TRACK_AUDIO_LEVEL_CHANGED,	audioLevel => console.debug(`Audio Level local: ${audioLevel}`));
+				localTracks[i].addEventListener(JitsiMeetJS.events.track.TRACK_MUTE_CHANGED, () => console.debug('local track muted'));
+				localTracks[i].addEventListener(JitsiMeetJS.events.track.LOCAL_TRACK_STOPPED,() => console.debug('local track stoped'));
+				localTracks[i].addEventListener(JitsiMeetJS.events.track.TRACK_AUDIO_OUTPUT_CHANGED, deviceId => {console.debug(`local track audio output device was changed to ${deviceId}`)	});
 
-		console.debug("performAudio", jid, id, occupants, chatview);	
+				const localAudio = newElement('span', `local-audio-${i}`, `<audio autoplay='1' muted='true' id='localAudio${i}' />`);
+				voiceChatAudio.append(localAudio);
+				localTracks[i].attach($(`#localAudio${i}`)[0]);				
+			}
+			
+			if (i == 0) {
+
+				if (_converse.api.settings.get('voicechat').transcribe) {
+					setupSpeechRecognition();
+				}					
+
+				harker = hark(localTracks[i].stream, {interval: 100, history: 4 });
 
-		const button = toolbar_el.querySelector('.plugin-voicechat');
-        const chatroom_body = chatview.querySelector('.chatroom-body');
-        let info_area = chatview.querySelector('.occupants-voice-chat');
+				harker.on('speaking', () => {
+					
+					if (_converse.api.settings.get('voicechat').transcribe && model) {					
+						model.setChatState(_converse.COMPOSING);											
+					}
+				});
 
-		console.debug("toggleInfoBar", chatview, jid, id);
+				harker.on('stopped_speaking', () =>  {
+					
+					if (_converse.api.settings.get('voicechat').transcribe && model) {						
+						model.setChatState(_converse.PAUSED);												
+					}
+				});						
+			}
+		}
 		
-        if (!info_area)
-        {
-            info_area = document.createElement("div");
-            info_area.classList.add('occupants-voice-chat'); // col-xs-12 col-md-4 col-xl-2
-			info_area.style.display = "none";				
-			info_area.style.width = "500px";			
-            info_area.classList.add('col-xs-12');
-            info_area.classList.add('col-md-4');
-            info_area.classList.add('col-xl-2');			
-            chatroom_body.appendChild(info_area);
-        }
+		goConnect();		
+	}
 
-		if (info_area.style.display == "none") {
-			chatview.model.save({'hidden_occupants': true});			
-			const style = "width:100%; height:100%; border:none; margin:0; padding:0; overflow:hidden;";
-			console.debug("performAudio iframe", voicechatServer, jid);
-			info_area.innerHTML = '<iframe allow="geolocation; microphone; camera" style="' + style + '" src="/community-plugins/packages/voicechat/ohun/index.html?server=' + voicechatServer + '#converse_' + jid.split("@")[0] + '"></iframe>';
-			info_area.style.display = "";	
-			button.classList.add('blink_me');		
+	function onRemoteTrack(track) {
+		if (track.isLocal() || track.getType() === 'video') {
+			return;
+		}
+		let voiceChatAudio = document.getElementById('voicechat-audio');		
+		const participant = track.getParticipantId();
 
-		} else {
-			chatview.model.save({'hidden_occupants': false});
-			info_area.innerHTML = "";			
-			info_area.style.display = "none";
-			button.classList.remove('blink_me');
+		if (!remoteTracks[participant]) {
+			remoteTracks[participant] = [];
 		}
+		const idx = remoteTracks[participant].push(track);
+		console.debug("onRemoteTrack", room, remoteTracks);
 		
-        chatview.scrollDown();
+		track.addEventListener(JitsiMeetJS.events.track.TRACK_AUDIO_LEVEL_CHANGED,	audioLevel => console.debug(`Audio Level remote: ${audioLevel}`));
+		track.addEventListener(JitsiMeetJS.events.track.TRACK_MUTE_CHANGED,	() => console.debug('remote track muted'));
+		track.addEventListener(JitsiMeetJS.events.track.LOCAL_TRACK_STOPPED, () => console.debug('remote track stoped'));
+		track.addEventListener(JitsiMeetJS.events.track.TRACK_AUDIO_OUTPUT_CHANGED,	deviceId =>	console.debug(`remote track audio output device was changed to ${deviceId}`));
+
+		const id = participant + track.getType() + idx;
+		const localAudio = newElement('span', `remote-audio-${participant}-${idx}`, `<audio autoplay='1' id='${participant}audio${idx}' />`);
+		voiceChatAudio.append(localAudio);		
+		track.attach($(`#${id}`)[0]);		
+	}
+	
+	function onDeviceListChanged(devices) {
+		console.info('onDeviceListChanged', devices);
+	}
+	
+	function onConnectionSuccess() {
+		console.debug("onConnectionSuccess", room);		
+		
+		jitsiRoom = connection.initJitsiConference(room, {});	
+		jitsiRoom.on(JitsiMeetJS.events.conference.TRACK_ADDED, onRemoteTrack);
+		jitsiRoom.on(JitsiMeetJS.events.conference.TRACK_REMOVED, track => {console.debug(`track removed!!!${track}`)	});
+		jitsiRoom.on(JitsiMeetJS.events.conference.CONFERENCE_JOINED, onConferenceJoined);
+		jitsiRoom.on(JitsiMeetJS.events.conference.USER_JOINED, id => {console.debug('user join'); remoteTracks[id] = []	});
+		jitsiRoom.on(JitsiMeetJS.events.conference.USER_LEFT, onUserLeft);
+		jitsiRoom.on(JitsiMeetJS.events.conference.TRACK_MUTE_CHANGED, track => {console.debug(`${track.getType()} - ${track.isMuted()}`)	});
+		jitsiRoom.on(JitsiMeetJS.events.conference.DISPLAY_NAME_CHANGED, (userID, displayName) => console.debug(`${userID} - ${displayName}`));
+		jitsiRoom.on(JitsiMeetJS.events.conference.TRACK_AUDIO_LEVEL_CHANGED, (userID, audioLevel) => console.debug(`${userID} - ${audioLevel}`));
+		jitsiRoom.on(JitsiMeetJS.events.conference.PHONE_NUMBER_CHANGED, () => console.debug(`${jitsiRoom.getPhoneNumber()} - ${jitsiRoom.getPhonePin()}`));
+		
+		jitsiRoom.join();
+	}
+
+	function onConnectionFailed() {
+		console.error('onConnectionFailed');
+	}
+
+	function onConnectionDisconnected() {
+		console.debug('onConnectionDisconnected!');
+		connection.removeEventListener(JitsiMeetJS.events.connection.CONNECTION_ESTABLISHED,  onConnectionSuccess);
+		connection.removeEventListener(JitsiMeetJS.events.connection.CONNECTION_FAILED,       onConnectionFailed);
+		connection.removeEventListener(JitsiMeetJS.events.connection.CONNECTION_DISCONNECTED, onConnectionDisconnected);
+	}
+
+	function onConferenceJoined() {
+		console.debug('onConferenceJoined!', jitsiRoom, localTracks);
+		
+		for (let i = 0; i < localTracks.length; i++) {
+			jitsiRoom.addTrack(localTracks[i]);
+		}
+		
+		if (button) {
+			button.classList.add('blink_me');	
+			button.title = _converse.api.settings.get('voicechat').stop;
+			model.sendMessage({body: '/me ' + _converse.api.settings.get('voicechat').started});			
+		}					
+	}
+
+	function onUserLeft(id) {
+		console.debug('onUserLeft', id);
+		
+		if (!remoteTracks[id]) {
+			return;
+		}
+		const tracks = remoteTracks[id];
+
+		for (let i = 0; i < tracks.length; i++) {
+			tracks[i].detach($(`#${id}${tracks[i].getType()}`));
+		}
+	}
+
+	function newElement(el, id, html, className) {
+		const ele = document.createElement(el);
+		if (id) ele.id = id;
+		if (html) ele.innerHTML = html;
+		if (className) ele.classList.add(className);
+		document.body.appendChild(ele);
+		return ele;
+	}
+	
+    function setupSpeechRecognition() {
+        console.debug("setupSpeechRecognition");
+
+        recognition = new webkitSpeechRecognition();
+        recognition.lang = _converse.api.settings.get('voicechat').transcribeLanguage;
+        recognition.continuous = true;
+        recognition.interimResults = false;
+
+        recognition.onresult = function(event)
+        {
+            console.debug("Speech recog event", event)
+
+            if (event.results[event.resultIndex].isFinal==true)
+            {
+                const transcript = event.results[event.resultIndex][0].transcript;
+                console.debug("Speech recog transcript", transcript);
+                if (model) model.sendMessage({'body': transcript});		
+				if (model) model.setChatState(_converse.ACTIVE);					
+			}
+        }
+
+        recognition.onspeechend  = function(event)
+        {
+            console.debug("Speech recog onspeechend", event);		
+        }
+
+        recognition.onstart = function(event)
+        {
+            console.debug("Speech to text started", event);
+            recognitionActive = true;			
+        }
+
+        recognition.onend = function(event)
+        {
+            console.debug("Speech to text ended", event);
+
+            if (recognitionActive)
+            {
+                console.debug("Speech to text restarted");
+                setTimeout(function() {recognition.start()}, 1000);
+            }
+        }
+
+        recognition.onerror = function(event)
+        {
+            console.debug("Speech to text error", event);
+        }
+
+        recognition.start();		
     }	
 	
 }));

+ 0 - 0
packages/voicechat-old/voicechat.png → packages/voicechat/voicechat.png


Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác