ask-user-question-plus 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/ws-service.js +5 -0
- package/package.json +1 -1
- package/public/index.html +63 -3
package/README.md
CHANGED
|
@@ -60,6 +60,9 @@ pm2 start "npx ask-user-question-plus -- --port=3456 --timeout=600000" --name as
|
|
|
60
60
|
|
|
61
61
|
# 停止服务
|
|
62
62
|
pm2 stop ask-user-question-plus-service
|
|
63
|
+
|
|
64
|
+
# Windows
|
|
65
|
+
pm2 start cmd --name ask-user-question-plus-service -- /c npx ask-user-question-plus
|
|
63
66
|
```
|
|
64
67
|
|
|
65
68
|
#### 使用 Docker
|
|
@@ -268,6 +271,9 @@ pm2 start "npx ask-user-question-plus -- --port=3456 --timeout=600000" --name as
|
|
|
268
271
|
|
|
269
272
|
# Stop service
|
|
270
273
|
pm2 stop ask-user-question-plus-service
|
|
274
|
+
|
|
275
|
+
# Windows
|
|
276
|
+
pm2 start cmd --name ask-user-question-plus-service -- /c npx ask-user-question-plu
|
|
271
277
|
```
|
|
272
278
|
|
|
273
279
|
#### Using Docker
|
package/dist/ws-service.js
CHANGED
|
@@ -39,6 +39,11 @@ export class WebSocketService {
|
|
|
39
39
|
clearTimeout(session.timeout);
|
|
40
40
|
session.timeout = null;
|
|
41
41
|
}
|
|
42
|
+
// Send session meta first so the client can start countdown when it receives NEW_QUESTION.
|
|
43
|
+
this.sendMessage(ws, {
|
|
44
|
+
type: "SESSION_META",
|
|
45
|
+
payload: { timeoutMs: this.sessionTimeoutMs },
|
|
46
|
+
});
|
|
42
47
|
// Send questions to client
|
|
43
48
|
this.sendMessage(ws, {
|
|
44
49
|
type: "NEW_QUESTION",
|
package/package.json
CHANGED
package/public/index.html
CHANGED
|
@@ -601,11 +601,57 @@
|
|
|
601
601
|
let activeReviewIndex = 0;
|
|
602
602
|
let shouldFocusOther = false;
|
|
603
603
|
let ws = null;
|
|
604
|
+
let sessionTimeoutMs = null;
|
|
605
|
+
let countdownInterval = null;
|
|
606
|
+
let countdownEndsAt = null;
|
|
607
|
+
let hasReceivedQuestions = false;
|
|
604
608
|
let sessionId =
|
|
605
609
|
new URLSearchParams(window.location.search).get("sessionId") ||
|
|
606
610
|
"default";
|
|
607
611
|
const isMac = /Mac|iPod|iPhone|iPad/.test(navigator.platform);
|
|
608
612
|
|
|
613
|
+
function formatMmSs(ms) {
|
|
614
|
+
const totalSeconds = Math.max(0, Math.floor(ms / 1000));
|
|
615
|
+
const minutes = String(Math.floor(totalSeconds / 60)).padStart(2, "0");
|
|
616
|
+
const seconds = String(totalSeconds % 60).padStart(2, "0");
|
|
617
|
+
return `${minutes}:${seconds}`;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
function setSessionInfo(statusText) {
|
|
621
|
+
document.getElementById("session-info").textContent = statusText;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
function setSessionInfoConnected() {
|
|
625
|
+
const base = `Session: ${sessionId} (Connected)`;
|
|
626
|
+
if (countdownEndsAt) {
|
|
627
|
+
const remaining = countdownEndsAt - Date.now();
|
|
628
|
+
setSessionInfo(`${base} | Timeout in ${formatMmSs(remaining)}`);
|
|
629
|
+
} else {
|
|
630
|
+
setSessionInfo(base);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
function stopCountdown() {
|
|
635
|
+
if (countdownInterval) {
|
|
636
|
+
clearInterval(countdownInterval);
|
|
637
|
+
countdownInterval = null;
|
|
638
|
+
}
|
|
639
|
+
countdownEndsAt = null;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
function startCountdown(timeoutMs) {
|
|
643
|
+
stopCountdown();
|
|
644
|
+
countdownEndsAt = Date.now() + timeoutMs;
|
|
645
|
+
|
|
646
|
+
// Tick immediately to avoid showing stale text for up to 1s.
|
|
647
|
+
setSessionInfoConnected();
|
|
648
|
+
countdownInterval = setInterval(() => {
|
|
649
|
+
const remaining = countdownEndsAt - Date.now();
|
|
650
|
+
setSessionInfoConnected();
|
|
651
|
+
if (remaining <= 0) stopCountdown();
|
|
652
|
+
}, 1000);
|
|
653
|
+
}
|
|
654
|
+
|
|
609
655
|
// --- WebSocket Logic ---
|
|
610
656
|
function connectWS() {
|
|
611
657
|
// Robust WS URL construction
|
|
@@ -628,9 +674,7 @@
|
|
|
628
674
|
|
|
629
675
|
ws.onopen = () => {
|
|
630
676
|
console.error("WS Open");
|
|
631
|
-
|
|
632
|
-
"session-info"
|
|
633
|
-
).textContent = `Session: ${sessionId} (Connected)`;
|
|
677
|
+
setSessionInfoConnected();
|
|
634
678
|
document.getElementById("session-info").style.color =
|
|
635
679
|
"var(--green-color)";
|
|
636
680
|
ws.send(JSON.stringify({ type: "GET_STATE" }));
|
|
@@ -649,6 +693,19 @@
|
|
|
649
693
|
try {
|
|
650
694
|
const message = JSON.parse(event.data);
|
|
651
695
|
|
|
696
|
+
if (message.type === "SESSION_META" && message.payload) {
|
|
697
|
+
sessionTimeoutMs =
|
|
698
|
+
typeof message.payload.timeoutMs === "number"
|
|
699
|
+
? message.payload.timeoutMs
|
|
700
|
+
: null;
|
|
701
|
+
|
|
702
|
+
// For B: start countdown when we have received the questions.
|
|
703
|
+
if (hasReceivedQuestions && sessionTimeoutMs) {
|
|
704
|
+
startCountdown(sessionTimeoutMs);
|
|
705
|
+
}
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
|
|
652
709
|
if (
|
|
653
710
|
message.type === "SYNC_STATE" ||
|
|
654
711
|
message.type === "NEW_QUESTION"
|
|
@@ -660,6 +717,8 @@
|
|
|
660
717
|
|
|
661
718
|
if (questions && questions.length > 0) {
|
|
662
719
|
QUESTIONS_DATA = questions;
|
|
720
|
+
hasReceivedQuestions = true;
|
|
721
|
+
if (sessionTimeoutMs) startCountdown(sessionTimeoutMs);
|
|
663
722
|
initAnswers();
|
|
664
723
|
activeQuestionIndex = 0;
|
|
665
724
|
activeOptionIndex = 0;
|
|
@@ -675,6 +734,7 @@
|
|
|
675
734
|
};
|
|
676
735
|
|
|
677
736
|
ws.onclose = () => {
|
|
737
|
+
stopCountdown();
|
|
678
738
|
document.getElementById(
|
|
679
739
|
"session-info"
|
|
680
740
|
).textContent = `Disconnected. Reconnecting...`;
|