rein0421 commited on
Commit
828cc8a
·
verified ·
1 Parent(s): 77591a2

Upload 6 files

Browse files
templates/feedback.html CHANGED
@@ -1,193 +1,193 @@
1
- <!DOCTYPE html>
2
- <html lang="ja">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>会話フィードバック画面</title>
7
- <link
8
- href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
9
- rel="stylesheet"
10
- />
11
- <style>
12
- body {
13
- font-family: Arial, sans-serif;
14
- display: flex;
15
- justify-content: center;
16
- align-items: center;
17
- height: 100vh;
18
- margin: 0;
19
- background-color: #f5f5f5;
20
- }
21
- .card {
22
- border: 2px solid #000;
23
- border-radius: 20px;
24
- padding: 30px;
25
- width: 500px;
26
- text-align: center;
27
- background-color: white;
28
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
29
- }
30
- .level {
31
- font-size: 28px;
32
- font-weight: bold;
33
- margin-bottom: 20px;
34
- }
35
- .message {
36
- margin: 15px 0;
37
- font-size: 20px;
38
- font-weight: bold;
39
- color: #333;
40
- }
41
- .bar-container {
42
- display: flex;
43
- align-items: center;
44
- margin: 8px 0;
45
- }
46
- .bar-label {
47
- width: 60px;
48
- margin-right: 10px;
49
- font-weight: bold;
50
- }
51
- .bar {
52
- flex: 1;
53
- height: 25px;
54
- background-color: lightgray;
55
- border-radius: 5px;
56
- overflow: hidden;
57
- }
58
- .bar-fill {
59
- height: 100%;
60
- border-radius: 5px;
61
- }
62
- .back-button,
63
- .history-button {
64
- margin-top: 20px;
65
- margin-left: 20px;
66
- padding: 10px 20px;
67
- background-color: #007bff;
68
- color: white;
69
- border: none;
70
- border-radius: 5px;
71
- cursor: pointer;
72
- }
73
- .back-button:hover,
74
- .history-button:hover {
75
- background-color: #0056b3;
76
- }
77
- .flex {
78
- display: flex;
79
- justify-content: center;
80
- }
81
- </style>
82
- <script>
83
- function getMessage(level) {
84
- if (level < 20) return "やばい";
85
- if (level < 40) return "気をつけよう";
86
- if (level < 60) return "まずまずですね";
87
- if (level < 80) return "がんばれあとちょっと";
88
- return "素晴らしい";
89
- }
90
-
91
- window.onload = function () {
92
- const level = 73; // レベル値
93
- const percentages = [80, 50, 60, 100, 30]; // 各バーのパーセンテージ
94
- const labels = ["項目1", "項目2", "項目3", "項目4", "項目5"]; // 各項目名
95
-
96
- const message = getMessage(level);
97
- document.getElementById("level").innerText = `話者Lv: ${level}`;
98
- document.getElementById("message").innerText = message;
99
-
100
- const barElements = document.getElementsByClassName("bar-fill");
101
- const labelElements = document.getElementsByClassName("bar-label");
102
- for (let i = 0; i < barElements.length; i++) {
103
- barElements[i].style.width = `${percentages[i]}%`;
104
- labelElements[i].innerText = labels[i];
105
- }
106
- };
107
- function showRecorder() {
108
- // 録音画面へ遷移
109
- window.location.href = "index";
110
- }
111
- function showTalkDetil() {
112
- // 会話詳細へ遷移
113
- window.location.href = "talk_detail";
114
- }
115
- </script>
116
- </head>
117
- <body>
118
- <div class="card">
119
- <div class="level" id="level">話者Lv: 85</div>
120
- <div class="message" id="message">素晴らしい</div>
121
-
122
- <div class="bar-container">
123
- <span class="bar-label"></span>
124
- <div class="bar">
125
- <div class="bar-fill" style="background-color: lightblue"></div>
126
- </div>
127
- </div>
128
- <div class="bar-container">
129
- <span class="bar-label"></span>
130
- <div class="bar">
131
- <div class="bar-fill" style="background-color: peachpuff"></div>
132
- </div>
133
- </div>
134
- <div class="bar-container">
135
- <span class="bar-label"></span>
136
- <div class="bar">
137
- <div class="bar-fill" style="background-color: lightblue"></div>
138
- </div>
139
- </div>
140
- <div class="bar-container">
141
- <span class="bar-label"></span>
142
- <div class="bar">
143
- <div class="bar-fill" style="background-color: peachpuff"></div>
144
- </div>
145
- </div>
146
- <div class="bar-container">
147
- <span class="bar-label"></span>
148
- <div class="bar">
149
- <div class="bar-fill" style="background-color: lightcoral"></div>
150
- </div>
151
- </div>
152
- <div class="flex">
153
- <!--
154
- <form method="POST" action="/index">
155
- <div class="feedback-space">
156
- <input
157
- class="history-button"
158
- id="indexButton"
159
- type="submit"
160
- name="submit"
161
- value="録音画面を表示"
162
- />
163
- </div>
164
- </form>-->
165
- <button
166
- class="history-button"
167
- id="detailButton"
168
- onclick="showRecorder()"
169
- >
170
- ��音画面を表示
171
- </button>
172
- <button
173
- class="history-button"
174
- id="detailButton"
175
- onclick="showTalkDetil()"
176
- >
177
- 会話詳細を表示
178
- </button>
179
- <!--<form method="POST" action="/talk_detail">
180
- <div class="feedback-space">
181
- <input
182
- class="history-button"
183
- id="detailButton"
184
- type="submit"
185
- name="submit"
186
- value="会話詳細を表示"
187
- />
188
- </div>
189
- </form>-->
190
- </div>
191
- </div>
192
- </body>
193
- </html>
 
