Skip to content

Commit

Permalink
feat: add Shortcut key and auto check pause for pause game
Browse files Browse the repository at this point in the history
  • Loading branch information
cuixiaorui committed Aug 6, 2024
1 parent 6ff8fd7 commit ea98379
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 28 deletions.
10 changes: 7 additions & 3 deletions apps/client/components/main/LearningTimer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@
import { computed, onMounted, onUnmounted, ref, watch } from "vue";
import { useLearningTimeTracker } from "~/composables/main/learningTimeTracker";
import { useGamePause } from "~/composables/main/useGamePause";
import { useGameStore } from "~/store/game";
const { $anime } = useNuxtApp();
const gameStore = useGameStore();
const { totalSeconds, startTracking, stopTracking } = useLearningTimeTracker();
const { pauseGame, enableAutoPauseCheck, disableAutoPauseCheck } = useGamePause();
const { totalSeconds, stopTracking } = useLearningTimeTracker();
const clockIcon = ref(null);
const formattedTime = computed(() => {
Expand Down Expand Up @@ -71,8 +74,7 @@ function handleVisibilityChange() {
if (document.hidden) {
stopTracking();
} else {
startTracking();
pauseGame();
}
}
Expand All @@ -87,10 +89,12 @@ function handleBeforeunload() {
onMounted(() => {
document.addEventListener("visibilitychange", handleVisibilityChange);
window.addEventListener("beforeunload", handleBeforeunload);
enableAutoPauseCheck();
});
onUnmounted(() => {
document.removeEventListener("visibilitychange", handleVisibilityChange);
window.removeEventListener("beforeunload", handleBeforeunload);
disableAutoPauseCheck();
});
</script>
44 changes: 19 additions & 25 deletions apps/client/components/main/Tool.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
<!-- 右侧 -->
<div class="flex items-center gap-4">
<div
data-tippy-content="暂停游戏"
@click="handleGamePause"
:data-tippy-content="`暂停游戏 (${shortcutKeys.pause})`"
@click="pauseGame"
@mouseenter="$lazyTippy"
>
<span class="clickable-item icon-item i-ph-pause-bold"></span>
Expand Down Expand Up @@ -65,36 +65,40 @@
confirm-btn-text="确认"
@confirm="handleTipConfirm"
/>
{{ showGamePauseModal }}

<MainMessageBox
v-model:show-modal="showGamePauseModal"
content="游戏暂停 快点回来!"
cancelBtnText=""
confirm-btn-text="继续游戏"
@confirm="handleGameResume"
@close="handleGameResume"
@confirm="resumeGame"
@close="resumeGame"
/>
</template>

<script setup lang="ts">
import { computed, ref } from "vue";
import { computed, onMounted, onUnmounted, ref } from "vue";
import { useQuestionInput } from "~/components/main/QuestionInput/questionInputHelper";
import { courseTimer } from "~/composables/courses/courseTimer";
import { useGameMode } from "~/composables/main/game";
import { clearQuestionInput } from "~/composables/main/question";
import { useGamePause } from "~/composables/main/useGamePause";
import { useRanking } from "~/composables/rank/rankingList";
import { useShortcutKeyMode } from "~/composables/user/shortcutKey";
import { useCourseStore } from "~/store/course";
import { useGameStore } from "~/store/game";
import { cancelShortcut, registerShortcut } from "~/utils/keyboardShortcuts";
import { useContent } from "./Contents/useContents";
const { shortcutKeys } = useShortcutKeyMode();
const rankingStore = useRanking();
const courseStore = useCourseStore();
const gameStore = useGameStore();
const { focusInput } = useQuestionInput();
const { toggleContents } = useContent();
const { showTipModal, handleDoAgain, handleTipConfirm } = useDoAgain();
const { showGamePauseModal, handleGameResume, handleGamePause } = useGamePause();
const { showGamePauseModal, pauseGame, resumeGame } = useGamePause();
useGamePauseWrapper();
const currentCourseInfo = computed(() => {
return `${courseStore.currentCourse?.title}(${currentSchedule.value}/${courseStore.visibleStatementsCount})`;
Expand All @@ -113,24 +117,14 @@ const currentPercentage = computed(() => {
);
});
function useGamePause() {
const showGamePauseModal = ref(false);
function useGamePauseWrapper() {
onMounted(() => {
registerShortcut(shortcutKeys.value.pause, pauseGame);
});
function handleGameResume() {
showGamePauseModal.value = false;
gameStore.resumeGame();
}
function handleGamePause() {
showGamePauseModal.value = true;
gameStore.pauseGame();
}
return {
showGamePauseModal,
handleGameResume,
handleGamePause,
};
onUnmounted(() => {
cancelShortcut(shortcutKeys.value.pause, pauseGame);
});
}
function useDoAgain() {
Expand Down
66 changes: 66 additions & 0 deletions apps/client/composables/main/useGamePause.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { ref, watch } from "vue";

import { useQuestionInput } from "~/components/main/QuestionInput/questionInputHelper";
import { useCourseStore } from "~/store/course";
import { useGameStore } from "~/store/game";

const inactivityTimer = ref<NodeJS.Timeout>();
const INACTIVITY_TIMEOUT = 5 * 60 * 1000; // 5分钟,单位毫秒

const showGamePauseModal = ref(false);
/**
* 用于处理游戏暂停页面(UI)逻辑
* 暂停 恢复 开启自动检测暂停等
* @returns
*/
export function useGamePause() {
const courseStore = useCourseStore();
const gameStore = useGameStore();
const { focusInput } = useQuestionInput();

function resumeGame() {
showGamePauseModal.value = false;
gameStore.resumeGame();
focusInput();
resetInactivityTimer();
}

function pauseGame() {
showGamePauseModal.value = true;
gameStore.pauseGame();
disableAutoPauseCheck();
}

function resetInactivityTimer() {
disableAutoPauseCheck();
inactivityTimer.value = setTimeout(() => {
pauseGame();
}, INACTIVITY_TIMEOUT);
}

function enableAutoPauseCheck() {
watch(
() => courseStore.statementIndex,
() => {
resetInactivityTimer();
},
{
immediate: true,
},
);
}

function disableAutoPauseCheck() {
if (inactivityTimer.value) {
clearTimeout(inactivityTimer.value);
}
}

return {
showGamePauseModal,
resumeGame,
pauseGame,
enableAutoPauseCheck,
disableAutoPauseCheck,
};
}
2 changes: 2 additions & 0 deletions apps/client/composables/user/shortcutKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export enum SHORTCUT_KEY_TYPES {
SKIP = "skip",
PREVIOUS = "previous",
MASTERED = "mastered",
PAUSE = "pause",
}
export const SHORTCUT_KEYS = "shortcutKeys";
export const DEFAULT_SHORTCUT_KEYS = {
Expand All @@ -14,6 +15,7 @@ export const DEFAULT_SHORTCUT_KEYS = {
skip: "Ctrl+.",
previous: "Ctrl+,",
mastered: "Ctrl+m",
pause: "Ctrl+p",
};

export const KEYBOARD = {
Expand Down
4 changes: 4 additions & 0 deletions apps/client/pages/User/Setting.vue
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,10 @@ const shortcutKeyBindList = [
label: "标记内容已经掌握",
type: SHORTCUT_KEY_TYPES.MASTERED,
},
{
label: "暂停游戏",
type: SHORTCUT_KEY_TYPES.PAUSE,
},
];
onMounted(() => {
Expand Down

0 comments on commit ea98379

Please sign in to comment.