Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
19 changes: 19 additions & 0 deletions packages/web/src/pages/common/timer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useSettingStore } from '@/stores/setting';
/** 启动和销毁计时器 hooks */
export const userTimer = () => {
const settingStore = useSettingStore();

const timerId = ref();

onMounted(() => {
timerId.value = setInterval(() => {
settingStore.readTime += 1;
}, 1000);
});

onBeforeUnmount(() => {
if (timerId.value) {
clearInterval(timerId.value);
}
});
};
Comment on lines +1 to +19
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix missing imports and consider timer behavior.

Several critical issues need to be addressed:

  1. Missing Vue imports - This will cause runtime errors:
  2. Timer runs continuously - Consider pausing when user is inactive
  3. Function naming - userTimer should probably be useTimer

Apply this diff to fix the missing imports:

+import { ref, onMounted, onBeforeUnmount } from 'vue';
 import { useSettingStore } from '@/stores/setting';
-/** 启动和销毁计时器 hooks */
-export const userTimer = () => {
+
+/** 启动和销毁计时器 hook */
+export const useTimer = () => {
   const settingStore = useSettingStore();
   
   const timerId = ref();
   
   onMounted(() => {
     timerId.value = setInterval(() => {
       settingStore.readTime += 1;
     }, 1000);
   });
   
   onBeforeUnmount(() => {
     if (timerId.value) {
       clearInterval(timerId.value);
+      timerId.value = null;
     }
   });
 };

Consider adding pause/resume functionality for when the user is inactive:

export const useTimer = () => {
  const settingStore = useSettingStore();
  const timerId = ref<number | null>(null);
  const isActive = ref(true);

  const startTimer = () => {
    if (timerId.value) return;
    timerId.value = setInterval(() => {
      if (isActive.value) {
        settingStore.readTime += 1;
      }
    }, 1000);
  };

  const pauseTimer = () => {
    isActive.value = false;
  };

  const resumeTimer = () => {
    isActive.value = true;
  };

  // Add window focus/blur listeners
  onMounted(() => {
    startTimer();
    window.addEventListener('focus', resumeTimer);
    window.addEventListener('blur', pauseTimer);
  });

  onBeforeUnmount(() => {
    if (timerId.value) {
      clearInterval(timerId.value);
      timerId.value = null;
    }
    window.removeEventListener('focus', resumeTimer);
    window.removeEventListener('blur', pauseTimer);
  });
};
🤖 Prompt for AI Agents
In packages/web/src/pages/common/timer.ts lines 1 to 19, the code is missing
necessary Vue imports like ref, onMounted, and onBeforeUnmount, which causes
runtime errors. Rename the function from userTimer to useTimer for clarity.
Implement pause and resume functionality to stop the timer when the user is
inactive by tracking window focus and blur events, and ensure the timerId is
properly typed and cleared on unmount. Add event listeners for window focus and
blur in onMounted and remove them in onBeforeUnmount to manage timer activity
accordingly.

3 changes: 3 additions & 0 deletions packages/web/src/pages/vscode/content/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import { ContentType } from '@any-reader/rule-utils';
import { useContent, useTheme } from '@/pages/common/content';
import { useReadStore } from '@/stores/read';
import { userTimer } from '@/pages/common/timer';
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Update import name and add error handling.

The import should be updated to match the corrected function name from the timer module.

-import { userTimer } from '@/pages/common/timer';
+import { useTimer } from '@/pages/common/timer';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { userTimer } from '@/pages/common/timer';
-import { userTimer } from '@/pages/common/timer';
+import { useTimer } from '@/pages/common/timer';
🤖 Prompt for AI Agents
In packages/web/src/pages/vscode/content/index.vue at line 56, update the import
statement to use the corrected function name from the timer module instead of
'userTimer'. Also, add appropriate error handling around the usage of this
imported function to handle potential failures gracefully.


const contentRef = ref();

Expand All @@ -62,6 +63,8 @@ const { content, contentType, settingStore, lastChapter, nextChapter, onPageUp,
useContent(contentRef);

useTheme(contentRef);

userTimer();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Update function call and consider error handling.

Update the function call to match the corrected name and consider adding error handling.

-userTimer();
+useTimer();

Consider wrapping the timer initialization with error handling:

try {
  useTimer();
} catch (error) {
  console.warn('Failed to initialize reading timer:', error);
}
🤖 Prompt for AI Agents
In packages/web/src/pages/vscode/content/index.vue at line 67, the function call
userTimer() should be updated to useTimer() to match the corrected function
name. Additionally, wrap the useTimer() call in a try-catch block to handle
potential errors gracefully by logging a warning message with the error details.

</script>

<style scoped>
Expand Down
16 changes: 15 additions & 1 deletion packages/web/src/pages/vscode/layout/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
<component :is="Component" v-if="!routev.meta.keepAlive" :key="routev.fullPath" />
</RouterView>
</div>
<div v-if="!hideBtmBar" class="flex gap-4 px-8 py-4">
<div v-if="!hideBtmBar" class="flex items-center gap-4 px-8 py-4">
<div class="codicon codicon-arrow-left vsc-toolbar-btn" @click="router.back()"></div>
<div v-if="settingStore.timeIsShow">已摸鱼:{{ showTIme }}</div>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Update template to use corrected computed property name.

Update the template binding to match the corrected computed property name.

-      <div v-if="settingStore.timeIsShow">已摸鱼:{{ showTIme }}</div>
+      <div v-if="settingStore.timeIsShow">已摸鱼:{{ showTime }}</div>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div v-if="settingStore.timeIsShow">已摸鱼:{{ showTIme }}</div>
<div v-if="settingStore.timeIsShow">已摸鱼:{{ showTime }}</div>
🤖 Prompt for AI Agents
In packages/web/src/pages/vscode/layout/index.vue at line 13, the template uses
the computed property name "showTIme" which is incorrect. Update the template
binding to use the corrected computed property name exactly as defined in the
script, ensuring proper casing and spelling.

<div class="flex-1"></div>
<div
class="codicon codicon-github-alt vsc-toolbar-btn"
Expand All @@ -31,9 +32,22 @@
import '@/plugins/vsc-ui';

import { executeCommand } from '@/api/modules/vsc';
import { useSettingStore } from '@/stores/setting';

const route = useRoute();
const router = useRouter();
const settingStore = useSettingStore();

const hideBtmBar = computed(() => route.meta?.hideBtmBar);

console.log('settingStore.readTime:', settingStore.readTime);
const showTIme = computed(() => {
const readTime = settingStore.readTime;

if (readTime <= 0) return 0;
const hours = Math.floor(readTime / 3600);
const minutes = Math.floor((readTime % 3600) / 60);
const seconds = readTime % 60;
return `${hours}:${minutes}:${seconds}`;
});
Comment on lines +44 to +52
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix typo in computed property name and improve formatting.

The computed property has a typo and the time formatting could be improved.

Apply this diff to fix the typo and improve formatting:

-const showTIme = computed(() => {
+const showTime = computed(() => {
   const readTime = settingStore.readTime;

   if (readTime <= 0) return 0;
   const hours = Math.floor(readTime / 3600);
   const minutes = Math.floor((readTime % 3600) / 60);
   const seconds = readTime % 60;
-  return `${hours}:${minutes}:${seconds}`;
+  return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
 });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const showTIme = computed(() => {
const readTime = settingStore.readTime;
if (readTime <= 0) return 0;
const hours = Math.floor(readTime / 3600);
const minutes = Math.floor((readTime % 3600) / 60);
const seconds = readTime % 60;
return `${hours}:${minutes}:${seconds}`;
});
const showTime = computed(() => {
const readTime = settingStore.readTime;
if (readTime <= 0) return 0;
const hours = Math.floor(readTime / 3600);
const minutes = Math.floor((readTime % 3600) / 60);
const seconds = readTime % 60;
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
});
🤖 Prompt for AI Agents
In packages/web/src/pages/vscode/layout/index.vue around lines 44 to 52, the
computed property name "showTIme" contains a typo and the time formatting lacks
leading zeros for minutes and seconds. Rename the property to "showTime" and
update the return statement to format hours, minutes, and seconds with leading
zeros (e.g., using padStart or equivalent) to ensure consistent time display.

</script>
8 changes: 8 additions & 0 deletions packages/web/src/pages/vscode/settings/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
<SettingRow title="缓存">
<vscode-button @click="clearCache">删除缓存</vscode-button>
</SettingRow>
<SettingRow title="摸鱼时间">
<vscode-checkbox :checked="settingStore.timeIsShow" @input="handleInput">显示/隐藏</vscode-checkbox>
</SettingRow>
Comment on lines +12 to +14
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix checkbox binding and event handling.

The current implementation has issues with the two-way binding:

  1. The event handler only logs but doesn't update the store state
  2. Missing proper two-way binding pattern

Apply this diff to fix the checkbox binding:

-    <SettingRow title="摸鱼时间">
-      <vscode-checkbox :checked="settingStore.timeIsShow" @input="handleInput">显示/隐藏</vscode-checkbox>
-    </SettingRow>
+    <SettingRow title="摸鱼时间">
+      <vscode-checkbox 
+        :checked="settingStore.timeIsShow" 
+        @input="(event) => settingStore.timeIsShow = event.target.checked"
+      >
+        显示/隐藏
+      </vscode-checkbox>
+    </SettingRow>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<SettingRow title="摸鱼时间">
<vscode-checkbox :checked="settingStore.timeIsShow" @input="handleInput">显示/隐藏</vscode-checkbox>
</SettingRow>
<SettingRow title="摸鱼时间">
<vscode-checkbox
:checked="settingStore.timeIsShow"
@input="(event) => settingStore.timeIsShow = event.target.checked"
>
显示/隐藏
</vscode-checkbox>
</SettingRow>
🤖 Prompt for AI Agents
In packages/web/src/pages/vscode/settings/index.vue around lines 12 to 14, the
checkbox component uses a :checked prop and an @input event that only logs
without updating the store, breaking two-way binding. Replace :checked with
v-model bound to settingStore.timeIsShow and update the event handler to modify
the store state accordingly, ensuring proper two-way binding and reactive
updates.

</div>
</template>

Expand All @@ -29,4 +32,9 @@ function clearCache() {
}
});
}

const handleInput = (event) => {
console.log('event:', event);
console.log('event.target.checked:', event.target.checked);
};
Comment on lines +36 to +39
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove unused event handler.

The handleInput function is no longer needed after fixing the checkbox binding.

-const handleInput = (event) => {
-  console.log('event:', event);
-  console.log('event.target.checked:', event.target.checked);
-};
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleInput = (event) => {
console.log('event:', event);
console.log('event.target.checked:', event.target.checked);
};
🤖 Prompt for AI Agents
In packages/web/src/pages/vscode/settings/index.vue around lines 36 to 39, the
handleInput function is no longer used after fixing the checkbox binding. Remove
the entire handleInput function to clean up unused code.

</script>
8 changes: 7 additions & 1 deletion packages/web/src/stores/setting.pc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { FontData } from '@/utils/font';

export type ReadStyle = {
// 字体
font: FontData;
font?: FontData;
// 字体大小
fontSize: number;
// 字体粗细
Expand Down Expand Up @@ -65,6 +65,10 @@ export const useSettingStore = defineStore('setting', () => {
bookDir: ''
});

/** 是否显示摸鱼时间 */
const timeIsShow = ref<boolean>(true);
const readTime = ref<number>(0);
Comment on lines +69 to +70
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adding timer state to persistent configuration.

The new timeIsShow and readTime variables are not included in the persistent data object that gets synchronized with the backend via readConfig/updateConfig. This means:

  1. Settings won't persist across application restarts
  2. Timer value will reset to 0 on page reload
  3. User preference for showing time won't be remembered

Consider moving these properties into the Setting type and data object:

export type Setting = {
  readStyle: ReadStyle;
  keyboardShortcuts: KeyboardShortcuts;
  sidebar: Sidebar;
  bookDir: string;
+ timeIsShow: boolean;
+ readTime: number;
};

export const useSettingStore = defineStore('setting', () => {
  const data = reactive<Setting>({
    readStyle: {
      // ...existing properties
    },
    keyboardShortcuts: {
      // ...existing properties  
    },
    sidebar: 'left',
-   bookDir: ''
+   bookDir: '',
+   timeIsShow: true,
+   readTime: 0
  });

-  /** 是否显示摸鱼时间 */
-  const timeIsShow = ref<boolean>(true);
-  const readTime = ref<number>(0);

  return {
    data,
-   readTime,
-   timeIsShow,
    sync
  };
});

Then access them via settingStore.data.timeIsShow and settingStore.data.readTime in components.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const timeIsShow = ref<boolean>(true);
const readTime = ref<number>(0);
export type Setting = {
readStyle: ReadStyle;
keyboardShortcuts: KeyboardShortcuts;
sidebar: Sidebar;
bookDir: string;
timeIsShow: boolean;
readTime: number;
};
export const useSettingStore = defineStore('setting', () => {
const data = reactive<Setting>({
readStyle: {
// ...existing properties
},
keyboardShortcuts: {
// ...existing properties
},
sidebar: 'left',
bookDir: '',
timeIsShow: true,
readTime: 0
});
// ...other store logic (e.g. readConfig, updateConfig, etc.)...
return {
data,
sync
};
});
🤖 Prompt for AI Agents
In packages/web/src/stores/setting.pc.ts around lines 69 to 70, the new reactive
variables timeIsShow and readTime are not part of the persistent data object
synchronized with the backend, causing their values and user preferences to
reset on reload. To fix this, add timeIsShow and readTime to the Setting type
and include them in the data object that is read and updated via readConfig and
updateConfig. Then update all references to these variables to access them
through settingStore.data.timeIsShow and settingStore.data.readTime to ensure
persistence across restarts.


// 同步
async function sync() {
const res = await readConfig().catch(() => {});
Expand All @@ -81,6 +85,8 @@ export const useSettingStore = defineStore('setting', () => {

return {
data,
readTime,
timeIsShow,
sync
};
});