1
+ <!DOCTYPE html>
2
+ <html lang="ja">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>会話フィードバック画面</title>
7
+ <link
8
+ href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
9
+ rel="stylesheet"
10
+ />
11
+ <style>
12
+ body {
13
+ font-family: Arial, sans-serif;
14
+ display: flex;
15
+ justify-content: center;
16
+ align-items: center;
17
+ height: 100vh;
18
+ margin: 0;
19
+ background-color: #f5f5f5;
20
+ }
21
+ .card {
22
+ border: 2px solid #000;
23
+ border-radius: 20px;
24
+ padding: 30px;
25
+ width: 500px;
26
+ text-align: center;
27
+ background-color: white;
28
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
29
+ }
30
+ .level {
31
+ font-size: 28px;
32
+ font-weight: bold;
33
+ margin-bottom: 20px;
34
+ }
35
+ .message {
36
+ margin: 15px 0;
37
+ font-size: 20px;
38
+ font-weight: bold;
39
+ color: #333;
40
+ }
41
+ .bar-container {
42
+ display: flex;
43
+ align-items: center;
44
+ margin: 8px 0;
45
+ }
46
+ .bar-label {
47
+ width: 60px;
48
+ margin-right: 10px;
49
+ font-weight: bold;
50
+ }
51
+ .bar {
52
+ flex: 1;
53
+ height: 25px;
54
+ background-color: lightgray;
55
+ border-radius: 5px;
56
+ overflow: hidden;
57
+ }
58
+ .bar-fill {
59
+ height: 100%;
60
+ border-radius: 5px;
61
+ }
62
+ .back-button,
63
+ .history-button {
64
+ margin-top: 20px;
65
+ margin-left: 20px;
66
+ padding: 10px 20px;
67
+ background-color: #007bff;
68
+ color: white;
69
+ border: none;
70
+ border-radius: 5px;
71
+ cursor: pointer;
72
+ }
73
+ .back-button:hover,
74
+ .history-button:hover {
75
+ background-color: #0056b3;
76
+ }
77
+ .flex {
78
+ display: flex;
79
+ justify-content: center;
80
+ }
81
+ </style>
82
+ <script>
83
+ function getMessage(level) {
84
+ if (level < 20) return "やばい";
85
+ if (level < 40) return "気をつけよう";
86
+ if (level < 60) return "まずまずですね";
87
+ if (level < 80) return "がんばれあとちょっと";
88
+ return "素晴らしい";
89
+ }
90
+
91
+ window.onload = function () {
92
+ const level = 73; // レベル値
93
+ const percentages = [80, 50, 60, 100, 30]; // 各バーのパーセンテージ
94
+ const labels = ["項目1", "項目2", "項目3", "項目4", "項目5"]; // 各項目名
95
+
96
+ const message = getMessage(level);
97
+ document.getElementById("level").innerText = `話者Lv: ${level}`;
98
+ document.getElementById("message").innerText = message;
99
+
100
+ const barElements = document.getElementsByClassName("bar-fill");
101
+ const labelElements = document.getElementsByClassName("bar-label");
102
+ for (let i = 0; i < barElements.length; i++) {
103
+ barElements[i].style.width = `${percentages[i]}%`;
104
+ labelElements[i].innerText = labels[i];
105
+ }
106
+ };
107
+ function showRecorder() {
108
+ // 録音画面へ遷移
109
+ window.location.href = "index";
110
+ }
111
+ function showTalkDetil() {
112
+ // 会話詳細へ遷移
113
+ window.location.href = "talk_detail";
114
+ }
115
+ </script>
116
+ </head>
117
+ <body>
118
+ <div class="card">
119
+ <div class="level" id="level">話者Lv: 85</div>
120
+ <div class="message" id="message">素晴らしい</div>
121
+
122
+ <div class="bar-container">
123
+ <span class="bar-label"></span>
124
+ <div class="bar">
125
+ <div class="bar-fill" style="background-color: lightblue"></div>
126
+ </div>
127
+ </div>
128
+ <div class="bar-container">
129
+ <span class="bar-label"></span>
130
+ <div class="bar">
131
+ <div class="bar-fill" style="background-color: peachpuff"></div>
132
+ </div>
133
+ </div>
134
+ <div class="bar-container">
135
+ <span class="bar-label"></span>
136
+ <div class="bar">
137
+ <div class="bar-fill" style="background-color: lightblue"></div>
138
+ </div>
139
+ </div>
140
+ <div class="bar-container">
141
+ <span class="bar-label"></span>
142
+ <div class="bar">
143
+ <div class="bar-fill" style="background-color: peachpuff"></div>
144
+ </div>
145
+ </div>
146
+ <div class="bar-container">
147
+ <span class="bar-label"></span>
148
+ <div class="bar">
149
+ <div class="bar-fill" style="background-color: lightcoral"></div>
150
+ </div>
151
+ </div>
152
+ <div class="flex">
153
+ <!--
154
+ <form method="POST" action="/index">
155
+ <div class="feedback-space">
156
+ <input
157
+ class="history-button"
158
+ id="indexButton"
159
+ type="submit"
160
+ name="submit"
161
+ value="録音画面を表示"
162
+ />
163
+ </div>
164
+ </form>-->
165
+ <button
166
+ class="history-button"
167
+ id="detailButton"
168
+ onclick="showRecorder()"
169
+ >
170
+ 録音画面を表示
171
+ </button>
172
+ <button
173
+ class="history-button"
174
+ id="detailButton"
175
+ onclick="showTalkDetil()"
176
+ >
177
+ 会話詳細を表示
178
+ </button>
179
+ <!--<form method="POST" action="/talk_detail">
180
+ <div class="feedback-space">
181
+ <input
182
+ class="history-button"
183
+ id="detailButton"
184
+ type="submit"
185
+ name="submit"
186
+ value="会話詳細を表示"
187
+ />
188
+ </div>
189
+ </form>-->
190
+ </div>
191
+ </div>
192
+ </body>
193
+ </html>
templates/history.html CHANGED
@@ -1,125 +1,125 @@
1
- <!DOCTYPE html>
2
- <html lang="ja">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>会話履歴</title>
7
- <link
8
- href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
9
- rel="stylesheet"
10
- />
11
- <style>
12
- body {
13
- margin: 0;
14
- padding: 0;
15
- font-family: Arial, sans-serif;
16
- background-color: #fff;
17
- color: #000;
18
- }
19
- header {
20
- padding: 16px;
21
- background-color: #f5f5f5;
22
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
23
- font-size: 20px;
24
- font-weight: bold;
25
- text-align: center;
26
- }
27
- .recording-list {
28
- padding: 16px;
29
- }
30
- .record-item {
31
- display: flex;
32
- justify-content: space-between;
33
- align-items: center;
34
- padding: 12px;
35
- margin: 8px 0;
36
- border-radius: 8px;
37
- background-color: #e9e9e9;
38
- transition: background-color 0.2s ease;
39
- cursor: pointer;
40
- }
41
- .record-item:hover {
42
- background-color: #d3d3d3;
43
- }
44
- .title {
45
- font-size: 18px;
46
- font-weight: bold;
47
- }
48
- .timestamp {
49
- font-size: 14px;
50
- color: #555;
51
- }
52
- .record-item-template {
53
- display: none;
54
- }
55
- button {
56
- margin: 5px;
57
- padding: 10px 20px;
58
- border: none;
59
- border-radius: 4px; /* 4pxに統一 */
60
- background-color: #007bff;
61
- color: #fff;
62
- cursor: pointer;
63
- position: fixed; /* 画面に固定 */
64
- left: 50%; /* 水平方向の中央 */
65
- transform: translateX(-50%); /* 中央に配置 */
66
- bottom: 20px; /* 画面下に配置 */
67
- }
68
- .history-button:hover {
69
- background-color: #0056b3;
70
- }
71
- button:hover {
72
- background-color: #0056b3;
73
- }
74
- </style>
75
- <script>
76
- const recordings = [
77
- { title: "Recording 1", time: "01:15:35", date: "2/26/2025" },
78
- { title: "Recording 2", time: "00:16:41", date: "2/10/2025" },
79
- ];
80
-
81
- function createRecordItem(title, time, date) {
82
- const template = document.querySelector(".record-item-template");
83
- const item = template.cloneNode(true);
84
- item.classList.remove("record-item-template");
85
- item.style.display = "flex";
86
- item.querySelector(".title").textContent = title;
87
- item.querySelector(".timestamp").textContent = `${time} | ${date}`;
88
- item.onclick = () => (location.href = "talkDetail");
89
- return item;
90
- }
91
-
92
- function renderRecordings() {
93
- const list = document.querySelector(".recording-list");
94
- list.innerHTML = "";
95
- recordings.forEach((rec) => {
96
- const item = createRecordItem(rec.title, rec.time, rec.date);
97
- list.appendChild(item);
98
- });
99
- }
100
-
101
- window.onload = renderRecordings;
102
-
103
- //画面遷移
104
- function showRecorder() {
105
- // 録音画面へ遷移
106
- window.location.href = "/index";
107
- }
108
- </script>
109
- </head>
110
- <body>
111
- <header>All Recordings</header>
112
-
113
- <div class="recording-list">
114
- <div class="record-item record-item-template">
115
- <div>
116
- <div class="title">Recording Title</div>
117
- <div class="timestamp">00:00:00 | 1/1/2025</div>
118
- </div>
119
- </div>
120
- </div>
121
- <button class="history-button" id="detailButton" onclick="showRecorder()">
122
- 録音画面を表示
123
- </button>
124
- </body>
125
- </html>
 
