-
Notifications
You must be signed in to change notification settings - Fork 0
/
script.js
167 lines (149 loc) · 5.85 KB
/
script.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
const protocol = window.location.protocol === "https:" ? "wss://" : "ws://";
const host = "uutan-deno-websocket-app.deno.dev";
// GitHub Pagesのため
const gitHubRepoName = "deno-websocket-app";
const port = 443;
const slideUrlInput = document.getElementById("slideUrlInput");
const startPresentationButton = document.getElementById(
"startPresentationButton"
);
const startPresentationDiv = document.getElementById("startPresentation");
const presentationRoomDiv = document.getElementById("presentationRoom");
const prevButton = document.getElementById("prev");
const nextButton = document.getElementById("next");
const fullscreenBtn = document.getElementById("fullscreenBtn");
const slideFrame = document.getElementById("slideFrame");
const toTopPageLink = document.getElementById("toTopPage");
let socket;
let currentSlide = 1;
// ルームIDをURLパラメータで取得して、WebSocket接続をセットアップ
const urlParams = new URLSearchParams(window.location.search);
const slideUrlFromUrl = urlParams.get("slideUrl");
if (slideUrlFromUrl) {
setupWebSocket(slideUrlFromUrl);
// ローカルストレージにslideUrlがなければスライド操作不可
if (localStorage.getItem("slide_sync_slideUrl") != slideUrlFromUrl) {
const speakerClasses = document.getElementsByClassName("speaker");
for (const speakerClass of speakerClasses) {
speakerClass.style.display = "none";
}
toTopPageLink.textContent = "プレゼンテーション開始する";
}
// 視聴者の場合表示する
if (localStorage.getItem("slide_sync_slideUrl") == slideUrlFromUrl) {
const audiencesClasses = document.getElementsByClassName("audience");
for (const audiencesClass of audiencesClasses) {
audiencesClass.style.display = "none";
}
}
toTopPageLink.href = `/${gitHubRepoName}`;
slideFrame.src = slideUrlFromUrl; // iflameにURLを設定
startPresentationDiv.style.display = "none"; // ルーム作成セクションを非表示
presentationRoomDiv.style.display = "block"; // スライド表示セクションを表示
} else {
startPresentationDiv.style.display = "block"; // ルーム作成セクションを表示
presentationRoomDiv.style.display = "none"; // スライド表示セクションを非表示
}
function replacePubWithEmbed(url) {
// URLオブジェクトを作成
const urlObj = new URL(url);
// パスが '/pub' で終わる場合のみ '/embed' に置き換え
if (urlObj.pathname.endsWith("/pub")) {
urlObj.pathname = urlObj.pathname.replace("/pub", "/embed");
}
// 変更されたURLを文字列として返す
return urlObj.toString();
}
startPresentationButton.addEventListener("click", () => {
const slideUrl = replacePubWithEmbed(slideUrlInput.value.trim());
if (slideUrl) {
const presentationRoomUrl = `${
window.location.origin
}/${gitHubRepoName}?slideUrl=${encodeURIComponent(slideUrl)}`;
// ローカルストレージにslideUrlを保存
// slideUrlが保存されている人がホスト
localStorage.setItem("slide_sync_slideUrl", slideUrl);
window.location.href = presentationRoomUrl; // URLを更新してリダイレクト
} else {
alert("URLを入力してください。");
}
});
// WebSocketのセットアップ
function setupWebSocket(slideUrl) {
const socketUrl = `${protocol}${host}:${port}/?slideUrl=${encodeURIComponent(
slideUrl
)}`;
socket = new WebSocket(socketUrl);
socket.onopen = () => {
console.log("WebSocket接続中...");
slideFrame.src = slideUrl; // スライドURLを設定
};
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
// メッセージがスライドの変更情報であることを確認
if (data.action === "slide") {
currentSlide = data.slide;
console.log(`Received slide change: ${currentSlide}`);
updateSlide();
}
};
socket.onerror = (error) => {
console.error("WebSocketエラー:", error);
};
socket.onclose = () => {
console.log("WebSocket接続終了");
};
// スライド操作ボタン
prevButton.addEventListener("click", () => {
if (currentSlide > 1) {
currentSlide--;
updateSlide();
// スライド変更情報をサーバーに送信
socket.send(JSON.stringify({ action: "slide", slide: currentSlide }));
}
});
nextButton.addEventListener("click", () => {
currentSlide++;
updateSlide();
// スライド変更情報をサーバーに送信
socket.send(JSON.stringify({ action: "slide", slide: currentSlide }));
});
// キーボード操作でスライドを前後に切り替え
document.addEventListener("keydown", (event) => {
if (event.key === "ArrowLeft" && currentSlide > 1) {
currentSlide--;
updateSlide();
// スライド変更情報をサーバーに送信
socket.send(JSON.stringify({ action: "slide", slide: currentSlide }));
} else if (event.key === "ArrowRight") {
currentSlide++;
updateSlide();
// スライド変更情報をサーバーに送信
socket.send(JSON.stringify({ action: "slide", slide: currentSlide }));
}
});
// スライドをフルスクリーンで表示する
fullscreenBtn.addEventListener("click", () => {
if (slideFrame.requestFullscreen) {
slideFrame.requestFullscreen();
} else if (slideFrame.webkitRequestFullscreen) {
slideFrame.webkitRequestFullscreen();
} else if (slideFrame.msRequestFullscreen) {
slideFrame.msRequestFullscreen();
}
});
}
// スライドの更新
function updateSlide() {
slideFrame.src = `${slideFrame.src.split("?")[0]}?slide=${currentSlide}`;
}
// コピーURL
function copyUrl() {
const element = document.createElement("input");
element.value = location.href;
document.body.appendChild(element);
element.select();
document.execCommand("copy");
document.body.removeChild(element);
window.alert("コピーしました");
}