index.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. import ajax from "./axios";
  2. import { ElMessage } from "element-plus/es";
  3. /** https://github.com/gedoor/legado/tree/master/app/src/main/java/io/legado/app/api */
  4. /** https://github.com/gedoor/legado/tree/master/app/src/main/java/io/legado/app/web */
  5. let legado_http_origin;
  6. let legado_webSocket_origin;
  7. const setLeagdoHttpUrl = (http_url) => {
  8. let legado_webSocket_port;
  9. const { protocol, hostname, port } = new URL(http_url);
  10. if (!protocol.startsWith("http"))
  11. throw new Error("unexpect protocol:" + http_url);
  12. ajax.defaults.baseURL = http_url;
  13. legado_http_origin = http_url;
  14. if (port !== "") {
  15. legado_webSocket_port = Number(port) + 1;
  16. } else {
  17. legado_webSocket_port = protocol.startsWith("https:") ? "444" : "81";
  18. }
  19. legado_webSocket_origin = `${protocol.startsWith("https:") ? "wss://" : "ws://"}${hostname}:${legado_webSocket_port}`;
  20. console.info("legado_server_config:");
  21. console.table({ legado_http_origin, legado_webSocket_origin });
  22. };
  23. // 手动初始化 阅读web服务地址
  24. setLeagdoHttpUrl(ajax.defaults.baseURL);
  25. const testLeagdoHttpUrlConnection = async (http_url) => {
  26. const { data = {} } = await ajax.get("/getReadConfig", {
  27. baseURL: http_url,
  28. timeout: 3000,
  29. });
  30. // 返回结果应该是JSON 并有键值isSuccess
  31. try {
  32. if ("isSuccess" in data) return data.data;
  33. throw new Error("ReadConfig后端返回格式错误");
  34. } catch {
  35. throw new Error("ReadConfig后端返回格式错误");
  36. }
  37. };
  38. const isSourecEditor = /source/i.test(location.href);
  39. const APIExceptionHandler = (error) => {
  40. if (isSourecEditor) {
  41. ElMessage({
  42. message: "后端错误,检查网络或者阅读app",
  43. type: "error",
  44. });
  45. }
  46. throw error;
  47. };
  48. ajax.interceptors.response.use((response) => response, APIExceptionHandler);
  49. // 书架API
  50. // Http
  51. /** @returns {Promise<import("axios").AxiosResponse<{isSuccess: boolean, data: string, errorMsg:string}>>} */
  52. const getReadConfig = () => ajax.get("/getReadConfig", { timeout: 3000 });
  53. const saveReadConfig = (config) => ajax.post("/saveReadConfig", config);
  54. const saveBookProgress = (bookProgress) =>
  55. ajax.post("/saveBookProgress", bookProgress);
  56. const saveBookProgressWithBeacon = (bookProgress) => {
  57. if (!bookProgress) return;
  58. // 常规请求可能会被取消 使用Fetch keep-alive 或者 navigator.sendBeacon
  59. navigator.sendBeacon(
  60. `${legado_http_origin}/saveBookProgress`,
  61. JSON.stringify(bookProgress),
  62. );
  63. };
  64. const getBookShelf = () => ajax.get("/getBookshelf");
  65. const getChapterList = (/** @type {string} */ bookUrl) =>
  66. ajax.get("/getChapterList?url=" + encodeURIComponent(bookUrl));
  67. const getBookContent = (
  68. /** @type {string} */ bookUrl,
  69. /** @type {number} */ chapterIndex,
  70. ) =>
  71. ajax.get(
  72. "/getBookContent?url=" +
  73. encodeURIComponent(bookUrl) +
  74. "&index=" +
  75. chapterIndex,
  76. );
  77. // webSocket
  78. const search = (
  79. /** @type {string} */ searchKey,
  80. /** @type {(data: string) => void} */ onReceive,
  81. /** @type {() => void} */ onFinish,
  82. ) => {
  83. const url = `${legado_webSocket_origin}/searchBook`;
  84. const socket = new WebSocket(url);
  85. socket.onopen = () => {
  86. socket.send(`{"key":"${searchKey}"}`);
  87. };
  88. socket.onmessage = ({ data }) => onReceive(data);
  89. socket.onclose = () => {
  90. onFinish();
  91. };
  92. };
  93. const saveBook = (book) => ajax.post("/saveBook", book);
  94. const deleteBook = (book) => ajax.post("/deleteBook", book);
  95. const isBookSource = /bookSource/i.test(location.href);
  96. // 源编辑API
  97. // Http
  98. const getSources = () =>
  99. isBookSource ? ajax.get("/getBookSources") : ajax.get("/getRssSources");
  100. const saveSource = (data) =>
  101. isBookSource
  102. ? ajax.post("/saveBookSource", data)
  103. : ajax.post("/saveRssSource", data);
  104. const saveSources = (data) =>
  105. isBookSource
  106. ? ajax.post("/saveBookSources", data)
  107. : ajax.post("/saveRssSources", data);
  108. const deleteSource = (data) =>
  109. isBookSource
  110. ? ajax.post("/deleteBookSources", data)
  111. : ajax.post("/deleteRssSources", data);
  112. // webSocket
  113. const debug = (
  114. /** @type {string} */ sourceUrl,
  115. /** @type {string} */ searchKey,
  116. /** @type {(data: string) => void} */ onReceive,
  117. /** @type {() => void} */ onFinish,
  118. ) => {
  119. const url = `${legado_webSocket_origin}/${
  120. isBookSource ? "bookSource" : "rssSource"
  121. }Debug`;
  122. const socket = new WebSocket(url);
  123. socket.onopen = () => {
  124. socket.send(JSON.stringify({ tag: sourceUrl, key: searchKey }));
  125. };
  126. socket.onmessage = ({ data }) => onReceive(data);
  127. socket.onclose = () => {
  128. ElMessage({
  129. message: "调试已关闭!",
  130. type: "info",
  131. });
  132. onFinish();
  133. };
  134. };
  135. /**
  136. * 从阅读获取需要特定处理的书籍封面
  137. * @param {string} coverUrl
  138. */
  139. const getProxyCoverUrl = (coverUrl) => {
  140. if (coverUrl.startsWith(legado_http_origin)) return coverUrl;
  141. return legado_http_origin + "/cover?path=" + encodeURIComponent(coverUrl);
  142. };
  143. /**
  144. * 从阅读获取需要特定处理的图片
  145. * @param {string} src
  146. * @param {number|`${number}`} width
  147. */
  148. const getProxyImageUrl = (src, width) => {
  149. if (src.startsWith(legado_http_origin)) return src;
  150. return (
  151. legado_http_origin +
  152. "/image?path=" +
  153. encodeURIComponent(src) +
  154. "&url=" +
  155. encodeURIComponent(sessionStorage.getItem("bookUrl")) +
  156. "&width=" +
  157. width
  158. );
  159. };
  160. export default {
  161. getReadConfig,
  162. saveReadConfig,
  163. saveBookProgress,
  164. saveBookProgressWithBeacon,
  165. getBookShelf,
  166. getChapterList,
  167. getBookContent,
  168. search,
  169. saveBook,
  170. deleteBook,
  171. getSources,
  172. saveSources,
  173. saveSource,
  174. deleteSource,
  175. debug,
  176. getProxyCoverUrl,
  177. getProxyImageUrl,
  178. testLeagdoHttpUrlConnection,
  179. setLeagdoHttpUrl,
  180. legado_http_origin,
  181. };