1
+ <!DOCTYPE html>
2
+ <html lang="ja">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>会話履歴</title>
7
+ <link
8
+ href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
9
+ rel="stylesheet"
10
+ />
11
+ <style>
12
+ body {
13
+ margin: 0;
14
+ padding: 0;
15
+ font-family: Arial, sans-serif;
16
+ background-color: #fff;
17
+ color: #000;
18
+ }
19
+ header {
20
+ padding: 16px;
21
+ background-color: #f5f5f5;
22
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
23
+ font-size: 20px;
24
+ font-weight: bold;
25
+ text-align: center;
26
+ }
27
+ .recording-list {
28
+ padding: 16px;
29
+ }
30
+ .record-item {
31
+ display: flex;
32
+ justify-content: space-between;
33
+ align-items: center;
34
+ padding: 12px;
35
+ margin: 8px 0;
36
+ border-radius: 8px;
37
+ background-color: #e9e9e9;
38
+ transition: background-color 0.2s ease;
39
+ cursor: pointer;
40
+ }
41
+ .record-item:hover {
42
+ background-color: #d3d3d3;
43
+ }
44
+ .title {
45
+ font-size: 18px;
46
+ font-weight: bold;
47
+ }
48
+ .timestamp {
49
+ font-size: 14px;
50
+ color: #555;
51
+ }
52
+ .record-item-template {
53
+ display: none;
54
+ }
55
+ button {
56
+ margin: 5px;
57
+ padding: 10px 20px;
58
+ border: none;
59
+ border-radius: 4px; /* 4pxに統一 */
60
+ background-color: #007bff;
61
+ color: #fff;
62
+ cursor: pointer;
63
+ position: fixed; /* 画面に固定 */
64
+ left: 50%; /* 水平方向の中央 */
65
+ transform: translateX(-50%); /* 中央に配置 */
66
+ bottom: 20px; /* 画面下に配置 */
67
+ }
68
+ .history-button:hover {
69
+ background-color: #0056b3;
70
+ }
71
+ button:hover {
72
+ background-color: #0056b3;
73
+ }
74
+ </style>
75
+ <script>
76
+ const recordings = [
77
+ { title: "Recording 1", time: "01:15:35", date: "2/26/2025" },
78
+ { title: "Recording 2", time: "00:16:41", date: "2/10/2025" },
79
+ ];
80
+
81
+ function createRecordItem(title, time, date) {
82
+ const template = document.querySelector(".record-item-template");
83
+ const item = template.cloneNode(true);
84
+ item.classList.remove("record-item-template");
85
+ item.style.display = "flex";
86
+ item.querySelector(".title").textContent = title;
87
+ item.querySelector(".timestamp").textContent = `${time} | ${date}`;
88
+ item.onclick = () => (location.href = "talkDetail");
89
+ return item;
90
+ }
91
+
92
+ function renderRecordings() {
93
+ const list = document.querySelector(".recording-list");
94
+ list.innerHTML = "";
95
+ recordings.forEach((rec) => {
96
+ const item = createRecordItem(rec.title, rec.time, rec.date);
97
+ list.appendChild(item);
98
+ });
99
+ }
100
+
101
+ window.onload = renderRecordings;
102
+
103
+ //画面遷移
104
+ function showRecorder() {
105
+ // 録音画面へ遷移
106
+ window.location.href = "/index";
107
+ }
108
+ </script>
109
+ </head>
110
+ <body>
111
+ <header>All Recordings</header>
112
+
113
+ <div class="recording-list">
114
+ <div class="record-item record-item-template">
115
+ <div>
116
+ <div class="title">Recording Title</div>
117
+ <div class="timestamp">00:00:00 | 1/1/2025</div>
118
+ </div>
119
+ </div>
120
+ </div>
121
+ <button class="history-button" id="detailButton" onclick="showRecorder()">
122
+ 録音画面を表示
123
+ </button>
124
+ </body>
125
+ </html>
templates/index.html CHANGED
@@ -1,268 +1,296 @@
1
- <!DOCTYPE html>
2
- <html lang="ja">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>Voice Recorder Interface</title>
7
- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
8
- <script src="https://cdn.tailwindcss.com"></script>
9
- </head>
10
- <body
11
- class="flex flex-col items-center justify-center h-screen bg-gray-900 text-white"
12
- >
13
- <!-- メンバーを登録ボタン -->
14
- <div class="flex items-center mb-5">
15
- <button
16
- id="registerButton"
17
- onclick="showUserRegister()"
18
- class="px-4 py-2 bg-blue-600 rounded-md hover:bg-blue-700 transition"
19
- >
20
- メンバーを登録
21
- </button>
22
- </div>
23
-
24
- <!-- チャート表示部 -->
25
- <div class="chart w-72 h-72 mb-5">
26
- <canvas id="speechChart"></canvas>
27
- </div>
28
- <form
29
- id="recordForm"
30
- action="/submit"
31
- method="POST"
32
- class="flex items-center space-x-2 w-full sm:w-auto"
33
- onsubmit="event.preventDefault();"
34
- >
35
- <input
36
- type="text"
37
- name="name"
38
- placeholder="名前を入力"
39
- class="flex-1 px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 bg-gray-700 text-white"
40
- />
41
- <!-- 録音ボタン -->
42
- <button
43
- type="button"
44
- class="record-button"
45
- id="recordButton"
46
- onclick="toggleRecording()"
47
- >
48
- <div class="record-icon" id="recordIcon"></div>
49
- </button>
50
- </form>
51
- <!-- 名前入力 -->
52
-
53
- <!-- 結果ボタン -->
54
- <div class="flex mt-5">
55
- <button
56
- id="historyButton"
57
- onclick="showTalkdetail()"
58
- class="result-button px-4 py-2 mx-2 bg-green-600 rounded-md hover:bg-green-700 transition"
59
- >
60
- 会話履歴を表示
61
- </button>
62
- <button
63
- id="feedbackButton"
64
- onclick="showResults()"
65
- class="result-button px-4 py-2 mx-2 bg-blue-600 rounded-md hover:bg-blue-700 transition"
66
- >
67
- フィードバック画面を表示
68
- </button>
69
- </div>
70
-
71
- <style>
72
- .record-button {
73
- width: 80px;
74
- height: 80px;
75
- background-color: transparent;
76
- border-radius: 50%;
77
- border: 4px solid white;
78
- display: flex;
79
- justify-content: center;
80
- align-items: center;
81
- cursor: pointer;
82
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.4);
83
- transition: all 0.2s ease;
84
- }
85
-
86
- .record-icon {
87
- width: 60px;
88
- height: 60px;
89
- background-color: #d32f2f;
90
- border-radius: 50%;
91
- transition: all 0.2s ease;
92
- }
93
-
94
- .recording .record-icon {
95
- width: 40px;
96
- height: 40px;
97
- border-radius: 10%;
98
- }
99
- </style>
100
-
101
- <script>
102
- let isRecording = false;
103
- let mediaRecorder;
104
- let audioChunks = [];
105
- let recordingInterval;
106
- let count_voice = 0;
107
- let before_rate = 0;
108
-
109
- // 初期設定:人数と名前を受け取って円グラフを作成
110
- let members = ["aaa", "bbb", "ccc", "その他"];
111
-
112
- let voiceData = [50, 20, 20, 10]; // 自分と不明の割合を仮設定
113
-
114
- // Chart.js の初期化
115
- const ctx = document.getElementById("speechChart").getContext("2d");
116
- const speechChart = new Chart(ctx, {
117
- type: "doughnut",
118
- data: {
119
- labels: members,
120
- datasets: [
121
- {
122
- data: voiceData,
123
- backgroundColor: ["#4caf50", "#757575"],
124
- },
125
- ],
126
- },
127
- options: {
128
- responsive: true,
129
- plugins: {
130
- legend: {
131
- display: true,
132
- position: "bottom",
133
- labels: { color: "white" },
134
- },
135
- },
136
- },
137
- });
138
-
139
- //録音ボタン見た目変化
140
- function toggleRecording() {
141
- isRecording = !isRecording;
142
- const recordIcon = document.getElementById("recordIcon");
143
- if (isRecording) {
144
- recordIcon.classList.add("w-10", "h-10", "bg-red-900", "rounded-md");
145
- } else {
146
- recordIcon.classList.remove(
147
- "w-10",
148
- "h-10",
149
- "bg-red-900",
150
- "rounded-md"
151
- );
152
- }
153
- }
154
-
155
- async function toggleRecording() {
156
- const recordButton = document.getElementById("recordButton");
157
-
158
- if (!isRecording) {
159
- // 録音開始
160
- isRecording = true;
161
- recordButton.classList.add("recording");
162
- try {
163
- const stream = await navigator.mediaDevices.getUserMedia({
164
- audio: true,
165
- });
166
- mediaRecorder = new MediaRecorder(stream);
167
- audioChunks = [];
168
-
169
- mediaRecorder.ondataavailable = (event) => {
170
- if (event.data.size > 0) {
171
- audioChunks.push(event.data);
172
- }
173
- };
174
-
175
- mediaRecorder.onstop = () => {
176
- sendAudioChunks([...audioChunks]);
177
- audioChunks = [];
178
- };
179
-
180
- mediaRecorder.start();
181
- } catch (error) {
182
- console.error("マイクへのアクセスに失敗しました:", error);
183
- isRecording = false;
184
- recordButton.classList.remove("recording");
185
- }
186
- } else {
187
- // 手動停止
188
- isRecording = false;
189
- recordButton.classList.remove("recording");
190
- if (mediaRecorder && mediaRecorder.state === "recording") {
191
- mediaRecorder.stop();
192
- count_voice = 0;
193
- before_rate = 0;
194
- }
195
- }
196
- }
197
-
198
- function sendAudioChunks(chunks) {
199
- const audioBlob = new Blob(chunks, { type: "audio/wav" });
200
- const reader = new FileReader();
201
- reader.onloadend = () => {
202
- const base64String = reader.result.split(",")[1]; // Base64エンコードされた音声データ
203
- // フォーム要素を取得
204
- const form = document.getElementById("recordForm");
205
- const nameInput = form.querySelector('input[name="name"]');
206
- const name = nameInput ? nameInput.value : "unknown"; // 名前がない
207
- fetch("/upload_audio", {
208
- method: "POST",
209
- headers: {
210
- "Content-Type": "application/json",
211
- },
212
- body: JSON.stringify({ audio_data: base64String, name: name }),
213
- })
214
- .then((response) => response.json())
215
- .then((data) => {
216
- if (data.error) {
217
- alert("エラー: " + data.error);
218
- console.error(data.details);
219
- } else if (data.rate !== undefined) {
220
- // 通常モードの場合、解析結果をチャートに反映
221
- if (count_voice === 0) {
222
- speechChart.data.datasets[0].data = [
223
- data.rate,
224
- 100 - data.rate,
225
- ];
226
- before_rate = data.rate;
227
- } else if (count_voice === 1) {
228
- let tmp_rate = (data.rate + before_rate) / 2;
229
- speechChart.data.datasets[0].data = [
230
- tmp_rate,
231
- 100 - tmp_rate,
232
- ];
233
- before_rate = tmp_rate;
234
- } else {
235
- let tmp_rate = (data.rate + before_rate * 2) / 3;
236
- speechChart.data.datasets[0].data = [
237
- tmp_rate,
238
- 100 - tmp_rate,
239
- ];
240
- before_rate = tmp_rate;
241
- }
242
- count_voice++;
243
- speechChart.update();
244
- }
245
- })
246
- .catch((error) => {
247
- console.error("エラー:", error);
248
- });
249
- };
250
- reader.readAsDataURL(audioBlob);
251
- }
252
-
253
- function showTalkdetail() {
254
- window.location.href = "talk_detail";
255
- }
256
-
257
- function showResults() {
258
- // フィードバック画面へ遷移
259
- window.location.href = "feedback";
260
- }
261
-
262
- function showUserRegister() {
263
- // 音声登録画面へ遷移
264
- window.location.href = "userregister";
265
- }
266
- </script>
267
- </body>
268
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="ja">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Voice Recorder Interface</title>
7
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ </head>
10
+ <body class="flex flex-col items-center justify-center h-screen bg-gray-900 text-white">
11
+ <!-- メンバーを登録ボタン -->
12
+ <div class="flex items-center mb-5">
13
+ <button
14
+ id="registerButton"
15
+ onclick="showUserRegister()"
16
+ class="px-4 py-2 bg-blue-600 rounded-md hover:bg-blue-700 transition"
17
+ >
18
+ メンバーを登録
19
+ </button>
20
+ </div>
21
+
22
+ <!-- チャート表示部 -->
23
+ <div class="chart w-72 h-72 mb-5">
24
+ <canvas id="speechChart"></canvas>
25
+ </div>
26
+
27
+ <!-- 録音フォーム -->
28
+ <form
29
+ id="recordForm"
30
+ action="/submit"
31
+ method="POST"
32
+ class="flex items-center space-x-2 w-full sm:w-auto"
33
+ onsubmit="event.preventDefault();"
34
+ >
35
+ <input
36
+ type="text"
37
+ name="name"
38
+ placeholder="名前を入力"
39
+ class="flex-1 px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 bg-gray-700 text-white"
40
+ />
41
+ <!-- 録音ボタン -->
42
+ <button type="button" class="record-button" id="recordButton" onclick="toggleRecording()">
43
+ <div class="record-icon" id="recordIcon"></div>
44
+ </button>
45
+ </form>
46
+
47
+ <!-- 結果ボタン -->
48
+ <div class="flex mt-5">
49
+ <button
50
+ id="historyButton"
51
+ onclick="showTalkdetail()"
52
+ class="result-button px-4 py-2 mx-2 bg-green-600 rounded-md hover:bg-green-700 transition"
53
+ >
54
+ 会話履歴を表示
55
+ </button>
56
+ <button
57
+ id="feedbackButton"
58
+ onclick="showResults()"
59
+ class="result-button px-4 py-2 mx-2 bg-blue-600 rounded-md hover:bg-blue-700 transition"
60
+ >
61
+ フィードバック画面を表示
62
+ </button>
63
+ </div>
64
+
65
+ <style>
66
+ .record-button {
67
+ width: 80px;
68
+ height: 80px;
69
+ background-color: transparent;
70
+ border-radius: 50%;
71
+ border: 4px solid white;
72
+ display: flex;
73
+ justify-content: center;
74
+ align-items: center;
75
+ cursor: pointer;
76
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.4);
77
+ transition: all 0.2s ease;
78
+ }
79
+ .record-icon {
80
+ width: 60px;
81
+ height: 60px;
82
+ background-color: #d32f2f;
83
+ border-radius: 50%;
84
+ transition: all 0.2s ease;
85
+ }
86
+ .recording .record-icon {
87
+ width: 40px;
88
+ height: 40px;
89
+ border-radius: 10%;
90
+ }
91
+ </style>
92
+
93
+ <script>
94
+ let isRecording = false;
95
+ let mediaRecorder;
96
+ let audioChunks = [];
97
+ let recordingInterval;
98
+ let count_voice = 0;
99
+ let before_rate = 0;
100
+
101
+ // メンバーとチャートの初期化
102
+ let members = [];
103
+ let voiceData = [];
104
+ let baseMemberColors = ["#4caf50", "#007bff", "#ffc107", "#dc3545", "#28a745", "#9c27b0", "#ff9800"];
105
+
106
+ // Chart.js の初期化
107
+ const ctx = document.getElementById("speechChart").getContext("2d");
108
+ const speechChart = new Chart(ctx, {
109
+ type: "doughnut",
110
+ data: {
111
+ labels: members,
112
+ datasets: [
113
+ {
114
+ data: voiceData,
115
+ backgroundColor: getMemberColors(members.length),
116
+ },
117
+ ],
118
+ },
119
+ options: {
120
+ responsive: true,
121
+ plugins: {
122
+ legend: {
123
+ display: true,
124
+ position: "bottom",
125
+ labels: { color: "white" },
126
+ },
127
+ },
128
+ },
129
+ });
130
+
131
+ // サーバーからメンバー情報を取得してチャートを更新する関数
132
+ async function updateChartFrom() {
133
+ try {
134
+ const response = await fetch("/confirm");
135
+ if (!response.ok) {
136
+ throw new Error(`HTTP error! status: ${response.status}`);
137
+ }
138
+ const data = await response.json();
139
+
140
+ if (!data || !data.members || !Array.isArray(data.members)) {
141
+ console.error("Invalid member data received:", data);
142
+ members = ["member1", "member2"];
143
+ voiceData = [50, 50];
144
+ if (members.length > 1) {
145
+ members.push("その他");
146
+ voiceData.push(0);
147
+ }
148
+ updateChart();
149
+ return;
150
+ }
151
+
152
+ members = data.members;
153
+ voiceData = [];
154
+ for (let i = 0; i < members.length; i++) {
155
+ voiceData.push(100 / members.length);
156
+ }
157
+
158
+ updateChart();
159
+ } catch (error) {
160
+ console.error("Failed to fetch member data:", error);
161
+ members = ["member1", "member2"];
162
+ voiceData = [50, 50];
163
+ if (members.length > 1) {
164
+ members.push("その他");
165
+ voiceData.push(0);
166
+ }
167
+ updateChart();
168
+ }
169
+ }
170
+
171
+ function updateChart() {
172
+ speechChart.data.labels = members;
173
+ speechChart.data.datasets[0].data = voiceData;
174
+ speechChart.data.datasets[0].backgroundColor = getMemberColors(members.length);
175
+ speechChart.update();
176
+ }
177
+
178
+ // ページ読み込み時にチャート情報を更新
179
+ updateChartFrom();
180
+
181
+ // 録音ボタンの録音開始/停止処理
182
+ async function toggleRecording() {
183
+ const recordButton = document.getElementById("recordButton");
184
+
185
+ if (!isRecording) {
186
+ // 録音開始
187
+ isRecording = true;
188
+ recordButton.classList.add("recording");
189
+ try {
190
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
191
+ mediaRecorder = new MediaRecorder(stream);
192
+ audioChunks = [];
193
+
194
+ mediaRecorder.ondataavailable = (event) => {
195
+ if (event.data.size > 0) {
196
+ audioChunks.push(event.data);
197
+ }
198
+ };
199
+
200
+ mediaRecorder.onstop = () => {
201
+ sendAudioChunks([...audioChunks]);
202
+ audioChunks = [];
203
+ };
204
+
205
+ mediaRecorder.start();
206
+ } catch (error) {
207
+ console.error("マイクへのアクセスに失敗しました:", error);
208
+ isRecording = false;
209
+ recordButton.classList.remove("recording");
210
+ }
211
+ } else {
212
+ // 録音停止
213
+ isRecording = false;
214
+ recordButton.classList.remove("recording");
215
+ if (mediaRecorder && mediaRecorder.state === "recording") {
216
+ mediaRecorder.stop();
217
+ count_voice = 0;
218
+ before_rate = 0;
219
+ }
220
+ }
221
+ }
222
+
223
+ function sendAudioChunks(chunks) {
224
+ const audioBlob = new Blob(chunks, { type: "audio/wav" });
225
+ const reader = new FileReader();
226
+ reader.onloadend = () => {
227
+ const base64String = reader.result.split(",")[1];
228
+ const form = document.getElementById("recordForm");
229
+ const nameInput = form.querySelector('input[name="name"]');
230
+ const name = nameInput ? nameInput.value : "unknown";
231
+ fetch("/upload_audio", {
232
+ method: "POST",
233
+ headers: { "Content-Type": "application/json" },
234
+ body: JSON.stringify({ audio_data: base64String, name: name }),
235
+ })
236
+ .then((response) => response.json())
237
+ .then((data) => {
238
+ if (data.error) {
239
+ alert("エラー: " + data.error);
240
+ console.error(data.details);
241
+ } else if (data.rate !== undefined) {
242
+ updateChartData(data.rate);
243
+ }
244
+ })
245
+ .catch((error) => {
246
+ console.error("エラー:", error);
247
+ });
248
+ };
249
+ reader.readAsDataURL(audioBlob);
250
+ }
251
+
252
+ function getMemberColors(memberCount) {
253
+ if (memberCount === 2) {
254
+ return ["#4caf50", "#757575"];
255
+ } else {
256
+ let colors = [];
257
+ for (let i = 0; i < memberCount; i++) {
258
+ colors.push(baseMemberColors[i % baseMemberColors.length]);
259
+ }
260
+ return colors;
261
+ }
262
+ }
263
+
264
+ function updateChartData(newRate) {
265
+ if (count_voice === 0) {
266
+ speechChart.data.datasets[0].data = [newRate, 100 - newRate];
267
+ before_rate = newRate;
268
+ } else if (count_voice === 1) {
269
+ let tmp_rate = (newRate + before_rate) / 2;
270
+ speechChart.data.datasets[0].data = [tmp_rate, 100 - tmp_rate];
271
+ before_rate = tmp_rate;
272
+ } else {
273
+ let tmp_rate = (newRate + before_rate * 2) / 3;
274
+ speechChart.data.datasets[0].data = [tmp_rate, 100 - tmp_rate];
275
+ before_rate = tmp_rate;
276
+ }
277
+ count_voice++;
278
+ speechChart.data.datasets[0].backgroundColor = getMemberColors(members.length);
279
+ speechChart.update();
280
+ }
281
+
282
+ function showTalkdetail() {
283
+ window.location.href = "talk_detail";
284
+ }
285
+
286
+ function showResults() {
287
+ window.location.href = "feedback";
288
+ }
289
+
290
+ function showUserRegister() {
291
+ fetch("/reset");
292
+ window.location.href = "userregister";
293
+ }
294
+ </script>
295
+ </body>
296
+ </html>
templates/talkDetail.html CHANGED
@@ -1,156 +1,156 @@
1
- <!DOCTYPE html>
2
- <html lang="ja">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>会話詳細画面</title>
7
- <link
8
- href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
9
- rel="stylesheet"
10
- />
11
- <style>
12
- body {
13
- font-family: Arial, sans-serif;
14
- margin: 0;
15
- padding: 20px;
16
- background-color: #f4f4f4;
17
- height: 100vh;
18
- display: flex;
19
- justify-content: center;
20
- align-items: center;
21
- }
22
- .container {
23
- max-width: 800px;
24
- background-color: #fff;
25
- padding: 20px;
26
- border-radius: 8px;
27
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
28
- }
29
- h2 {
30
- margin-bottom: 20px;
31
- }
32
- #transcription {
33
- white-space: pre-wrap;
34
- padding: 10px;
35
- background-color: #e9e9e9;
36
- border-radius: 4px;
37
- margin-bottom: 20px;
38
- max-height: 400px;
39
- overflow-y: auto;
40
- }
41
- button {
42
- margin: 5px;
43
- padding: 10px 20px;
44
- border: none;
45
- border-radius: 4px;
46
- background-color: #007bff;
47
- color: #fff;
48
- cursor: pointer;
49
- }
50
- .history-button {
51
- margin-top: 20px;
52
- margin-left: 20px;
53
- padding: 10px 20px;
54
- background-color: #007bff;
55
- color: white;
56
- border: none;
57
- border-radius: 5px;
58
- cursor: pointer;
59
- }
60
- history-button:hover {
61
- background-color: #0056b3;
62
- }
63
- button:hover {
64
- background-color: #0056b3;
65
- }
66
- .flex {
67
- display: flex;
68
- justify-content: center;
69
- }
70
- </style>
71
- </head>
72
- <body>
73
- <div class="container">
74
- <h2>会話の文字起こし表示</h2>
75
- <div id="transcription">ここに会話内容が表示されます。</div>
76
- <div class="flex">
77
- <button
78
- class="history-button"
79
- id="detailButton"
80
- onclick="showRecorder()"
81
- >
82
- 録音画面を表示
83
- </button>
84
- <button
85
- class="history-button"
86
- id="detailButton"
87
- onclick="showFeedback()"
88
- >
89
- フィードバック画面を表示
90
- </button>
91
- <!--
92
- <form method="POST" action="/index">
93
- <div class="feedback-space">
94
- <input
95
- class="history-button"
96
- id="indexButton"
97
- type="submit"
98
- name="submit"
99
- value="録音画面を表示"
100
- />
101
- </div>
102
- </form>
103
-
104
- <form method="POST" action="/feedback">
105
- <div class="feedback-space">
106
- <input
107
- class="history-button"
108
- id="feedbackButton"
109
- type="submit"
110
- name="submit"
111
- value="フィードバック画面を表示"
112
- />
113
- </div>
114
- </form>-->
115
- </div>
116
- </div>
117
-
118
- <script>
119
- // 会話データを表示
120
- async function displayTranscription() {
121
- const transcriptionElement = document.getElementById("transcription");
122
-
123
- try {
124
- // バックエンドからデータを取得(デモ用のURLを指定)
125
- const response = await fetch("/api/transcription");
126
- if (!response.ok) throw new Error("データ取得に失敗しました。");
127
-
128
- const data = await response.json();
129
-
130
- // 会話内容を整形して表示
131
- const formattedText = data.conversations
132
- .map((conv, index) => `【${conv.speaker}】 ${conv.text}`)
133
- .join("\n");
134
-
135
- transcriptionElement.textContent = formattedText;
136
- } catch (error) {
137
- transcriptionElement.textContent = `エラー: ${error.message}`;
138
- console.error("データ取得エラー:", error);
139
- }
140
- }
141
-
142
- // 初期化処理
143
- displayTranscription();
144
-
145
- //画面遷移
146
- function showRecorder() {
147
- // 録音画面へ遷移
148
- window.location.href = "/index";
149
- }
150
- function showFeedback() {
151
- // フィードバック画面へ遷移
152
- window.location.href = "/feedback";
153
- }
154
- </script>
155
- </body>
156
- </html>
 
