chenlei 10 ماه پیش
والد
کامیت
4610cc85a3

+ 32 - 6
packages/base/src/stores/epub.js

@@ -1,4 +1,4 @@
-import { ref } from "vue";
+import { ref, nextTick } from "vue";
 import { tify, sify } from "chinese-conv";
 import { tify, sify } from "chinese-conv";
 import { defineStore } from "pinia";
 import { defineStore } from "pinia";
 import { FONT_FAMILYS, THEMES } from "../constants";
 import { FONT_FAMILYS, THEMES } from "../constants";
@@ -58,7 +58,14 @@ export const useEpubStore = defineStore("epub", () => {
   const init = (options = {}) => {
   const init = (options = {}) => {
     initEpub(options);
     initEpub(options);
     initTheme(options.themes);
     initTheme(options.themes);
-    goToChapter(localStorage.getItem(`${EPUB_LOCATION}-1`) || undefined);
+    const locationStorage = localStorage.getItem(`${EPUB_LOCATION}-1`);
+    if (locationStorage) {
+      const arr = locationStorage.split("-");
+
+      goToChapter(arr[0], arr[1]);
+    } else {
+      goToChapter();
+    }
   };
   };
 
 
   const initEpub = (options) => {
   const initEpub = (options) => {
@@ -126,7 +133,15 @@ export const useEpubStore = defineStore("epub", () => {
   const refreshLocation = async () => {
   const refreshLocation = async () => {
     const curLocation = rendition.value.currentLocation();
     const curLocation = rendition.value.currentLocation();
     const startCfi = curLocation.start.cfi;
     const startCfi = curLocation.start.cfi;
-    localStorage.setItem(`${EPUB_LOCATION}-1`, startCfi);
+    const scrollLeft =
+      document.getElementsByClassName("epub-container")[0]?.scrollLeft;
+
+    localStorage.setItem(`${EPUB_LOCATION}-1`, `${startCfi}-${scrollLeft}`);
+
+    return {
+      startCfi,
+      scrollLeft,
+    };
   };
   };
 
 
   /**
   /**
@@ -169,11 +184,21 @@ export const useEpubStore = defineStore("epub", () => {
   /**
   /**
    * 跳转目录
    * 跳转目录
    * @param {String} cfi
    * @param {String} cfi
+   * @param {String | Number} scrollLeft
    */
    */
-  const goToChapter = (cfi) => {
-    rendition.value.display(cfi).then(() => {
+  const goToChapter = async (cfi, scrollLeft) => {
+    await rendition.value.display(cfi);
+
+    if (scrollLeft) {
+      nextTick(() => {
+        document.getElementsByClassName("epub-container")[0]?.scrollTo({
+          left: Number(scrollLeft),
+        });
+        refreshLocation();
+      });
+    } else {
       refreshLocation();
       refreshLocation();
-    });
+    }
   };
   };
 
 
   /**
   /**
@@ -219,6 +244,7 @@ export const useEpubStore = defineStore("epub", () => {
     toggleFontSize,
     toggleFontSize,
     goToChapter,
     goToChapter,
     searchKeyword,
     searchKeyword,
+    refreshLocation,
     prePage,
     prePage,
     nextPage,
     nextPage,
   };
   };

+ 2 - 1
packages/base/src/theme.scss

@@ -17,7 +17,8 @@ html {
 dark
 dark
 ==========
 ==========
  */
  */
-html.dark {
+html.dark,
+html.van-theme-dark {
   --topnav-bg-color: #414141;
   --topnav-bg-color: #414141;
   --page-bg-color: #373737;
   --page-bg-color: #373737;
   --pane-bg-color: #2c2c2c;
   --pane-bg-color: #2c2c2c;

+ 1 - 1
packages/mobile/index.html

@@ -10,6 +10,6 @@
     <div id="app"></div>
     <div id="app"></div>
     <script type="module" src="/src/main.js"></script>
     <script type="module" src="/src/main.js"></script>
     <script type="text/javascript" src="./jszip.min.js"></script>
     <script type="text/javascript" src="./jszip.min.js"></script>
-    <script type="text/javascript" src="./epub.min.js"></script>
+    <script type="text/javascript" src="./epub.js"></script>
   </body>
   </body>
 </html>
 </html>

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 19295 - 0
packages/mobile/public/epub.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1
packages/mobile/public/epub.min.js


BIN
packages/mobile/public/test.epub


+ 5 - 1
packages/mobile/src/App.vue

@@ -1,15 +1,19 @@
 <script setup>
 <script setup>
 import { computed } from "vue";
 import { computed } from "vue";
 import { useRoute, RouterView } from "vue-router";
 import { useRoute, RouterView } from "vue-router";
+import { storeToRefs } from "pinia";
 import Tabbar from "@/components/Tabbar/index.vue";
 import Tabbar from "@/components/Tabbar/index.vue";
+import { useSettingStore } from "@/stores";
 
 
 const route = useRoute();
 const route = useRoute();
+const settingStore = useSettingStore();
+const { theme } = storeToRefs(settingStore);
 
 
 const tabbarVisible = computed(() => !route.meta.hideTabbar);
 const tabbarVisible = computed(() => !route.meta.hideTabbar);
 </script>
 </script>
 
 
 <template>
 <template>
-  <VanConfigProvider>
+  <VanConfigProvider :theme="theme">
     <RouterView />
     <RouterView />
 
 
     <Tabbar :visible="tabbarVisible" />
     <Tabbar :visible="tabbarVisible" />

+ 1 - 0
packages/mobile/src/stores/index.js

@@ -1,2 +1,3 @@
 export * from "@lsq/base/src/stores";
 export * from "@lsq/base/src/stores";
 export * from "./detail";
 export * from "./detail";
+export * from "./setting";

+ 8 - 0
packages/mobile/src/stores/setting.js

@@ -0,0 +1,8 @@
+import { ref } from "vue";
+import { defineStore } from "pinia";
+
+export const useSettingStore = defineStore("setting", () => {
+  const theme = ref("light");
+
+  return { theme };
+});

+ 1 - 0
packages/mobile/src/views/Reader/components/CommentPopup.vue

@@ -59,6 +59,7 @@ const list = ref([
     margin: 30px 0;
     margin: 30px 0;
     height: 352px;
     height: 352px;
     border-color: var(--van-primary-color);
     border-color: var(--van-primary-color);
+    background: transparent;
   }
   }
   .van-button {
   .van-button {
     margin-bottom: 30px;
     margin-bottom: 30px;

+ 1 - 0
packages/mobile/src/views/Reader/components/NotePopup.vue

@@ -66,6 +66,7 @@ const editVisible = ref(false);
   &__textarea {
   &__textarea {
     height: 352px;
     height: 352px;
     border-color: var(--van-primary-color);
     border-color: var(--van-primary-color);
+    background: transparent;
   }
   }
   .van-button {
   .van-button {
     border-radius: 0;
     border-radius: 0;

+ 4 - 0
packages/mobile/src/views/Reader/components/SearchPopup.vue

@@ -2,6 +2,7 @@
   <popup v-bind="$attrs" title="全文搜索">
   <popup v-bind="$attrs" title="全文搜索">
     <search-input
     <search-input
       v-model="detailStore.searchKey"
       v-model="detailStore.searchKey"
+      class="search-popup-input"
       simple
       simple
       @search="debounceSearch"
       @search="debounceSearch"
     />
     />
@@ -97,5 +98,8 @@ watch(
     padding: 20px;
     padding: 20px;
     border-bottom: 1px solid var(--van-border-color);
     border-bottom: 1px solid var(--van-border-color);
   }
   }
+  &-input {
+    background: transparent;
+  }
 }
 }
 </style>
 </style>

+ 8 - 3
packages/mobile/src/views/Reader/components/SettingPopup.vue

@@ -77,7 +77,7 @@
 </template>
 </template>
 
 
 <script setup>
 <script setup>
-import { ref, onMounted } from "vue";
+import { ref, onMounted, onUnmounted } from "vue";
 import {
 import {
   FONT_FAMILYS,
   FONT_FAMILYS,
   FONT_SIZES,
   FONT_SIZES,
@@ -85,11 +85,12 @@ import {
   EPUB_FONTSIZE_KEY,
   EPUB_FONTSIZE_KEY,
   EPUB_THEME_KEY,
   EPUB_THEME_KEY,
 } from "@lsq/base";
 } from "@lsq/base";
-import { useEpubStore } from "@/stores";
+import { useEpubStore, useSettingStore } from "@/stores";
 import Popup from "./Popup.vue";
 import Popup from "./Popup.vue";
 import { THEMES } from "../constants";
 import { THEMES } from "../constants";
 
 
 const epubStore = useEpubStore();
 const epubStore = useEpubStore();
+const settingStore = useSettingStore();
 
 
 const currentFamily = ref(
 const currentFamily = ref(
   localStorage.getItem(EPUB_FONT_KEY) ?? FONT_FAMILYS[0].value
   localStorage.getItem(EPUB_FONT_KEY) ?? FONT_FAMILYS[0].value
@@ -102,13 +103,17 @@ const sizeVisible = ref(false);
 
 
 const handleTheme = (item) => {
 const handleTheme = (item) => {
   epubStore.toggleTheme(item.key);
   epubStore.toggleTheme(item.key);
+  settingStore.theme = item.key === "dark" ? "dark" : "light";
 };
 };
 
 
 onMounted(() => {
 onMounted(() => {
   if (localStorage.getItem(EPUB_THEME_KEY) === "dark") {
   if (localStorage.getItem(EPUB_THEME_KEY) === "dark") {
-    // toggleDark(true);
+    settingStore.theme = "dark";
   }
   }
 });
 });
+onUnmounted(() => {
+  settingStore.theme = "light";
+});
 </script>
 </script>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>

+ 44 - 106
packages/mobile/src/views/Reader/components/ToolbarPopover.vue

@@ -11,101 +11,42 @@
       </div>
       </div>
       <div class="select-menu__driver" />
       <div class="select-menu__driver" />
       <div class="select-menu-toolbar">
       <div class="select-menu-toolbar">
-        <div @click="removeHighlight">
-          <svg-icon
-            name="icon_delete"
-            width="24px"
-            height="24px"
-            color="var(--el-color-primary)"
-          />删除标记
-        </div>
-        <div @click="copyText">
-          <svg-icon
-            name="icon_copy"
-            width="24px"
-            height="24px"
-            color="var(--el-color-primary)"
-          />复制
-        </div>
-        <div @click="handleSearch">
-          <svg-icon
-            name="icon_search"
-            width="24px"
-            height="24px"
-            color="var(--el-color-primary)"
-          />搜索
-        </div>
+        <p @click="removeHighlight">删除</p>
+        <p @click="copyText">复制</p>
+        <p @click="handleSearch">搜索</p>
       </div>
       </div>
     </div>
     </div>
   </Teleport>
   </Teleport>
 </template>
 </template>
 
 
 <script setup>
 <script setup>
-import { onMounted, ref } from "vue";
+import { ref } from "vue";
 import useClipboard from "vue-clipboard3";
 import useClipboard from "vue-clipboard3";
 import { showNotify } from "vant";
 import { showNotify } from "vant";
+import "vant/es/notify/style/index";
 import { useEpubStore, useDetailStore } from "@/stores";
 import { useEpubStore, useDetailStore } from "@/stores";
 import { COLOR_MAP } from "../constants";
 import { COLOR_MAP } from "../constants";
 
 
+const props = defineProps({
+  selectMenuStyle: {
+    type: Object,
+    default: undefined,
+  },
+  selectedCfi: {
+    type: String,
+    default: "",
+  },
+});
+const emits = defineEmits(["close"]);
+
 const epubStore = useEpubStore();
 const epubStore = useEpubStore();
 const detailStore = useDetailStore();
 const detailStore = useDetailStore();
 const { toClipboard } = useClipboard();
 const { toClipboard } = useClipboard();
-const selectMenuStyle = ref({});
-const selectedCfi = ref("");
 const selectedCfiStack = ref([]);
 const selectedCfiStack = ref([]);
 
 
-onMounted(() => {
-  epubStore.rendition.hooks.render.register((v) => {
-    v.document.body.addEventListener("touchend", (e) => {
-      const selection = v.window.getSelection();
-
-      console.log(selection);
-      setTimeout(() => {
-        if (!selection.isCollapsed) selected(e, v);
-        else hideSelectMenu();
-      }, 50);
-    });
-  });
-
-  epubStore.rendition.on("selected", (v) => {
-    selectedCfi.value = v;
-  });
-});
-
-const hideSelectMenu = () => {
-  selectMenuStyle.value = { visibility: "hidden" };
-};
-
-const selected = (e, v) => {
-  const sty = {
-    visibility: "visible",
-  };
-  const x = e.clientX;
-  const y = e.clientY;
-  const menuWidth = 506;
-  const menuHeight = 58;
-  const screenWidth = v.document.body.clientWidth;
-  const screenHeight = v.document.body.clientHeight;
-  const offset = Math.floor(x / screenWidth) + 1;
-  const top = y + Math.round(menuHeight / 2) + 25;
-
-  if (x + menuWidth > screenWidth * offset) {
-    sty.left = screenWidth * offset - menuWidth - 11 + "px";
-  } else {
-    sty.left = x + "px";
-  }
-  if (top + menuHeight > screenHeight) {
-    sty.top = screenHeight - menuHeight - 11 + "px";
-  } else {
-    sty.top = top + "px";
-  }
-
-  selectMenuStyle.value = sty;
-};
-
 const setHighlight = (color) => {
 const setHighlight = (color) => {
   epubStore.rendition.annotations.highlight(
   epubStore.rendition.annotations.highlight(
-    selectedCfi.value,
+    props.selectedCfi,
     {},
     {},
     () => {},
     () => {},
     "",
     "",
@@ -114,32 +55,32 @@ const setHighlight = (color) => {
     }
     }
   );
   );
 
 
-  hideSelectMenu();
-  selectedCfiStack.value.push(selectedCfi.value);
+  emits("close");
+  selectedCfiStack.value.push(props.selectedCfi);
 };
 };
 
 
 const removeHighlight = () => {
 const removeHighlight = () => {
-  epubStore.rendition.annotations.remove(selectedCfi.value, "highlight");
-  hideSelectMenu();
+  epubStore.rendition.annotations.remove(props.selectedCfi, "highlight");
+  emits("close");
 };
 };
 
 
 const copyText = async () => {
 const copyText = async () => {
   try {
   try {
-    const range = epubStore.rendition.getRange(selectedCfi.value);
+    const range = epubStore.rendition.getRange(props.selectedCfi);
     const selectedText = range.toString();
     const selectedText = range.toString();
     await toClipboard(selectedText);
     await toClipboard(selectedText);
     showNotify({ type: "success", message: "复制成功" });
     showNotify({ type: "success", message: "复制成功" });
   } catch (err) {
   } catch (err) {
     showNotify({ type: "danger", message: "复制失败" });
     showNotify({ type: "danger", message: "复制失败" });
   }
   }
-  hideSelectMenu();
+  emits("close");
 };
 };
 
 
 const handleSearch = () => {
 const handleSearch = () => {
-  const range = epubStore.rendition.getRange(selectedCfi.value);
+  const range = epubStore.rendition.getRange(props.selectedCfi);
   const selectedText = range.toString();
   const selectedText = range.toString();
   detailStore.openSearchDrawer(selectedText);
   detailStore.openSearchDrawer(selectedText);
-  hideSelectMenu();
+  emits("close");
 };
 };
 </script>
 </script>
 
 
@@ -148,44 +89,41 @@ const handleSearch = () => {
   position: absolute;
   position: absolute;
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
-  gap: 15px;
-  padding: 15px;
+  gap: 20px;
+  padding: 20px;
   background: var(--el-bg-color);
   background: var(--el-bg-color);
-  border-radius: 5px;
+  border-radius: 10px;
   visibility: hidden;
   visibility: hidden;
   white-space: nowrap;
   white-space: nowrap;
-  box-shadow: 0px 0px 11px 0px rgba(0, 0, 0, 0.25);
+  box-sizing: border-box;
+  background: var(--van-white);
+  box-shadow: 0px 0px 22px 0px rgba(0, 0, 0, 0.25);
+  z-index: 999;
 
 
   &-colors {
   &-colors {
     display: flex;
     display: flex;
     align-items: center;
     align-items: center;
-    gap: 8px;
+    gap: 20px;
 
 
     div {
     div {
-      width: 24px;
-      height: 24px;
+      width: 50px;
+      height: 50px;
       border-radius: 50%;
       border-radius: 50%;
-      cursor: pointer;
     }
     }
   }
   }
   &__driver {
   &__driver {
-    width: 1px;
-    height: 28px;
-    background: var(--text-color);
+    flex-shrink: 0;
+    width: 2px;
+    height: 56px;
+    background: var(--van-border-color);
   }
   }
   &-toolbar {
   &-toolbar {
     display: flex;
     display: flex;
     align-items: center;
     align-items: center;
-    gap: 15px;
-    font-size: 18px;
-    color: var(--el-color-primary);
-
-    div {
-      display: flex;
-      align-items: center;
-      gap: 5px;
-      cursor: pointer;
-    }
+    gap: 30px;
+    font-size: 27px;
+    line-height: 50px;
+    color: var(--van-primary-color);
   }
   }
 }
 }
 </style>
 </style>

+ 50 - 8
packages/mobile/src/views/Reader/index.vue

@@ -1,6 +1,6 @@
 <template>
 <template>
   <div class="reader-page">
   <div class="reader-page">
-    <nav-bar back-color="#464646" :need-bg-color="false" />
+    <nav-bar back-color="var(--icon-close-color)" :need-bg-color="false" />
 
 
     <div id="reader" />
     <div id="reader" />
 
 
@@ -14,7 +14,11 @@
     />
     />
   </div>
   </div>
 
 
-  <toolbar-popover v-if="inited" />
+  <toolbar-popover
+    :select-menu-style="selectMenuStyle"
+    :selected-cfi="selectedCfi"
+    @close="hideSelectMenu"
+  />
 </template>
 </template>
 
 
 <script setup>
 <script setup>
@@ -26,8 +30,8 @@ import ToolbarPopover from "./components/ToolbarPopover.vue";
 import ToolbarMenu from "./components/ToolbarMenu.vue";
 import ToolbarMenu from "./components/ToolbarMenu.vue";
 
 
 const epubStore = useEpubStore();
 const epubStore = useEpubStore();
-const inited = ref(false);
 const selectedCfi = ref("");
 const selectedCfi = ref("");
+const selectMenuStyle = ref({});
 const paneBgColor = computed(
 const paneBgColor = computed(
   () => THEMES.find((theme) => theme.key === epubStore.curTheme).background
   () => THEMES.find((theme) => theme.key === epubStore.curTheme).background
 );
 );
@@ -36,14 +40,13 @@ onMounted(() => {
   epubStore.init({
   epubStore.init({
     url: "./test2.epub",
     url: "./test2.epub",
     themes: THEMES,
     themes: THEMES,
-    renderOptions: {
-      allowScriptedContent: true,
-    },
   });
   });
 
 
   epubStore.rendition.hooks.render.register((v) => {
   epubStore.rendition.hooks.render.register((v) => {
-    console.log(v);
     v.document.addEventListener("click", (e) => {
     v.document.addEventListener("click", (e) => {
+      // 如果显示冒泡,则不翻页
+      if (selectMenuStyle.value.visibility === "visible") return;
+
       const offsetX = e.offsetX;
       const offsetX = e.offsetX;
       const width = window.innerWidth;
       const width = window.innerWidth;
 
 
@@ -51,13 +54,52 @@ onMounted(() => {
       else if (offsetX > 0 && offsetX > width * 0.7) epubStore.nextPage();
       else if (offsetX > 0 && offsetX > width * 0.7) epubStore.nextPage();
     });
     });
 
 
-    inited.value = true;
+    v.document.body.addEventListener("touchend", (e) => {
+      const selection = v.window.getSelection();
+
+      setTimeout(() => {
+        if (!selection.isCollapsed) selected(e, v);
+        else hideSelectMenu();
+      }, 50);
+    });
   });
   });
 
 
   epubStore.rendition.on("selected", (v) => {
   epubStore.rendition.on("selected", (v) => {
     selectedCfi.value = v;
     selectedCfi.value = v;
   });
   });
 });
 });
+
+const selected = (e, v) => {
+  const sty = {
+    visibility: "visible",
+  };
+  const x = e.changedTouches[0].clientX;
+  const y = e.changedTouches[0].clientY;
+  const menuWidth = (704 / 750) * window.innerWidth;
+  const menuHeight = (96 / 750) * window.innerWidth;
+  const shadowWidth = (11 / 750) * window.innerWidth;
+  const screenWidth = window.innerWidth;
+  const screenHeight = v.document.body.clientHeight;
+  const offset = Math.floor(x / screenWidth) + 1;
+  const top = y + Math.round(menuHeight / 2);
+
+  if (x + menuWidth > screenWidth * offset) {
+    sty.left = screenWidth * offset - menuWidth - shadowWidth + "px";
+  } else {
+    sty.left = x + "px";
+  }
+  if (top + menuHeight > screenHeight) {
+    sty.top = screenHeight - menuHeight - shadowWidth + "px";
+  } else {
+    sty.top = top + "px";
+  }
+
+  selectMenuStyle.value = sty;
+};
+
+const hideSelectMenu = () => {
+  selectMenuStyle.value = { visibility: "hidden" };
+};
 </script>
 </script>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>

+ 7 - 9
packages/pc/src/views/Detail/components/Bookmark.vue

@@ -37,11 +37,8 @@ const emits = defineEmits(["update:visible", "close"]);
 const epubStore = useEpubStore();
 const epubStore = useEpubStore();
 const list = ref([
 const list = ref([
   {
   {
-    location: {
-      start: {
-        cfi: "epubcfi(/6/8[x02.xhtml]!/4/22/1:15)",
-      },
-    },
+    scrollLeft: 5416,
+    location: "epubcfi(/6/14[x05.xhtml]!/4/38/1:0)",
     time: "2022-01-01",
     time: "2022-01-01",
   },
   },
 ]);
 ]);
@@ -55,17 +52,18 @@ const show = computed({
   },
   },
 });
 });
 
 
-const addBookmark = () => {
-  const curLocation = epubStore.book?.rendition.currentLocation();
+const addBookmark = async () => {
+  const { startCfi, scrollLeft } = await epubStore.refreshLocation();
 
 
   list.value.push({
   list.value.push({
-    location: curLocation,
+    location: startCfi,
+    scrollLeft,
     time: formatDate(new Date(), "YYYY-MM-DD HH:mm:ss"),
     time: formatDate(new Date(), "YYYY-MM-DD HH:mm:ss"),
   });
   });
 };
 };
 
 
 const goToDetail = (item) => {
 const goToDetail = (item) => {
-  epubStore.goToChapter(item.location.start.cfi);
+  epubStore.goToChapter(item.location, item.scrollLeft);
 };
 };
 </script>
 </script>
 
 

+ 19 - 3
packages/pc/src/views/Detail/components/Reader/index.vue

@@ -43,12 +43,28 @@
     </Teleport>
     </Teleport>
 
 
     <div class="detail-text-pagination">
     <div class="detail-text-pagination">
-      <div class="detail-text-pagination__btn" @click="epubStore.prePage">
+      <div
+        class="detail-text-pagination__btn"
+        @click="
+          () => {
+            hideSelectMenu();
+            epubStore.prePage();
+          }
+        "
+      >
         <el-icon><ArrowLeft /></el-icon>
         <el-icon><ArrowLeft /></el-icon>
         上一页
         上一页
       </div>
       </div>
 
 
-      <div class="detail-text-pagination__btn" @click="epubStore.nextPage">
+      <div
+        class="detail-text-pagination__btn"
+        @click="
+          () => {
+            hideSelectMenu();
+            epubStore.nextPage();
+          }
+        "
+      >
         下一页
         下一页
         <el-icon><ArrowRight /></el-icon>
         <el-icon><ArrowRight /></el-icon>
       </div>
       </div>
@@ -73,7 +89,7 @@ const selectedCfiStack = ref([]);
 
 
 onMounted(() => {
 onMounted(() => {
   epubStore.init({
   epubStore.init({
-    url: "./test2.epub",
+    url: "./test.epub",
   });
   });
 
 
   epubStore.rendition.hooks.render.register((v) => {
   epubStore.rendition.hooks.render.register((v) => {

+ 12 - 13
packages/pc/src/views/Detail/components/Toolbar/index.vue

@@ -27,7 +27,7 @@
 </template>
 </template>
 
 
 <script setup>
 <script setup>
-import { ref, computed } from "vue";
+import { ref, computed, watch } from "vue";
 import { useFullscreen } from "@vueuse/core";
 import { useFullscreen } from "@vueuse/core";
 import { useEpubStore, useDetailStore } from "@/stores";
 import { useEpubStore, useDetailStore } from "@/stores";
 import Directory from "../Directory.vue";
 import Directory from "../Directory.vue";
@@ -37,7 +37,7 @@ import NoteDrawer from "../Note.vue";
 import Bookmark from "../Bookmark.vue";
 import Bookmark from "../Bookmark.vue";
 import Comment from "../Comment.vue";
 import Comment from "../Comment.vue";
 
 
-const { isSupported, toggle } = useFullscreen();
+const { isFullscreen, isSupported, toggle } = useFullscreen();
 const epubStore = useEpubStore();
 const epubStore = useEpubStore();
 const detailStore = useDetailStore();
 const detailStore = useDetailStore();
 const active = ref(-1);
 const active = ref(-1);
@@ -126,17 +126,7 @@ const handleToolbar = (key, idx) => {
       commentVisible.value = true;
       commentVisible.value = true;
       break;
       break;
     case "fullscreen":
     case "fullscreen":
-      toggle().then(() => {
-        setTimeout(() => {
-          const dom = document.getElementsByClassName("detail-text");
-          if (dom.length) {
-            epubStore.rendition.resize(
-              dom[0].clientWidth,
-              dom[0].clientHeight - 68
-            );
-          }
-        }, 50);
-      });
+      toggle();
       break;
       break;
   }
   }
 
 
@@ -146,6 +136,15 @@ const handleToolbar = (key, idx) => {
 const handleClose = () => {
 const handleClose = () => {
   active.value = -1;
   active.value = -1;
 };
 };
+
+watch(isFullscreen, () => {
+  setTimeout(() => {
+    const dom = document.getElementsByClassName("detail-text");
+    if (dom.length) {
+      epubStore.rendition.resize(dom[0].clientWidth, dom[0].clientHeight - 68);
+    }
+  }, 50);
+});
 </script>
 </script>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>