");
1253 | let td = $("").addClass("users-list-table-td").appendTo(tr);
1254 | // 名前
1255 | $("").addClass("users-list-table-text")
1256 | .text(user.name)
1257 | .appendTo(td);
1258 | // 選択中アイコン
1259 | let checking_icon = $(" ")
1260 | .addClass("users-list-table-checking-icon")
1261 | .appendTo(td)
1262 | .hide();
1263 | // 選択済みアイコン
1264 | let checked_icon = $(" ")
1265 | .addClass("users-list-table-checked-icon")
1266 | .appendTo(td);
1267 | // ユーザーが非選択の場合は選択済みアイコンを非表示にする
1268 | if(selected_user_names.indexOf(user.name) < 0) {
1269 | checked_icon.hide();
1270 | }
1271 |
1272 | // tdタグをホバーしたとき背景色を変更、選択中アイコンを表示する
1273 | td.css("cursor", "pointer")
1274 | td.hover(function(e) {
1275 | td.css("background-color", "rgba(0, 0, 0, .04)")
1276 | checking_icon.show();
1277 | }, function(e) {
1278 | td.css("background-color", "")
1279 | checking_icon.hide();
1280 | });
1281 |
1282 | // tdタグをクリックした時、選択/非選択を入れ替える
1283 | td.click(function() {
1284 | if(selected_user_names.indexOf(user.name) >= 0) {
1285 | // 選択を外す
1286 | selected_user_names = selected_user_names.filter(a => a != user.name);
1287 | checked_icon.hide();
1288 | } else {
1289 | // 選択をする
1290 | selected_user_names.push(user.name);
1291 | checked_icon.show();
1292 | }
1293 | update_request_buttons();
1294 | });
1295 | tr.appendTo(table);
1296 | }
1297 | // 他の人と通話中のユーザー
1298 | for (let user of in_other_room_users) {
1299 | let tr = $(" ");
1300 | let td = $("").addClass("users-list-table-td").appendTo(tr);
1301 | // 名前
1302 | $("").addClass("users-list-table-text-disabled")
1303 | .text(user.name)
1304 | .appendTo(td);
1305 | // 通話中アイコン
1306 | $(" ")
1307 | .addClass("users-list-table-talking-icon")
1308 | .appendTo(td);
1309 | tr.appendTo(table);
1310 | }
1311 | });
1312 | // 自分と通話中のユーザー
1313 | for (let user of my_room_users) {
1314 | let tr = $(" ");
1315 | let td = $("").addClass("users-list-table-td").appendTo(tr);
1316 | // 名前
1317 | $("").addClass("users-list-table-text-in-room")
1318 | .text(user.name)
1319 | .appendTo(td);
1320 | if(user.is_mute) {
1321 | // ミュートアイコン
1322 | $(" ")
1323 | .addClass("users-list-table-mute-icon")
1324 | .appendTo(td)
1325 | .css("right", user.is_sharing_display ? "30px" : "");
1326 | }
1327 | if(user.is_sharing_display) {
1328 | // 画面共有アイコン
1329 | $(" ")
1330 | .addClass("users-list-table-share-display-icon")
1331 | .appendTo(td);
1332 | }
1333 | tr.appendTo($("#"+ROOM_MEMBERS_TABLE_ID));
1334 | }
1335 | if(invited_my_room_users.length > 0) {
1336 | {
1337 | // セパレータ
1338 | let tr = $(" ");
1339 | let td = $("").addClass("users-list-table-td").appendTo(tr);
1340 | $(" ").addClass("users-list-table-hr").appendTo(td);
1341 | tr.appendTo($("#"+ROOM_MEMBERS_TABLE_ID));
1342 | }
1343 | {
1344 | // リクエスト済み(num)
1345 | let tr = $(" | ");
1346 | let td = $("").addClass("users-list-table-td").appendTo(tr);
1347 | $("").addClass("users-list-table-text")
1348 | .text("リクエスト済み(" + invited_my_room_users.length + ")")
1349 | .css("color", "#5D5D5D").css("font-weight", "bold")
1350 | .appendTo(td);
1351 | tr.appendTo($("#"+ROOM_MEMBERS_TABLE_ID));
1352 | }
1353 | for (let user of invited_my_room_users) {
1354 | // 名前
1355 | let tr = $(" ");
1356 | let td = $("").addClass("users-list-table-td").appendTo(tr);
1357 | $("").addClass("users-list-table-text-in-room")
1358 | .text(user.name)
1359 | .appendTo(td);
1360 | tr.appendTo($("#"+ROOM_MEMBERS_TABLE_ID));
1361 | }
1362 | }
1363 |
1364 | // ボタンを更新
1365 | update_request_buttons();
1366 | }
1367 |
1368 | // ユーザーリストダイアログ作成
1369 | var create_user_list_dialog = function() {
1370 | let dialog = $(" ").addClass("user-list-dialog");
1371 | setup_move_and_resize_dialog(dialog)
1372 |
1373 | // ユーザーリストのテーブル
1374 | let user_list_table_container = $(" ").addClass("dialog-list-container").appendTo(dialog);
1375 | $(" ")
1376 | .attr("id", USERS_TABLE_ID)
1377 | .addClass("users-list-table")
1378 | .appendTo(user_list_table_container);
1379 |
1380 | // 通話リクエストボタン(無効)
1381 | let request_button_disabled = $("")
1382 | .addClass("request-talking-button-disabled")
1383 | .appendTo(dialog);
1384 | $(" ").addClass("button-text-white")
1385 | .text("通話をリクエスト")
1386 | .appendTo(request_button_disabled);
1387 |
1388 | // 通話リクエストボタン
1389 | let request_button = $(" ")
1390 | .attr("id", REQUEST_TALKING_BUTTON_ID)
1391 | .addClass("request-talking-button")
1392 | .appendTo(dialog)
1393 | .hide()
1394 | .click(function(e) {
1395 | invoke_async_process(async function() {
1396 | await process_talk_button_async();
1397 | });
1398 | });
1399 | $(" ").addClass("button-text-white")
1400 | .text("通話をリクエスト")
1401 | .appendTo(request_button);
1402 |
1403 | return dialog;
1404 | }
1405 |
1406 | // 通話パレット作成
1407 | var create_talking_palette = function() {
1408 | let div = $(" ").addClass("talking-palette");
1409 | let container = $(" ").addClass("talking-palette-tools-container").appendTo(div);
1410 | $(" ")
1411 | .attr("id", TALKING_PALETTE_MUTE_BUTTON_ID)
1412 | .addClass("mic-off-button-talking-palette")
1413 | .attr("title", "マイクをオフ")
1414 | .appendTo(container)
1415 | .click(() => set_mute(true));
1416 | $(" ")
1417 | .attr("id", TALKING_PALETTE_UNMUTE_BUTTON_ID)
1418 | .addClass("mic-on-button-talking-palette")
1419 | .attr("title", "マイクをオン")
1420 | .appendTo(container)
1421 | .hide()
1422 | .click(() => set_mute(false));
1423 | $(" ")
1424 | .attr("id", TALKING_PALETTE_STOP_SHARE_DISPLAY_ID)
1425 | .addClass("share-display-button-talking-palette")
1426 | .attr("title", "画面共有を停止")
1427 | .appendTo(container)
1428 | .hide()
1429 | .click(set_share_display_off);
1430 | $(" ")
1431 | .addClass("hung-up-button-talking-palette")
1432 | .attr("title", "通話を切る")
1433 | .appendTo(container)
1434 | .click(process_hung_up_button);
1435 | $(" ")
1436 | .addClass("spacing-talking-palette")
1437 | .appendTo(container);
1438 | $(" ")
1439 | .addClass("maximize-button-talking-palette")
1440 | .appendTo(container)
1441 | .attr("title", "通話画面を最大化")
1442 | .click(function(e) {
1443 | invoke_async_process(async () => {
1444 | if(own_user.is_sharing_display) {
1445 | // 画面共有中の場合は共有をやめるか聞く
1446 | let ret = await ask_stop_sharing_for_showing_talk_screen_async();
1447 | if(!ret) return;
1448 | // 共有停止
1449 | set_share_display_off();
1450 | }
1451 | // 通話スクリーンを表示する
1452 | show_view_from_bottom_right($("#"+TALK_SCREEN_ID));
1453 | // 共有画面を通話スクリーンのコンテナに移動
1454 | dispose_mini_remote_videos();
1455 | });
1456 | });
1457 | return div;
1458 | }
1459 |
1460 | // ミニ画像表示コンテナ作成
1461 | var create_mini_remote_videos_container = function() {
1462 | let container = $(" ")
1463 | .addClass("mini-remote-videos-container");
1464 | let maximize_button = $(" ")
1465 | .attr("title", "通話画面を最大化")
1466 | .addClass("maximize-screen-button")
1467 | .appendTo(container)
1468 | .click(function() {
1469 | invoke_async_process(async () => {
1470 | if(own_user.is_sharing_display) {
1471 | // 画面共有中の場合は共有をやめるか聞く
1472 | let ret = await ask_stop_sharing_for_showing_talk_screen_async();
1473 | if(!ret) return;
1474 | // 共有停止
1475 | set_share_display_off();
1476 | }
1477 | // 通話スクリーンを表示する
1478 | show_view_from_bottom_right($("#"+TALK_SCREEN_ID));
1479 | // 共有画面を通話スクリーンのコンテナに移動
1480 | dispose_mini_remote_videos();
1481 | });
1482 | })
1483 | .hide();
1484 | let minimize_button = $(" ")
1485 | .attr("title", "画面共有をたたむ")
1486 | .addClass("minimize-screen-button")
1487 | .appendTo(container)
1488 | .click(function() {
1489 | $("#"+MINI_REMOTE_VIDEOS_CONTAINER_ID).animate({
1490 | width: "0px"
1491 | }, 250, "swing", function() {
1492 | $("#"+STRETCH_MINI_REMOTE_VIDEOS_ID).css("width", "");
1493 | });
1494 | })
1495 | .hide();
1496 | container.hover(function() {
1497 | maximize_button.show();
1498 | minimize_button.show();
1499 | }, function() {
1500 | maximize_button.hide();
1501 | minimize_button.hide();
1502 | });
1503 | return container;
1504 | }
1505 |
1506 | // 通話スクリーン内のメンバーウィンドウ作成
1507 | var create_member_window = function () {
1508 | let div = $(" ").addClass("member-list-view-talk-screen");
1509 | let inner_div = $(" ").addClass("member-list-view-talk-screen-inner").appendTo(div);
1510 |
1511 | {
1512 | // 参加者一覧
1513 | let container = $(" ")
1514 | .attr("id", TALK_SCREEN_MEMBERS_LIST_ID)
1515 | .appendTo(inner_div);
1516 |
1517 | // キャプション
1518 | $(" ").addClass("window-caption")
1519 | .text("参加者")
1520 | .appendTo(container);
1521 |
1522 | // クローズボタン
1523 | $(" ").addClass("member-window-close-button")
1524 | .appendTo(container)
1525 | .click(hide_member_window_on_talk_screen);
1526 |
1527 | // ルームメンバーリストテーブル
1528 | let list_container = $(" ").addClass("window-table-container").appendTo(container);
1529 | $(" ").attr("id", ROOM_MEMBERS_TABLE_ID).addClass("users-list-table").appendTo(list_container);
1530 |
1531 | // 参加者を追加ボタン
1532 | let add_member_button = $("")
1533 | .addClass("add-member-button")
1534 | .appendTo(container)
1535 | .click(function(e) {
1536 | $("#"+TALK_SCREEN_MEMBERS_LIST_ID).hide();
1537 | $("#"+TALK_SCREEN_ADD_MEMBERS_CONTAINER_ID).show();
1538 | });
1539 | $(" ").addClass("icon-button-text")
1540 | .text("参加者を追加")
1541 | .appendTo(add_member_button);
1542 | }
1543 |
1544 | {
1545 | // 参加者を追加
1546 | let container = $(" ")
1547 | .attr("id", TALK_SCREEN_ADD_MEMBERS_CONTAINER_ID)
1548 | .appendTo(inner_div);
1549 |
1550 | // キャプション
1551 | $(" ").addClass("window-caption-padding")
1552 | .text("参加者を追加")
1553 | .appendTo(container);
1554 |
1555 | // バックボタン
1556 | $(" ").addClass("member-window-back-button")
1557 | .appendTo(container)
1558 | .click(function(e) {
1559 | $("#"+TALK_SCREEN_ADD_MEMBERS_CONTAINER_ID).hide();
1560 | $("#"+TALK_SCREEN_MEMBERS_LIST_ID).show();
1561 | // 選択ユーザーをクリアする
1562 | selected_user_names = [];
1563 | update_tables();
1564 | });
1565 |
1566 | // クローズボタン
1567 | $(" ").addClass("member-window-close-button")
1568 | .appendTo(container)
1569 | .click(hide_member_window_on_talk_screen);
1570 |
1571 | // ユーザーリストテーブル
1572 | let list_container = $(" ").addClass("window-table-container").appendTo(container);
1573 | $(" ").attr("id", TALK_SCREEN_USERS_TABLE_ID).addClass("users-list-table").appendTo(list_container);
1574 |
1575 | // 参加リクエストボタン(無効)
1576 | let request_button_disabled = $("")
1577 | .addClass("request-joining-button-disabled")
1578 | .appendTo(container);
1579 | $(" ").addClass("button-text-white")
1580 | .text("参加をリクエスト")
1581 | .appendTo(request_button_disabled);
1582 |
1583 | // 参加リクエストボタン
1584 | let button = $(" ")
1585 | .attr("id", REQUEST_JOINING_BUTTON_ID)
1586 | .addClass("request-joining-button")
1587 | .appendTo(container)
1588 | .hide()
1589 | .click(process_request_joining_button);
1590 | $(" ").addClass("button-text-white")
1591 | .text("参加をリクエスト")
1592 | .appendTo(button);
1593 |
1594 | container.hide();
1595 | }
1596 |
1597 | return div;
1598 | }
1599 |
1600 | // 通話スクリーンのメンバーウィンドウ表示
1601 | var show_member_window_on_talk_screen = function() {
1602 | $("#"+TALK_SCREEN_MEMBERS_WINDOW_ID).show();
1603 | $("#"+TALK_SCREEN_MEMBERS_WINDOW_ID).animate({
1604 | width: "248px"
1605 | }, 250, "swing", function() {
1606 | $("#"+TALK_SCREEN_SHOW_MEMBERS_BUTTON_ID).hide();
1607 | $("#"+TALK_SCREEN_HIDE_MEMBERS_BUTTON_ID).show();
1608 | });
1609 | }
1610 |
1611 | // 通話スクリーンのメンバーウィンドウを隠す
1612 | var hide_member_window_on_talk_screen = function() {
1613 | $("#"+TALK_SCREEN_MEMBERS_WINDOW_ID).animate({
1614 | width: "0"
1615 | }, 250, "swing", function() {
1616 | $("#"+TALK_SCREEN_MEMBERS_WINDOW_ID).hide();
1617 | $("#"+TALK_SCREEN_HIDE_MEMBERS_BUTTON_ID).hide();
1618 | $("#"+TALK_SCREEN_SHOW_MEMBERS_BUTTON_ID).show();
1619 | });
1620 | }
1621 |
1622 | // 通話スクリーン作成
1623 | var create_talk_screen = function() {
1624 | let bg = $(" ").addClass("talk-screen-bg-mask");
1625 | // メンバーリスト、画面共有ビューのコンテナ
1626 | let container = $(" ").addClass("view-container-talk-screen").appendTo(bg);
1627 | // リモートビデオコンテナ
1628 | let remote_videos_area_outer = $(" ")
1629 | .addClass("remote-videos-area-outer")
1630 | .appendTo(container);
1631 | let remote_videos_area = $(" ")
1632 | .addClass("remote-videos-area")
1633 | .appendTo(remote_videos_area_outer);
1634 | let description_container = $(" ")
1635 | .addClass("remote-videos-area-child")
1636 | .appendTo(remote_videos_area);
1637 | $(" ")
1638 | .attr("id", TALK_SCREEN_REMOTE_VIDEOS_DESCRIPTION_ID)
1639 | .addClass("remote-videos-description")
1640 | .text("画面共有が開始されるとここに表示されます。")
1641 | .appendTo(description_container);
1642 | let remote_videos_container_outer = $(" ")
1643 | .attr("id", TALK_SCREEN_REMOTE_VIDEOS_CONTAINER_OUTER_ID)
1644 | .addClass("remote-videos-area-child")
1645 | .appendTo(remote_videos_area);
1646 | $(" ")
1647 | .attr("id", TALK_SCREEN_REMOTE_VIDEOS_CONTAINER_ID)
1648 | .addClass("remote-videos-container")
1649 | .appendTo(remote_videos_container_outer);
1650 | // メンバーウィンドウ
1651 | create_member_window()
1652 | .attr("id", TALK_SCREEN_MEMBERS_WINDOW_ID)
1653 | .appendTo(container)
1654 | .hide();
1655 | // リモートビデオの共有者表示
1656 | let text_container = $(" ")
1657 | .attr("id", TALK_SCREEN_SHARING_USER_NAME_TEXT_ID)
1658 | .addClass("sharing-user-name-text-container")
1659 | .appendTo(bg)
1660 | .hide();
1661 | $(" ")
1662 | .addClass("sharing-user-name-text")
1663 | .text("の画面")
1664 | .appendTo(text_container);
1665 | // 最小化
1666 | $(" ").addClass("close-talk-button")
1667 | .click(function() {
1668 | // 通話スクリーンをしまう
1669 | hide_view_to_bottom_right(bg);
1670 | // ミニ動画共有コンテナセットアップ
1671 | setup_mini_remote_videos();
1672 | })
1673 | .attr("title", "通話画面を最小化")
1674 | .appendTo(bg);
1675 | // マイクOFF
1676 | $(" ").addClass("mic-off-button")
1677 | .attr("id", TALK_SCREEN_MUTE_BUTTON_ID)
1678 | .attr("title", "マイクをオフ")
1679 | .appendTo(bg)
1680 | .click(() => set_mute(true));
1681 | // マイクON
1682 | $(" ").addClass("mic-on-button")
1683 | .attr("id", TALK_SCREEN_UNMUTE_BUTTON_ID)
1684 | .attr("title", "マイクをオン")
1685 | .appendTo(bg)
1686 | .hide()
1687 | .click(() => set_mute(false));
1688 | // 共有開始
1689 | $(" ").addClass("share-display-button")
1690 | .attr("id", TALK_SCREEN_START_SHARE_DISPLAY_ID)
1691 | .attr("title", "画面を共有")
1692 | .appendTo(bg)
1693 | .click(function(e) {
1694 | invoke_async_process(async function() {
1695 | await set_share_display_on_async();
1696 | });
1697 | });
1698 | // 共有停止
1699 | $(" ").addClass("stop-share-display-button")
1700 | .attr("id", TALK_SCREEN_STOP_SHARE_DISPLAY_ID)
1701 | .attr("title", "画面共有を停止")
1702 | .appendTo(bg)
1703 | .click(set_share_display_off)
1704 | .hide();
1705 | // 退室
1706 | $(" ").addClass("hang-up-button")
1707 | .attr("title", "通話を切る")
1708 | .appendTo(bg)
1709 | .click(process_hung_up_button);
1710 | // メンバー表示・非表示
1711 | $(" ").addClass("hide-members-button")
1712 | .attr("id", TALK_SCREEN_HIDE_MEMBERS_BUTTON_ID)
1713 | .attr("title", "メンバーを非表示")
1714 | .click(hide_member_window_on_talk_screen)
1715 | .appendTo(bg)
1716 | .hide();
1717 | $(" ").addClass("show-members-button")
1718 | .attr("id", TALK_SCREEN_SHOW_MEMBERS_BUTTON_ID)
1719 | .attr("title", "メンバーを表示")
1720 | .click(show_member_window_on_talk_screen)
1721 | .appendTo(bg);
1722 | return bg;
1723 | }
1724 |
1725 | // 待機ルームに入る
1726 | var join_waiting_room = function(room_name) {
1727 | waiting_room = peer.joinRoom(room_name, {
1728 | mode: params.nbwhisper_room_mode_for_waiting_room
1729 | });
1730 | if(waiting_room == null) {
1731 | console.log(logPrefix, "cannot create room...");
1732 | }
1733 |
1734 | waiting_room.once("open", function() {
1735 | console.log(logPrefix, "waiting room open")
1736 | // メンバーにユーザー情報を送信
1737 | send_message_to_waiting_room(UPDATE_USER_DATA_MESSAGE);
1738 | });
1739 |
1740 | waiting_room.on("peerJoin", function(peer_id) {
1741 | console.log(logPrefix, "waiting peer joined to room: " + peer_id);
1742 | });
1743 |
1744 | waiting_room.on("peerLeave", function(peer_id) {
1745 | console.log(logPrefix, "waiting peer left from room: " + peer_id);
1746 | // このpeer_idに限らず、ルームに参加していないpeer_idは全て削除する。
1747 | // ユーザー更新
1748 | for(let temp_peer_id in own_other_peer_id_to_joining_rooms) {
1749 | if(temp_peer_id == peer_id || !(temp_peer_id in waiting_room.members))
1750 | delete own_other_peer_id_to_joining_rooms.temp_peer_id;
1751 | }
1752 | let remove_users = [];
1753 | for(let user of other_users) {
1754 | for(let temp_peer_id in user.peer_id_to_joining_rooms) {
1755 | if(temp_peer_id == peer_id || !(temp_peer_id in waiting_room.members))
1756 | delete user.peer_id_to_joining_rooms[temp_peer_id];
1757 | }
1758 | if(Object.keys(user.peer_id_to_joining_rooms).length == 0) {
1759 | // ユーザーが一つもPeerIdを持たなくなったので削除する
1760 | remove_users.push(user);
1761 | }
1762 | }
1763 | other_users = other_users.filter(a => remove_users.indexOf(a) < 0);
1764 | update_tables();
1765 | });
1766 |
1767 | waiting_room.on("data", function(data) {
1768 | if(data == null) return;
1769 | let message_obj = JSON.parse(data.data);
1770 | let peer_id = data.src;
1771 | console.log(logPrefix, "waiting meesage from: " + peer_id);
1772 | console.log(logPrefix, message_obj);
1773 |
1774 | if(message_obj.message == UPDATE_USER_DATA_MESSAGE || message_obj.message == UPDATE_USER_DATA_RESPONSE_MESSAGE) {
1775 | if(message_obj.message == UPDATE_USER_DATA_MESSAGE) {
1776 | // レスポンスする: この処理で新規メンバーにも自身の情報が伝わる
1777 | send_message_to_waiting_room(UPDATE_USER_DATA_RESPONSE_MESSAGE);
1778 | }
1779 | setTimeout(() => {
1780 | // 情報更新
1781 | update_other_user(peer_id, message_obj);
1782 | }, 1);
1783 | } else if(message_obj.message == INVITE_USER_MESSAGE) {
1784 | // 招待を送られた
1785 | if(message_obj.target_user != own_user_name) {
1786 | // 自分への招待ではない
1787 | return;
1788 | }
1789 | console.log(logPrefix, "invited room: " + message_obj.room_name + " from: " + message_obj.user_name);
1790 | own_user.invited_rooms.push(message_obj.room_name);
1791 | // データ更新を送信
1792 | send_message_to_waiting_room(UPDATE_USER_DATA_MESSAGE);
1793 | setTimeout(() => {
1794 | // 情報更新
1795 | update_other_user(peer_id, message_obj);
1796 | }, 1);
1797 | // キューに招待メッセージデータを追加
1798 | invitaions_queue.push(message_obj);
1799 | if(!is_processing_invitaions_queue) {
1800 | process_invitations_queue();
1801 | }
1802 | }
1803 | });
1804 |
1805 | waiting_room.on("close", function() {
1806 | console.log(logPrefix, "I left from waiting room.");
1807 | if(!is_page_unloading) {
1808 | // ページアンロード中以外でここに来たらアラート
1809 | alert("NBWhisperの接続が切断されました。このページを再読み込みしてください。");
1810 | }
1811 | });
1812 | }
1813 |
1814 | // 情報を更新する
1815 | var update_other_user = function(peer_id, message_obj) {
1816 | if(message_obj.user_name == own_user_name) {
1817 | // 自身の場合は自身の情報を更新する
1818 | own_other_peer_id_to_joining_rooms[peer_id] = message_obj.joining_room;
1819 | return;
1820 | }
1821 | let existed_index = -1;
1822 | for(let i = 0; i < other_users.length; ++i) {
1823 | if(other_users[i].name == message_obj.user_name) {
1824 | existed_index = i;
1825 | break;
1826 | }
1827 | }
1828 | if(existed_index >= 0) {
1829 | // 更新
1830 | other_users[existed_index].peer_id_to_joining_rooms[peer_id] = message_obj.joining_room;
1831 | other_users[existed_index].invited_rooms = message_obj.invited_rooms;
1832 | } else {
1833 | // 追加
1834 | let new_user = {
1835 | name : message_obj.user_name,
1836 | is_mute : false,
1837 | is_sharing_display : false,
1838 | peer_id_to_joining_rooms : {},
1839 | invited_rooms : message_obj.invited_rooms
1840 | }
1841 | new_user.peer_id_to_joining_rooms[peer_id] = message_obj.joining_room;
1842 | other_users.push(new_user);
1843 | }
1844 | update_tables();
1845 | }
1846 |
1847 | // 招待の処理のキューを処理する
1848 | var invitaions_queue = []; // 処理する招待のキュー
1849 | var is_processing_invitaions_queue = false; // 招待キューを処理中のフラグ
1850 | var process_invitations_queue = function() {
1851 | if(invitaions_queue.length > 0) {
1852 | is_processing_invitaions_queue = true;
1853 | let message_obj = invitaions_queue.shift();
1854 | setTimeout(async () => {
1855 | await process_invitation_async(message_obj);
1856 | // 処理が終了したら次の処理
1857 | process_invitations_queue();
1858 | }, 1);
1859 | } else {
1860 | // キューがなくなったら何もしない
1861 | console.log(logPrefix, "process_invitations_queue has finished.");
1862 | is_processing_invitaions_queue = false;
1863 | }
1864 | }
1865 |
1866 | // 招待を処理する
1867 | var process_invitation_async = async function(message_obj) {
1868 | // ルームメンバーの取得
1869 | let room_members = [];
1870 | for(let user of other_users) {
1871 | if(user.joining_room == message_obj.room_name) room_members.push(user.name);
1872 | }
1873 | // 招待を受けるか?
1874 | if(await ask_accept_talking(message_obj.user_name, room_members)) {
1875 | // 招待を消去する
1876 | own_user.invited_rooms = own_user.invited_rooms.filter(r => r != message_obj.room_name);
1877 | // 部屋が存在するか確認する
1878 | let exists_room = false;
1879 | for(let user of other_users) {
1880 | if(user.name == message_obj.user_name) {
1881 | if(message_obj.peer_id in user.peer_id_to_joining_rooms) {
1882 | exists_room = user.peer_id_to_joining_rooms[message_obj.peer_id] == message_obj.room_name;
1883 | break;
1884 | }
1885 | }
1886 | }
1887 | if(exists_room) {
1888 | // 自身がほかのタブ・ウィンドウでルームに参加済みか確認する
1889 | let has_room = false;
1890 | for(let peer_id in own_other_peer_id_to_joining_rooms) {
1891 | if(own_other_peer_id_to_joining_rooms[peer_id] != "") {
1892 | has_room = true;
1893 | break;
1894 | }
1895 | }
1896 | if(!has_room) {
1897 | // 通話を開始する
1898 | await start_talking_async(message_obj.room_name);
1899 | // データ更新を送信
1900 | send_message_to_waiting_room(UPDATE_USER_DATA_MESSAGE);
1901 | } else {
1902 | // データ更新を送信
1903 | send_message_to_waiting_room(UPDATE_USER_DATA_MESSAGE);
1904 | // 参加済みなのでアラート表示
1905 | show_room_existed_alert();
1906 | }
1907 | } else {
1908 | // データ更新を送信
1909 | send_message_to_waiting_room(UPDATE_USER_DATA_MESSAGE);
1910 | // 通話がないため招待無効のアラート表示
1911 | show_unavailable_invitation_with_finished_talk_alert();
1912 | }
1913 | } else {
1914 | // 招待を消去する
1915 | own_user.invited_rooms = own_user.invited_rooms.filter(r => r != message_obj.room_name);
1916 | // データ更新を送信
1917 | send_message_to_waiting_room(UPDATE_USER_DATA_MESSAGE);
1918 | }
1919 | }
1920 |
1921 | // 参加する
1922 | const join = function () {
1923 | // 待機ルームに入る
1924 | const waiting_room_name = get_waiting_room_name();
1925 | console.log(logPrefix, "待機ルーム: " + waiting_room_name);
1926 | join_waiting_room(waiting_room_name);
1927 | }
1928 |
1929 | // 初期化前処理
1930 | const pre_initialize = async function() {
1931 | // パラメータ初期化
1932 | await configure();
1933 | // Peerを作成する
1934 | try {
1935 | await setup_peer();
1936 | } catch(e) {
1937 | alert(e.toString());
1938 | throw e;
1939 | }
1940 | }
1941 |
1942 | // 初期化
1943 | const initialize_panel = function() {
1944 | $(" ").attr("id", ELEMENT_ID).appendTo($(document.body));
1945 |
1946 | // ユーザーリスト表示ボタン
1947 | $(" ")
1948 | .attr("id", SHOW_USERS_BUTTON_ID)
1949 | .addClass("show-list-button")
1950 | .click(show_user_list)
1951 | .attr("title", "ユーザーを表示")
1952 | .appendTo($("#"+ELEMENT_ID));
1953 |
1954 | // ユーザーリスト非表示ボタン
1955 | $(" ")
1956 | .attr("id", HIDE_USERS_BUTTON_ID)
1957 | .addClass("hide-list-button")
1958 | .click(hide_user_list)
1959 | .attr("title", "ユーザーを非表示")
1960 | .appendTo($("#"+ELEMENT_ID))
1961 | .hide();
1962 |
1963 | // ユーザーリスト
1964 | create_user_list_dialog()
1965 | .attr("id", USERS_LIST_DIALOG_ID)
1966 | .appendTo($("#"+ELEMENT_ID))
1967 | .hide();
1968 |
1969 | // 通話パレット
1970 | create_talking_palette()
1971 | .attr("id", TALKING_PALETTE_ID)
1972 | .appendTo($("#"+ELEMENT_ID))
1973 | .hide();
1974 |
1975 | // ミニ画面共有コンテナ
1976 | create_mini_remote_videos_container()
1977 | .attr("id", MINI_REMOTE_VIDEOS_CONTAINER_ID)
1978 | .appendTo("#"+ELEMENT_ID)
1979 | .hide();
1980 |
1981 | // ミニ画面共有コンテナを開くボタン
1982 | $(" ")
1983 | .attr("id", STRETCH_MINI_REMOTE_VIDEOS_ID)
1984 | .addClass("stretch-screen-button")
1985 | .appendTo("#"+ELEMENT_ID)
1986 | .click(function() {
1987 | $("#"+MINI_REMOTE_VIDEOS_CONTAINER_ID).animate({
1988 | width: "256px"
1989 | }, 250, "swing", function() {
1990 | $("#"+STRETCH_MINI_REMOTE_VIDEOS_ID).css("width", "0px");
1991 | });
1992 | })
1993 | .css("width", "0px")
1994 | .hide();
1995 |
1996 | // 通話画面
1997 | create_talk_screen()
1998 | .attr("id", TALK_SCREEN_ID)
1999 | .appendTo($("#"+ELEMENT_ID))
2000 | .hide();
2001 |
2002 | // ダミー映像ストリームキャンバス
2003 | create_dummy_video_canvas()
2004 | .attr("id", DUMMY_VIDEO_CANVAS_ID)
2005 | .appendTo($("#"+ELEMENT_ID));
2006 | }
2007 |
2008 | const load_extension = async function() {
2009 | console.log(logPrefix, "NBWhisper starting...");
2010 | load_css('./main.css');
2011 | Peer = await load_js_async("https://cdn.webrtc.ecl.ntt.com/skyway-4.4.5.min.js");
2012 | await pre_initialize();
2013 | initialize_panel();
2014 |
2015 | join();
2016 | console.log(logPrefix, "NBWhisper started.");
2017 | };
2018 |
2019 | // ページ離脱時
2020 | $(window).on('beforeunload', function() {
2021 | console.log(logPrefix, "page is closed.")
2022 | is_page_unloading = true;
2023 | if(talking_room != null) {
2024 | // 会話ルームから出る
2025 | console.log(logPrefix, "leave talking room...");
2026 | talking_room.close();
2027 | talking_room = null;
2028 | }
2029 | if(local_stream != null) {
2030 | // ローカルストリームを閉じる
2031 | console.log(logPrefix, "close local stream...");
2032 | local_stream.getTracks().forEach(t => t.stop());
2033 | local_stream = null;
2034 | }
2035 | if(display_stream != null) {
2036 | // ディスプレイストリームを閉じる
2037 | console.log(logPrefix, "close display stream...");
2038 | display_stream.getTracks().forEach(t => t.stop());
2039 | display_stream = null;
2040 | }
2041 | if(waiting_room != null) {
2042 | // 待機ルームから出る
2043 | console.log(logPrefix, "leave talking room...");
2044 | waiting_room.close();
2045 | waiting_room = null;
2046 | }
2047 | if(peer != null) {
2048 | // peerを閉じる
2049 | console.log(logPrefix, "destory peer...");
2050 | peer.destroy();
2051 | peer = null;
2052 | own_user.peer_id = null;
2053 | }
2054 | });
2055 |
2056 | var extension = {
2057 | load_ipython_extension : load_extension
2058 | };
2059 | return extension;
2060 | });
2061 |
--------------------------------------------------------------------------------
| | | | |