1
+ <!DOCTYPE html>
2
+ <html lang="ja">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>会話詳細画面</title>
7
+ <link
8
+ href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
9
+ rel="stylesheet"
10
+ />
11
+ <style>
12
+ body {
13
+ font-family: Arial, sans-serif;
14
+ margin: 0;
15
+ padding: 20px;
16
+ background-color: #f4f4f4;
17
+ height: 100vh;
18
+ display: flex;
19
+ justify-content: center;
20
+ align-items: center;
21
+ }
22
+ .container {
23
+ max-width: 800px;
24
+ background-color: #fff;
25
+ padding: 20px;
26
+ border-radius: 8px;
27
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
28
+ }
29
+ h2 {
30
+ margin-bottom: 20px;
31
+ }
32
+ #transcription {
33
+ white-space: pre-wrap;
34
+ padding: 10px;
35
+ background-color: #e9e9e9;
36
+ border-radius: 4px;
37
+ margin-bottom: 20px;
38
+ max-height: 400px;
39
+ overflow-y: auto;
40
+ }
41
+ button {
42
+ margin: 5px;
43
+ padding: 10px 20px;
44
+ border: none;
45
+ border-radius: 4px;
46
+ background-color: #007bff;
47
+ color: #fff;
48
+ cursor: pointer;
49
+ }
50
+ .history-button {
51
+ margin-top: 20px;
52
+ margin-left: 20px;
53
+ padding: 10px 20px;
54
+ background-color: #007bff;
55
+ color: white;
56
+ border: none;
57
+ border-radius: 5px;
58
+ cursor: pointer;
59
+ }
60
+ history-button:hover {
61
+ background-color: #0056b3;
62
+ }
63
+ button:hover {
64
+ background-color: #0056b3;
65
+ }
66
+ .flex {
67
+ display: flex;
68
+ justify-content: center;
69
+ }
70
+ </style>
71
+ </head>
72
+ <body>
73
+ <div class="container">
74
+ <h2>会話の文字起こし表示</h2>
75
+ <div id="transcription">ここに会話内容が表示されます。</div>
76
+ <div class="flex">
77
+ <button
78
+ class="history-button"
79
+ id="detailButton"
80
+ onclick="showRecorder()"
81
+ >
82
+ 録音画面を表示
83
+ </button>
84
+ <button
85
+ class="history-button"
86
+ id="detailButton"
87
+ onclick="showFeedback()"
88
+ >
89
+ フィードバック画面を表示
90
+ </button>
91
+ <!--
92
+ <form method="POST" action="/index">
93
+ <div class="feedback-space">
94
+ <input
95
+ class="history-button"
96
+ id="indexButton"
97
+ type="submit"
98
+ name="submit"
99
+ value="録音画面を表示"
100
+ />
101
+ </div>
102
+ </form>
103
+
104
+ <form method="POST" action="/feedback">
105
+ <div class="feedback-space">
106
+ <input
107
+ class="history-button"
108
+ id="feedbackButton"
109
+ type="submit"
110
+ name="submit"
111
+ value="フィードバック画面を表示"
112
+ />
113
+ </div>
114
+ </form>-->
115
+ </div>
116
+ </div>
117
+
118
+ <script>
119
+ // 会話データを表示
120
+ async function displayTranscription() {
121
+ const transcriptionElement = document.getElementById("transcription");
122
+
123
+ try {
124
+ // バックエンドからデータを取得(デモ用のURLを指定)
125
+ const response = await fetch("/api/transcription");
126
+ if (!response.ok) throw new Error("データ取得に失敗しました。");
127
+
128
+ const data = await response.json();
129
+
130
+ // 会話内容を整形して表示
131
+ const formattedText = data.conversations
132
+ .map((conv, index) => `【${conv.speaker}】 ${conv.text}`)
133
+ .join("\n");
134
+
135
+ transcriptionElement.textContent = formattedText;
136
+ } catch (error) {
137
+ transcriptionElement.textContent = `エラー: ${error.message}`;
138
+ console.error("データ取得エラー:", error);
139
+ }
140
+ }
141
+
142
+ // 初期化処理
143
+ displayTranscription();
144
+
145
+ //画面遷移
146
+ function showRecorder() {
147
+ // 録音画面へ遷移
148
+ window.location.href = "/index";
149
+ }
150
+ function showFeedback() {
151
+ // フィードバック画面へ遷移
152
+ window.location.href = "/feedback";
153
+ }
154
+ </script>
155
+ </body>
156
+ </html>
templates/userRegister.html CHANGED
@@ -1,85 +1,90 @@
1
- <!DOCTYPE html>
2
- <html lang="ja">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>ユーザー音声登録</title>
6
- <script src="https://cdn.tailwindcss.com"></script>
7
- <style>
8
- @keyframes pulse-scale {
9
- 0%,
10
- 100% {
11
- transform: scale(1);
12
- }
13
- 50% {
14
- transform: scale(1.1);
15
- }
16
- }
17
- .animate-pulse-scale {
18
- animation: pulse-scale 1s infinite;
19
- }
20
- .record-button {
21
- width: 50px;
22
- height: 50px;
23
- background-color: transparent;
24
- border-radius: 50%;
25
- border: 2px solid white;
26
- display: flex;
27
- justify-content: center;
28
- align-items: center;
29
- cursor: pointer;
30
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.4);
31
- transition: all 0.3s ease;
32
- }
33
- .record-icon {
34
- width: 35px;
35
- height: 35px;
36
- background-color: #d32f2f;
37
- border-radius: 50%;
38
- transition: all 0.3s ease;
39
- }
40
- .record-button.recording .record-icon {
41
- border-radius: 4px; /* 録音時に赤い部分だけ四角にする */
42
- }
43
- .recording .record-icon {
44
- width: 20px;
45
- height: 20px;
46
- border-radius: 50%;
47
- }
48
- @media (max-width: 640px) {
49
- .container {
50
- padding: 2rem;
51
- }
52
- }
53
- </style>
54
- </head>
55
- <body
56
- class="bg-gray-800 text-gray-100 dark:bg-gray-900 dark:text-gray-300 transition-colors"
57
- >
58
- <div class="container mx-auto p-5 max-w-full sm:max-w-2xl">
59
- <div id="people-list" class="space-y-4"></div>
60
- <button
61
- id="add-btn"
62
- class="mt-6 px-6 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition-colors"
63
- >
64
- メンバーを追加
65
- </button>
66
-
67
- <!-- 録音画面に戻るボタン -->
68
- <button
69
- id="backButton"
70
- onclick="showRecorder()"
71
- class="mt-6 px-6 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors"
72
- >
73
- 録音画面に戻る
74
- </button>
75
- </div>
76
-
77
- <script src="{{ url_for('static', filename='register_record.js') }}"></script>
78
- <script>
79
- function showRecorder() {
80
- // 録音画面へ遷移
81
- window.location.href = "index";
82
- }
83
- </script>
84
- </body>
85
- </html>
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="ja">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <title>ユーザー音声登録</title>
6
+ <script src="https://cdn.tailwindcss.com"></script>
7
+ <style>
8
+ @keyframes pulse-scale {
9
+ 0%,
10
+ 100% {
11
+ transform: scale(1);
12
+ }
13
+ 50% {
14
+ transform: scale(1.1);
15
+ }
16
+ }
17
+ .animate-pulse-scale {
18
+ animation: pulse-scale 1s infinite;
19
+ }
20
+ .record-button {
21
+ width: 50px;
22
+ height: 50px;
23
+ background-color: transparent;
24
+ border-radius: 50%;
25
+ border: 2px solid white;
26
+ display: flex;
27
+ justify-content: center;
28
+ align-items: center;
29
+ cursor: pointer;
30
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.4);
31
+ transition: all 0.3s ease;
32
+ }
33
+ .record-icon {
34
+ width: 35px;
35
+ height: 35px;
36
+ background-color: #d32f2f;
37
+ border-radius: 50%;
38
+ transition: all 0.3s ease;
39
+ }
40
+ .record-button.recording .record-icon {
41
+ border-radius: 4px; /* 録音時に赤い部分だけ四角にする */
42
+ }
43
+ .recording .record-icon {
44
+ width: 20px;
45
+ height: 20px;
46
+ border-radius: 50%;
47
+ }
48
+ @media (max-width: 640px) {
49
+ .container {
50
+ padding: 2rem;
51
+ }
52
+ }
53
+ </style>
54
+ </head>
55
+ <body
56
+ class="bg-gray-800 text-gray-100 dark:bg-gray-900 dark:text-gray-300 transition-colors"
57
+ >
58
+ <div class="container mx-auto p-5 max-w-full sm:max-w-2xl">
59
+ <div id="people-list" class="space-y-4"></div>
60
+ <button
61
+ id="add-btn"
62
+ class="mt-6 px-6 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition-colors"
63
+ >
64
+ メンバーを追加
65
+ </button>
66
+
67
+ <!-- 録音画面に戻るボタン -->
68
+ <button
69
+ id="backButton"
70
+ onclick="showRecorder()"
71
+ class="mt-6 px-6 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors"
72
+ >
73
+ 録音画面に戻る
74
+ </button>
75
+ </div>
76
+
77
+ <script src="{{ url_for('static', filename='register_record.js') }}"></script>
78
+ <script>
79
+ function showRecorder() {
80
+ // 録音画面へ遷移
81
+ window.location.href = "index";
82
+ }
83
+ </script>
84
+ <script>
85
+
86
+
87
+
88
+ </script>
89
+ </body>
90
+ </html>