Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
- Fix: チャートの描画終了後にリソースが解放されない問題を修正
- Fix: ドライブの「このファイルからノートを作成」やギャラリーの「ノートで共有」、誕生日ウィジェットからのノート作成において、通常投稿の下書きが表示される問題を修正
- Fix: QRコードリーダーがページを離れても停止しない問題を修正
- Fix: リバーシの対局中に制限時間の経過が実際より遅く計測されることがある問題を修正

### Server
- Feat: OpenTelemetryサポート
Expand Down
28 changes: 14 additions & 14 deletions packages/frontend/src/pages/reversi/game.board.vue
Original file line number Diff line number Diff line change
Expand Up @@ -279,29 +279,30 @@ function putStone(pos: number) {
});
appliedOps.push(id);

myTurnTimerRmain.value = game.value.timeLimitForEachTurn;
opTurnTimerRmain.value = game.value.timeLimitForEachTurn;
resetTurnTimer();

checkEnd();
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

const myTurnTimerRmain = ref<number>(game.value.timeLimitForEachTurn);
const opTurnTimerRmain = ref<number>(game.value.timeLimitForEachTurn);
let turnTimerDeadline = Date.now() + game.value.timeLimitForEachTurn * 1000;

function resetTurnTimer() {
turnTimerDeadline = Date.now() + game.value.timeLimitForEachTurn * 1000;
myTurnTimerRmain.value = game.value.timeLimitForEachTurn;
opTurnTimerRmain.value = game.value.timeLimitForEachTurn;
}

const TIMER_INTERVAL_SEC = 3;
if (!props.game.isEnded) {
useInterval(() => {
if (myTurnTimerRmain.value > 0) {
myTurnTimerRmain.value = Math.max(0, myTurnTimerRmain.value - TIMER_INTERVAL_SEC);
}
if (opTurnTimerRmain.value > 0) {
opTurnTimerRmain.value = Math.max(0, opTurnTimerRmain.value - TIMER_INTERVAL_SEC);
}
const remain = Math.max(0, Math.ceil((turnTimerDeadline - Date.now()) / 1000));
myTurnTimerRmain.value = remain;
opTurnTimerRmain.value = remain;

if (iAmPlayer.value) {
if ((isMyTurn.value && myTurnTimerRmain.value === 0) || (!isMyTurn.value && opTurnTimerRmain.value === 0)) {
props.connection!.send('claimTimeIsUp', {});
}
if (iAmPlayer.value && remain === 0) {
props.connection!.send('claimTimeIsUp', {});
Comment on lines 317 to +325

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== game.board.vue around target ==\n'
sed -n '240,360p' packages/frontend/src/pages/reversi/game.board.vue

printf '\n== search useInterval implementation/usages ==\n'
rg -n "function useInterval|const useInterval|export .*useInterval|useInterval\(" packages/frontend/src -g '!**/*.map'

printf '\n== search claimTimeIsUp and end/start checks in reversi page ==\n'
rg -n "claimTimeIsUp|isEnded|isStarted|checkEnd\\(" packages/frontend/src/pages/reversi packages/frontend/src -g '!**/*.map'

Repository: misskey-dev/misskey

Length of output: 14429


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== game.vue around GameBoard mount conditions ==\n'
sed -n '1,170p' packages/frontend/src/pages/reversi/game.vue

printf '\n== checkEnd() and related timer reset logic ==\n'
sed -n '360,430p' packages/frontend/src/pages/reversi/game.board.vue

Repository: misskey-dev/misskey

Length of output: 4838


時間切れ通知は1回に制限してください if (!props.game.isEnded) は初期化時にしか効かないため、checkEnd()game.value.isEnded が更新されてもこの interval は止まりません。remain === 0 以降も 3 秒ごとに claimTimeIsUp を送ってしまうので、コールバック内で終了判定を入れるか、送信済みフラグ/停止処理を追加してください。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/frontend/src/pages/reversi/game.board.vue` around lines 297 - 305,
Limit the time-expiration notification to one send in the interval callback
around useInterval: re-check the current game-ended state after checkEnd updates
it and/or track whether the notification was already sent, so claimTimeIsUp is
not sent again once remain reaches zero. Preserve the existing timer updates and
stop or bypass further notifications after the first claim.

}
}, TIMER_INTERVAL_SEC * 1000, { immediate: false, afterMounted: true });
}
Expand Down Expand Up @@ -333,8 +334,7 @@ async function onStreamLog(log: Reversi.Serializer.Log & { id: string | null })
engine.value.putStone(log.pos);
triggerRef(engine);

myTurnTimerRmain.value = game.value.timeLimitForEachTurn;
opTurnTimerRmain.value = game.value.timeLimitForEachTurn;
resetTurnTimer();

checkEnd();
break;
Expand Down
Loading