mirror of
				https://github.com/usememos/memos.git
				synced 2025-06-05 22:09:59 +02:00 
			
		
		
		
	chore: use axios instead of fetch
				
					
				
			This commit is contained in:
		| @@ -23,7 +23,6 @@ | ||||
|     ], | ||||
|     "@typescript-eslint/no-empty-interface": ["off"], | ||||
|     "@typescript-eslint/no-explicit-any": ["off"], | ||||
|     "react/react-in-jsx-scope": "off", | ||||
|     "@typescript-eslint/no-namespace": "off" | ||||
|     "react/react-in-jsx-scope": "off" | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "memos", | ||||
|   "version": "2.0.6", | ||||
|   "version": "0.0.1", | ||||
|   "scripts": { | ||||
|     "dev": "vite", | ||||
|     "build": "tsc && vite build", | ||||
| @@ -9,6 +9,7 @@ | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@reduxjs/toolkit": "^1.8.1", | ||||
|     "axios": "^0.27.2", | ||||
|     "lodash-es": "^4.17.21", | ||||
|     "react": "^18.1.0", | ||||
|     "react-dom": "^18.1.0", | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import { useEffect, useState } from "react"; | ||||
| import api from "../helpers/api"; | ||||
| import * as api from "../helpers/api"; | ||||
| import Only from "./common/OnlyWhen"; | ||||
| import { showDialog } from "./Dialog"; | ||||
| import "../less/about-site-dialog.less"; | ||||
| @@ -11,7 +11,10 @@ const AboutSiteDialog: React.FC<Props> = ({ destroy }: Props) => { | ||||
|  | ||||
|   useEffect(() => { | ||||
|     try { | ||||
|       api.getSystemStatus().then(({ profile }) => { | ||||
|       api.getSystemStatus().then(({ data }) => { | ||||
|         const { | ||||
|           data: { profile }, | ||||
|         } = data; | ||||
|         setProfile(profile); | ||||
|       }); | ||||
|     } catch (error) { | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import { IMAGE_URL_REG } from "../helpers/consts"; | ||||
| import utils from "../helpers/utils"; | ||||
| import * as utils from "../helpers/utils"; | ||||
| import { formatMemoContent } from "./Memo"; | ||||
| import Only from "./common/OnlyWhen"; | ||||
| import "../less/daily-memo.less"; | ||||
|   | ||||
| @@ -4,7 +4,7 @@ import toImage from "../labs/html2image"; | ||||
| import useToggle from "../hooks/useToggle"; | ||||
| import useLoading from "../hooks/useLoading"; | ||||
| import { DAILY_TIMESTAMP } from "../helpers/consts"; | ||||
| import utils from "../helpers/utils"; | ||||
| import * as utils from "../helpers/utils"; | ||||
| import { showDialog } from "./Dialog"; | ||||
| import showPreviewImageDialog from "./PreviewImageDialog"; | ||||
| import DailyMemo from "./DailyMemo"; | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import { IMAGE_URL_REG } from "../helpers/consts"; | ||||
| import utils from "../helpers/utils"; | ||||
| import * as utils from "../helpers/utils"; | ||||
| import useToggle from "../hooks/useToggle"; | ||||
| import { memoService } from "../services"; | ||||
| import Only from "./common/OnlyWhen"; | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import { memo } from "react"; | ||||
| import { escape } from "lodash-es"; | ||||
| import { IMAGE_URL_REG, LINK_REG, MEMO_LINK_REG, TAG_REG, UNKNOWN_ID } from "../helpers/consts"; | ||||
| import { parseMarkedToHtml, parseRawTextToHtml } from "../helpers/marked"; | ||||
| import utils from "../helpers/utils"; | ||||
| import * as utils from "../helpers/utils"; | ||||
| import useToggle from "../hooks/useToggle"; | ||||
| import { editorStateService, memoService } from "../services"; | ||||
| import Only from "./common/OnlyWhen"; | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import { useState, useEffect, useCallback } from "react"; | ||||
| import { IMAGE_URL_REG, MEMO_LINK_REG, UNKNOWN_ID } from "../helpers/consts"; | ||||
| import utils from "../helpers/utils"; | ||||
| import * as utils from "../helpers/utils"; | ||||
| import { editorStateService, memoService } from "../services"; | ||||
| import { parseHtmlToRawText } from "../helpers/marked"; | ||||
| import { formatMemoContent } from "./Memo"; | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useMemo, useRef } from "react"; | ||||
| import { editorStateService, locationService, memoService, resourceService } from "../services"; | ||||
| import { useAppSelector } from "../store"; | ||||
| import { UNKNOWN_ID } from "../helpers/consts"; | ||||
| import { storage } from "../helpers/storage"; | ||||
| import * as storage from "../helpers/storage"; | ||||
| import useToggle from "../hooks/useToggle"; | ||||
| import toastHelper from "./Toast"; | ||||
| import Editor, { EditorRefActions } from "./Editor/Editor"; | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import { useAppSelector } from "../store"; | ||||
| import { locationService, shortcutService } from "../services"; | ||||
| import utils from "../helpers/utils"; | ||||
| import * as utils from "../helpers/utils"; | ||||
| import { getTextWithMemoType } from "../helpers/filter"; | ||||
| import "../less/memo-filter.less"; | ||||
|  | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import { useCallback, useEffect, useRef, useState } from "react"; | ||||
| import { locationService, memoService, shortcutService } from "../services"; | ||||
| import { useAppSelector } from "../store"; | ||||
| import { IMAGE_URL_REG, LINK_REG, MEMO_LINK_REG, TAG_REG } from "../helpers/consts"; | ||||
| import utils from "../helpers/utils"; | ||||
| import * as utils from "../helpers/utils"; | ||||
| import { checkShouldShowMemoWithFilters } from "../helpers/filter"; | ||||
| import Memo from "./Memo"; | ||||
| import toastHelper from "./Toast"; | ||||
| @@ -79,6 +79,7 @@ const MemoList: React.FC<Props> = () => { | ||||
|   const pinnedMemos = shownMemos.filter((m) => m.pinned); | ||||
|   const unpinnedMemos = shownMemos.filter((m) => !m.pinned); | ||||
|   const sortedMemos = pinnedMemos.concat(unpinnedMemos).filter((m) => m.rowStatus === "NORMAL"); | ||||
|   console.log(memos.length, sortedMemos.length); | ||||
|  | ||||
|   useEffect(() => { | ||||
|     memoService | ||||
|   | ||||
| @@ -14,7 +14,6 @@ const MemoTrashDialog: React.FC<Props> = (props: Props) => { | ||||
|   const [deletedMemos, setDeletedMemos] = useState<Memo[]>([]); | ||||
|  | ||||
|   useEffect(() => { | ||||
|     memoService.fetchAllMemos(); | ||||
|     memoService | ||||
|       .fetchDeletedMemos() | ||||
|       .then((result) => { | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import { useEffect, useRef, useState } from "react"; | ||||
| import utils from "../helpers/utils"; | ||||
| import * as utils from "../helpers/utils"; | ||||
| import { showDialog } from "./Dialog"; | ||||
| import "../less/preview-image-dialog.less"; | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import React, { useEffect, useState } from "react"; | ||||
| import { isEmpty } from "lodash-es"; | ||||
| import api from "../../helpers/api"; | ||||
| import * as api from "../../helpers/api"; | ||||
| import toastHelper from "../Toast"; | ||||
| import "../../less/settings/member-section.less"; | ||||
|  | ||||
| @@ -23,7 +23,7 @@ const PreferencesSection: React.FC<Props> = () => { | ||||
|   }, []); | ||||
|  | ||||
|   const fetchUserList = async () => { | ||||
|     const data = await api.getUserList(); | ||||
|     const { data } = (await api.getUserList()).data; | ||||
|     setUserList(data); | ||||
|   }; | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import { memoService } from "../../services"; | ||||
| import utils from "../../helpers/utils"; | ||||
| import * as utils from "../../helpers/utils"; | ||||
| import toastHelper from "../Toast"; | ||||
| import "../../less/settings/preferences-section.less"; | ||||
|  | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import { useEffect, useRef, useState } from "react"; | ||||
| import { userService } from "../services"; | ||||
| import toImage from "../labs/html2image"; | ||||
| import { ANIMATION_DURATION, IMAGE_URL_REG } from "../helpers/consts"; | ||||
| import utils from "../helpers/utils"; | ||||
| import * as utils from "../helpers/utils"; | ||||
| import { showDialog } from "./Dialog"; | ||||
| import { formatMemoContent } from "./Memo"; | ||||
| import Only from "./common/OnlyWhen"; | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import { useEffect } from "react"; | ||||
| import { locationService, shortcutService } from "../services"; | ||||
| import { useAppSelector } from "../store"; | ||||
| import { UNKNOWN_ID } from "../helpers/consts"; | ||||
| import utils from "../helpers/utils"; | ||||
| import * as utils from "../helpers/utils"; | ||||
| import useToggle from "../hooks/useToggle"; | ||||
| import useLoading from "../hooks/useLoading"; | ||||
| import toastHelper from "./Toast"; | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import { useAppSelector } from "../store"; | ||||
| import utils from "../helpers/utils"; | ||||
| import * as utils from "../helpers/utils"; | ||||
| import showDailyMemoDiaryDialog from "./DailyMemoDiaryDialog"; | ||||
| import showSettingDialog from "./SettingDialog"; | ||||
| import showMemoTrashDialog from "./MemoTrashDialog"; | ||||
|   | ||||
| @@ -3,7 +3,7 @@ import { useAppSelector } from "../store"; | ||||
| import { locationService, memoService } from "../services"; | ||||
| import useToggle from "../hooks/useToggle"; | ||||
| import Only from "./common/OnlyWhen"; | ||||
| import utils from "../helpers/utils"; | ||||
| import * as utils from "../helpers/utils"; | ||||
| import "../less/tag-list.less"; | ||||
|  | ||||
| interface Tag { | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import { useCallback, useEffect, useRef, useState } from "react"; | ||||
| import { useAppSelector } from "../store"; | ||||
| import { locationService } from "../services"; | ||||
| import { DAILY_TIMESTAMP } from "../helpers/consts"; | ||||
| import utils from "../helpers/utils"; | ||||
| import * as utils from "../helpers/utils"; | ||||
| import "../less/usage-heat-map.less"; | ||||
|  | ||||
| const tableConfig = { | ||||
|   | ||||
| @@ -1,209 +1,99 @@ | ||||
| import axios from "axios"; | ||||
|  | ||||
| type ResponseObject<T> = { | ||||
|   data: T; | ||||
|   error?: string; | ||||
|   message?: string; | ||||
| }; | ||||
|  | ||||
| type RequestConfig = { | ||||
|   method: string; | ||||
|   url: string; | ||||
|   data?: any; | ||||
|   dataType?: "json" | "file"; | ||||
| }; | ||||
|  | ||||
| async function request<T>(config: RequestConfig): Promise<T> { | ||||
|   const { method, url, data, dataType } = config; | ||||
|   const requestConfig: RequestInit = { | ||||
|     method, | ||||
|   }; | ||||
|  | ||||
|   if (data !== undefined) { | ||||
|     if (dataType === "file") { | ||||
|       requestConfig.body = data; | ||||
|     } else { | ||||
|       requestConfig.headers = { | ||||
|         "Content-Type": "application/json", | ||||
|       }; | ||||
|       requestConfig.body = JSON.stringify(data); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   const response = await fetch(url, requestConfig); | ||||
|   const responseData = (await response.json()) as ResponseObject<T>; | ||||
|  | ||||
|   if (responseData.error || responseData.message) { | ||||
|     throw new Error(responseData.error || responseData.message); | ||||
|   } | ||||
|  | ||||
|   return responseData.data; | ||||
| export function getSystemStatus() { | ||||
|   return axios.get<ResponseObject<SystemStatus>>("/api/status"); | ||||
| } | ||||
|  | ||||
| namespace api { | ||||
|   export function getSystemStatus() { | ||||
|     return request<SystemStatus>({ | ||||
|       method: "GET", | ||||
|       url: "/api/status", | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   export function login(email: string, password: string) { | ||||
|     return request<User>({ | ||||
|       method: "POST", | ||||
|       url: "/api/auth/login", | ||||
|       data: { | ||||
| export function login(email: string, password: string) { | ||||
|   return axios.post<ResponseObject<User>>("/api/auth/login", { | ||||
|     email, | ||||
|     password, | ||||
|       }, | ||||
|   }); | ||||
|   } | ||||
| } | ||||
|  | ||||
|   export function signup(email: string, password: string, role: UserRole) { | ||||
|     return request<User>({ | ||||
|       method: "POST", | ||||
|       url: "/api/auth/signup", | ||||
|       data: { | ||||
| export function signup(email: string, password: string, role: UserRole) { | ||||
|   return axios.post<ResponseObject<User>>("/api/auth/signup", { | ||||
|     email, | ||||
|     password, | ||||
|     role, | ||||
|     name: email, | ||||
|       }, | ||||
|   }); | ||||
|   } | ||||
|  | ||||
|   export function signout() { | ||||
|     return request({ | ||||
|       method: "POST", | ||||
|       url: "/api/auth/logout", | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   export function createUser(userCreate: UserCreate) { | ||||
|     return request<User[]>({ | ||||
|       method: "POST", | ||||
|       url: "/api/user", | ||||
|       data: userCreate, | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   export function getUser() { | ||||
|     return request<User>({ | ||||
|       method: "GET", | ||||
|       url: "/api/user/me", | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   export function getUserList() { | ||||
|     return request<User[]>({ | ||||
|       method: "GET", | ||||
|       url: "/api/user", | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   export function patchUser(userPatch: UserPatch) { | ||||
|     return request<User>({ | ||||
|       method: "PATCH", | ||||
|       url: "/api/user/me", | ||||
|       data: userPatch, | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   export function getMyMemos() { | ||||
|     return request<Memo[]>({ | ||||
|       method: "GET", | ||||
|       url: "/api/memo", | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   export function getMyArchivedMemos() { | ||||
|     return request<Memo[]>({ | ||||
|       method: "GET", | ||||
|       url: "/api/memo?rowStatus=ARCHIVED", | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   export function createMemo(memoCreate: MemoCreate) { | ||||
|     return request<Memo>({ | ||||
|       method: "POST", | ||||
|       url: "/api/memo", | ||||
|       data: memoCreate, | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   export function patchMemo(memoPatch: MemoPatch) { | ||||
|     return request<Memo>({ | ||||
|       method: "PATCH", | ||||
|       url: `/api/memo/${memoPatch.id}`, | ||||
|       data: { | ||||
|         memoPatch, | ||||
|       }, | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   export function pinMemo(memoId: MemoId) { | ||||
|     return request({ | ||||
|       method: "POST", | ||||
|       url: `/api/memo/${memoId}/organizer`, | ||||
|       data: { | ||||
|         pinned: true, | ||||
|       }, | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   export function unpinMemo(memoId: MemoId) { | ||||
|     return request({ | ||||
|       method: "POST", | ||||
|       url: `/api/memo/${memoId}/organizer`, | ||||
|       data: { | ||||
|         pinned: false, | ||||
|       }, | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   export function deleteMemo(memoId: MemoId) { | ||||
|     return request({ | ||||
|       method: "DELETE", | ||||
|       url: `/api/memo/${memoId}`, | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   export function getMyShortcuts() { | ||||
|     return request<Shortcut[]>({ | ||||
|       method: "GET", | ||||
|       url: "/api/shortcut", | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   export function createShortcut(shortcutCreate: ShortcutCreate) { | ||||
|     return request<Shortcut>({ | ||||
|       method: "POST", | ||||
|       url: "/api/shortcut", | ||||
|       data: shortcutCreate, | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   export function patchShortcut(shortcutPatch: ShortcutPatch) { | ||||
|     return request<Shortcut>({ | ||||
|       method: "PATCH", | ||||
|       url: `/api/shortcut/${shortcutPatch.id}`, | ||||
|       data: shortcutPatch, | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   export function deleteShortcutById(shortcutId: ShortcutId) { | ||||
|     return request({ | ||||
|       method: "DELETE", | ||||
|       url: `/api/shortcut/${shortcutId}`, | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   export function uploadFile(formData: FormData) { | ||||
|     return request<Resource>({ | ||||
|       method: "POST", | ||||
|       url: "/api/resource", | ||||
|       data: formData, | ||||
|       dataType: "file", | ||||
|     }); | ||||
|   } | ||||
| } | ||||
|  | ||||
| export default api; | ||||
| export function signout() { | ||||
|   return axios.post("/api/auth/logout"); | ||||
| } | ||||
|  | ||||
| export function createUser(userCreate: UserCreate) { | ||||
|   return axios.post<ResponseObject<User>>("/api/user", userCreate); | ||||
| } | ||||
|  | ||||
| export function getUser() { | ||||
|   return axios.get<ResponseObject<User>>("/api/user/me"); | ||||
| } | ||||
|  | ||||
| export function getUserList() { | ||||
|   return axios.get<ResponseObject<User[]>>("/api/user"); | ||||
| } | ||||
|  | ||||
| export function patchUser(userPatch: UserPatch) { | ||||
|   return axios.patch<ResponseObject<User>>("/api/user/me", userPatch); | ||||
| } | ||||
|  | ||||
| export function getMyMemos() { | ||||
|   return axios.get<ResponseObject<Memo[]>>("/api/memo"); | ||||
| } | ||||
|  | ||||
| export function getMyArchivedMemos() { | ||||
|   return axios.get<ResponseObject<Memo[]>>("/api/memo?rowStatus=ARCHIVED"); | ||||
| } | ||||
|  | ||||
| export function createMemo(memoCreate: MemoCreate) { | ||||
|   return axios.post<ResponseObject<Memo>>("/api/memo", memoCreate); | ||||
| } | ||||
|  | ||||
| export function patchMemo(memoPatch: MemoPatch) { | ||||
|   return axios.patch<ResponseObject<Memo>>(`/api/memo/${memoPatch.id}`, memoPatch); | ||||
| } | ||||
|  | ||||
| export function pinMemo(memoId: MemoId) { | ||||
|   return axios.post(`/api/memo/${memoId}/organizer`, { | ||||
|     pinned: true, | ||||
|   }); | ||||
| } | ||||
|  | ||||
| export function unpinMemo(memoId: MemoId) { | ||||
|   return axios.post(`/api/memo/${memoId}/organizer`, { | ||||
|     pinned: false, | ||||
|   }); | ||||
| } | ||||
|  | ||||
| export function deleteMemo(memoId: MemoId) { | ||||
|   return axios.delete(`/api/memo/${memoId}`); | ||||
| } | ||||
|  | ||||
| export function getMyShortcuts() { | ||||
|   return axios.get<ResponseObject<Shortcut[]>>("/api/shortcut"); | ||||
| } | ||||
|  | ||||
| export function createShortcut(shortcutCreate: ShortcutCreate) { | ||||
|   return axios.post<ResponseObject<Shortcut>>("/api/shortcut", shortcutCreate); | ||||
| } | ||||
|  | ||||
| export function patchShortcut(shortcutPatch: ShortcutPatch) { | ||||
|   return axios.patch<ResponseObject<Shortcut>>(`/api/shortcut/${shortcutPatch.id}`, shortcutPatch); | ||||
| } | ||||
|  | ||||
| export function deleteShortcutById(shortcutId: ShortcutId) { | ||||
|   return axios.delete(`/api/shortcut/${shortcutId}`); | ||||
| } | ||||
|  | ||||
| export function uploadFile(formData: FormData) { | ||||
|   return axios.post<ResponseObject<Resource>>("/api/resource", formData); | ||||
| } | ||||
|   | ||||
| @@ -14,8 +14,7 @@ type StorageKey = keyof StorageData; | ||||
| /** | ||||
|  * storage helper | ||||
|  */ | ||||
| export namespace storage { | ||||
|   export function get(keys: StorageKey[]): Partial<StorageData> { | ||||
| export function get(keys: StorageKey[]): Partial<StorageData> { | ||||
|   const data: Partial<StorageData> = {}; | ||||
|  | ||||
|   for (const key of keys) { | ||||
| @@ -31,9 +30,9 @@ export namespace storage { | ||||
|   } | ||||
|  | ||||
|   return data; | ||||
|   } | ||||
| } | ||||
|  | ||||
|   export function set(data: Partial<StorageData>) { | ||||
| export function set(data: Partial<StorageData>) { | ||||
|   for (const key in data) { | ||||
|     try { | ||||
|       const stringifyValue = JSON.stringify(data[key as StorageKey]); | ||||
| @@ -42,9 +41,9 @@ export namespace storage { | ||||
|       console.error("Save storage failed in ", key, error); | ||||
|     } | ||||
|   } | ||||
|   } | ||||
| } | ||||
|  | ||||
|   export function remove(keys: StorageKey[]) { | ||||
| export function remove(keys: StorageKey[]) { | ||||
|   for (const key of keys) { | ||||
|     try { | ||||
|       localStorage.removeItem(key); | ||||
| @@ -52,14 +51,13 @@ export namespace storage { | ||||
|       console.error("Remove storage failed in ", key, error); | ||||
|     } | ||||
|   } | ||||
|   } | ||||
| } | ||||
|  | ||||
|   export function emitStorageChangedEvent() { | ||||
| export function emitStorageChangedEvent() { | ||||
|   const iframeEl = document.createElement("iframe"); | ||||
|   iframeEl.style.display = "none"; | ||||
|   document.body.appendChild(iframeEl); | ||||
|  | ||||
|   iframeEl.contentWindow?.localStorage.setItem("t", Date.now().toString()); | ||||
|   iframeEl.remove(); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,9 +1,8 @@ | ||||
| namespace utils { | ||||
|   export function getNowTimeStamp(): number { | ||||
| export function getNowTimeStamp(): number { | ||||
|   return Date.now(); | ||||
|   } | ||||
| } | ||||
|  | ||||
|   export function getOSVersion(): "Windows" | "MacOS" | "Linux" | "Unknown" { | ||||
| export function getOSVersion(): "Windows" | "MacOS" | "Linux" | "Unknown" { | ||||
|   const appVersion = navigator.userAgent; | ||||
|   let detectedOS: "Windows" | "MacOS" | "Linux" | "Unknown" = "Unknown"; | ||||
|  | ||||
| @@ -16,24 +15,24 @@ namespace utils { | ||||
|   } | ||||
|  | ||||
|   return detectedOS; | ||||
|   } | ||||
| } | ||||
|  | ||||
|   export function getTimeStampByDate(t: Date | number | string): number { | ||||
| export function getTimeStampByDate(t: Date | number | string): number { | ||||
|   if (typeof t === "string") { | ||||
|     t = t.replaceAll("-", "/"); | ||||
|   } | ||||
|   const d = new Date(t); | ||||
|  | ||||
|   return d.getTime(); | ||||
|   } | ||||
| } | ||||
|  | ||||
|   export function getDateStampByDate(t: Date | number | string): number { | ||||
| export function getDateStampByDate(t: Date | number | string): number { | ||||
|   const d = new Date(getTimeStampByDate(t)); | ||||
|  | ||||
|   return new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime(); | ||||
|   } | ||||
| } | ||||
|  | ||||
|   export function getDateString(t: Date | number | string): string { | ||||
| export function getDateString(t: Date | number | string): string { | ||||
|   const d = new Date(getTimeStampByDate(t)); | ||||
|  | ||||
|   const year = d.getFullYear(); | ||||
| @@ -41,13 +40,13 @@ namespace utils { | ||||
|   const date = d.getDate(); | ||||
|  | ||||
|   return `${year}/${month}/${date}`; | ||||
|   } | ||||
| } | ||||
|  | ||||
|   export function getDataStringWithTs(ts: number): string { | ||||
| export function getDataStringWithTs(ts: number): string { | ||||
|   return getDateTimeString(ts * 1000); | ||||
|   } | ||||
| } | ||||
|  | ||||
|   export function getTimeString(t: Date | number | string): string { | ||||
| export function getTimeString(t: Date | number | string): string { | ||||
|   const d = new Date(getTimeStampByDate(t)); | ||||
|  | ||||
|   const hours = d.getHours(); | ||||
| @@ -57,10 +56,10 @@ namespace utils { | ||||
|   const minsStr = mins < 10 ? "0" + mins : mins; | ||||
|  | ||||
|   return `${hoursStr}:${minsStr}`; | ||||
|   } | ||||
| } | ||||
|  | ||||
|   // For example: 2021-4-8 17:52:17 | ||||
|   export function getDateTimeString(t: Date | number | string): string { | ||||
| // For example: 2021-4-8 17:52:17 | ||||
| export function getDateTimeString(t: Date | number | string): string { | ||||
|   const d = new Date(getTimeStampByDate(t)); | ||||
|  | ||||
|   const year = d.getFullYear(); | ||||
| @@ -77,13 +76,13 @@ namespace utils { | ||||
|   const secsStr = secs < 10 ? "0" + secs : secs; | ||||
|  | ||||
|   return `${year}/${monthStr}/${dateStr} ${hoursStr}:${minsStr}:${secsStr}`; | ||||
|   } | ||||
| } | ||||
|  | ||||
|   export function dedupe<T>(data: T[]): T[] { | ||||
| export function dedupe<T>(data: T[]): T[] { | ||||
|   return Array.from(new Set(data)); | ||||
|   } | ||||
| } | ||||
|  | ||||
|   export function dedupeObjectWithId<T extends { id: string | number }>(data: T[]): T[] { | ||||
| export function dedupeObjectWithId<T extends { id: string | number }>(data: T[]): T[] { | ||||
|   const idSet = new Set<string | number>(); | ||||
|   const result = []; | ||||
|  | ||||
| @@ -95,9 +94,9 @@ namespace utils { | ||||
|   } | ||||
|  | ||||
|   return result; | ||||
|   } | ||||
| } | ||||
|  | ||||
|   export function debounce(fn: FunctionType, delay: number) { | ||||
| export function debounce(fn: FunctionType, delay: number) { | ||||
|   let timer: number | null = null; | ||||
|  | ||||
|   return () => { | ||||
| @@ -108,9 +107,9 @@ namespace utils { | ||||
|       timer = setTimeout(fn, delay); | ||||
|     } | ||||
|   }; | ||||
|   } | ||||
| } | ||||
|  | ||||
|   export function throttle(fn: FunctionType, delay: number) { | ||||
| export function throttle(fn: FunctionType, delay: number) { | ||||
|   let valid = true; | ||||
|  | ||||
|   return () => { | ||||
| @@ -123,9 +122,9 @@ namespace utils { | ||||
|       valid = true; | ||||
|     }, delay); | ||||
|   }; | ||||
|   } | ||||
| } | ||||
|  | ||||
|   export function transformObjectToParamsString(object: KVObject): string { | ||||
| export function transformObjectToParamsString(object: KVObject): string { | ||||
|   const params = []; | ||||
|   const keys = Object.keys(object).sort(); | ||||
|  | ||||
| @@ -141,9 +140,9 @@ namespace utils { | ||||
|   } | ||||
|  | ||||
|   return params.join("&"); | ||||
|   } | ||||
| } | ||||
|  | ||||
|   export function transformParamsStringToObject(paramsString: string): KVObject { | ||||
| export function transformParamsStringToObject(paramsString: string): KVObject { | ||||
|   const object: KVObject = {}; | ||||
|   const params = paramsString.split("&"); | ||||
|  | ||||
| @@ -155,9 +154,9 @@ namespace utils { | ||||
|   } | ||||
|  | ||||
|   return object; | ||||
|   } | ||||
| } | ||||
|  | ||||
|   export function filterObjectNullKeys(object: KVObject): KVObject { | ||||
| export function filterObjectNullKeys(object: KVObject): KVObject { | ||||
|   if (!object) { | ||||
|     return {}; | ||||
|   } | ||||
| @@ -180,9 +179,9 @@ namespace utils { | ||||
|   } | ||||
|  | ||||
|   return finalObject; | ||||
|   } | ||||
| } | ||||
|  | ||||
|   export async function copyTextToClipboard(text: string) { | ||||
| export async function copyTextToClipboard(text: string) { | ||||
|   if (navigator.clipboard && navigator.clipboard.writeText) { | ||||
|     try { | ||||
|       await navigator.clipboard.writeText(text); | ||||
| @@ -192,9 +191,9 @@ namespace utils { | ||||
|   } else { | ||||
|     console.warn("Copy to clipboard failed, methods not supports."); | ||||
|   } | ||||
|   } | ||||
| } | ||||
|  | ||||
|   export function getImageSize(src: string): Promise<{ width: number; height: number }> { | ||||
| export function getImageSize(src: string): Promise<{ width: number; height: number }> { | ||||
|   return new Promise((resolve) => { | ||||
|     const imgEl = new Image(); | ||||
|  | ||||
| @@ -217,7 +216,4 @@ namespace utils { | ||||
|     document.body.appendChild(imgEl); | ||||
|     imgEl.remove(); | ||||
|   }); | ||||
|   } | ||||
| } | ||||
|  | ||||
| export default utils; | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import { useEffect, useState } from "react"; | ||||
| import api from "../helpers/api"; | ||||
| import * as api from "../helpers/api"; | ||||
| import { validate, ValidatorConfig } from "../helpers/validator"; | ||||
| import useLoading from "../hooks/useLoading"; | ||||
| import { locationService, userService } from "../services"; | ||||
| @@ -23,7 +23,8 @@ const Signin: React.FC<Props> = () => { | ||||
|   const actionBtnLoadingState = useLoading(false); | ||||
|  | ||||
|   useEffect(() => { | ||||
|     api.getSystemStatus().then((status) => { | ||||
|     api.getSystemStatus().then(({ data }) => { | ||||
|       const { data: status } = data; | ||||
|       setSiteOwner(status.owner); | ||||
|       if (status.profile.mode === "dev") { | ||||
|         setEmail("demo@usememos.com"); | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import utils from "../helpers/utils"; | ||||
| import * as utils from "../helpers/utils"; | ||||
| import store from "../store"; | ||||
| import { setQuery, setPathname, Query } from "../store/modules/location"; | ||||
|  | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import api from "../helpers/api"; | ||||
| import * as api from "../helpers/api"; | ||||
| import { TAG_REG } from "../helpers/consts"; | ||||
| import { createMemo, patchMemo, setMemos, setTags } from "../store/modules/memo"; | ||||
| import store from "../store"; | ||||
| @@ -17,7 +17,7 @@ const memoService = { | ||||
|   }, | ||||
|  | ||||
|   fetchAllMemos: async () => { | ||||
|     const data = await api.getMyMemos(); | ||||
|     const { data } = (await api.getMyMemos()).data; | ||||
|     const memos = data.filter((m) => m.rowStatus !== "ARCHIVED").map((m) => convertResponseModelMemo(m)); | ||||
|     store.dispatch(setMemos(memos)); | ||||
|  | ||||
| @@ -25,7 +25,7 @@ const memoService = { | ||||
|   }, | ||||
|  | ||||
|   fetchDeletedMemos: async () => { | ||||
|     const data = await api.getMyArchivedMemos(); | ||||
|     const { data } = (await api.getMyArchivedMemos()).data; | ||||
|     const deletedMemos = data.map((m) => { | ||||
|       return convertResponseModelMemo(m); | ||||
|     }); | ||||
| @@ -60,13 +60,13 @@ const memoService = { | ||||
|   }, | ||||
|  | ||||
|   createMemo: async (memoCreate: MemoCreate) => { | ||||
|     const data = await api.createMemo(memoCreate); | ||||
|     const { data } = (await api.createMemo(memoCreate)).data; | ||||
|     const memo = convertResponseModelMemo(data); | ||||
|     store.dispatch(createMemo(memo)); | ||||
|   }, | ||||
|  | ||||
|   patchMemo: async (memoPatch: MemoPatch): Promise<Memo> => { | ||||
|     const data = await api.patchMemo(memoPatch); | ||||
|     const { data } = (await api.patchMemo(memoPatch)).data; | ||||
|     const memo = convertResponseModelMemo(data); | ||||
|     store.dispatch(patchMemo(memo)); | ||||
|     return memo; | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import api from "../helpers/api"; | ||||
| import * as api from "../helpers/api"; | ||||
|  | ||||
| const resourceService = { | ||||
|   /** | ||||
| @@ -6,7 +6,7 @@ const resourceService = { | ||||
|    * @param file file | ||||
|    * @returns resource: id, filename | ||||
|    */ | ||||
|   async upload(file: File) { | ||||
|   async upload(file: File): Promise<Resource> { | ||||
|     const { name: filename, size } = file; | ||||
|  | ||||
|     if (size > 64 << 20) { | ||||
| @@ -15,7 +15,7 @@ const resourceService = { | ||||
|  | ||||
|     const formData = new FormData(); | ||||
|     formData.append("file", file, filename); | ||||
|     const data = await api.uploadFile(formData); | ||||
|     const { data } = (await api.uploadFile(formData)).data; | ||||
|  | ||||
|     return data; | ||||
|   }, | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import api from "../helpers/api"; | ||||
| import * as api from "../helpers/api"; | ||||
| import store from "../store/"; | ||||
| import { createShortcut, deleteShortcut, patchShortcut, setShortcuts } from "../store/modules/shortcut"; | ||||
|  | ||||
| @@ -16,8 +16,8 @@ const shortcutService = { | ||||
|   }, | ||||
|  | ||||
|   getMyAllShortcuts: async () => { | ||||
|     const rawData = await api.getMyShortcuts(); | ||||
|     const shortcuts = rawData.map((s) => convertResponseModelShortcut(s)); | ||||
|     const { data } = (await api.getMyShortcuts()).data; | ||||
|     const shortcuts = data.map((s) => convertResponseModelShortcut(s)); | ||||
|     store.dispatch(setShortcuts(shortcuts)); | ||||
|   }, | ||||
|  | ||||
| @@ -32,13 +32,13 @@ const shortcutService = { | ||||
|   }, | ||||
|  | ||||
|   createShortcut: async (shortcutCreate: ShortcutCreate) => { | ||||
|     const data = await api.createShortcut(shortcutCreate); | ||||
|     const { data } = (await api.createShortcut(shortcutCreate)).data; | ||||
|     const shortcut = convertResponseModelShortcut(data); | ||||
|     store.dispatch(createShortcut(shortcut)); | ||||
|   }, | ||||
|  | ||||
|   patchShortcut: async (shortcutPatch: ShortcutPatch) => { | ||||
|     const data = await api.patchShortcut(shortcutPatch); | ||||
|     const { data } = (await api.patchShortcut(shortcutPatch)).data; | ||||
|     const shortcut = convertResponseModelShortcut(data); | ||||
|     store.dispatch(patchShortcut(shortcut)); | ||||
|   }, | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import api from "../helpers/api"; | ||||
| import * as api from "../helpers/api"; | ||||
| import store from "../store"; | ||||
| import { setUser, patchUser } from "../store/modules/user"; | ||||
|  | ||||
| @@ -16,7 +16,7 @@ const userService = { | ||||
|   }, | ||||
|  | ||||
|   doSignIn: async () => { | ||||
|     const user = await api.getUser(); | ||||
|     const { data: user } = (await api.getUser()).data; | ||||
|     if (user) { | ||||
|       store.dispatch(setUser(convertResponseModelUser(user))); | ||||
|     } else { | ||||
| @@ -31,7 +31,7 @@ const userService = { | ||||
|   }, | ||||
|  | ||||
|   patchUser: async (userPatch: UserPatch): Promise<void> => { | ||||
|     const data = await api.patchUser(userPatch); | ||||
|     const { data } = (await api.patchUser(userPatch)).data; | ||||
|     const user = convertResponseModelUser(data); | ||||
|     store.dispatch(patchUser(user)); | ||||
|   }, | ||||
|   | ||||
| @@ -589,6 +589,11 @@ array.prototype.flatmap@^1.2.5: | ||||
|     es-abstract "^1.19.2" | ||||
|     es-shim-unscopables "^1.0.0" | ||||
|  | ||||
| asynckit@^0.4.0: | ||||
|   version "0.4.0" | ||||
|   resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" | ||||
|   integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== | ||||
|  | ||||
| autoprefixer@^10.4.2: | ||||
|   version "10.4.4" | ||||
|   resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.4.tgz#3e85a245b32da876a893d3ac2ea19f01e7ea5a1e" | ||||
| @@ -601,6 +606,14 @@ autoprefixer@^10.4.2: | ||||
|     picocolors "^1.0.0" | ||||
|     postcss-value-parser "^4.2.0" | ||||
|  | ||||
| axios@^0.27.2: | ||||
|   version "0.27.2" | ||||
|   resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" | ||||
|   integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== | ||||
|   dependencies: | ||||
|     follow-redirects "^1.14.9" | ||||
|     form-data "^4.0.0" | ||||
|  | ||||
| balanced-match@^1.0.0: | ||||
|   version "1.0.2" | ||||
|   resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" | ||||
| @@ -716,6 +729,13 @@ color-name@^1.1.4, color-name@~1.1.4: | ||||
|   resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" | ||||
|   integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== | ||||
|  | ||||
| combined-stream@^1.0.8: | ||||
|   version "1.0.8" | ||||
|   resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" | ||||
|   integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== | ||||
|   dependencies: | ||||
|     delayed-stream "~1.0.0" | ||||
|  | ||||
| concat-map@0.0.1: | ||||
|   version "0.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" | ||||
| @@ -785,6 +805,11 @@ defined@^1.0.0: | ||||
|   resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" | ||||
|   integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= | ||||
|  | ||||
| delayed-stream@~1.0.0: | ||||
|   version "1.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" | ||||
|   integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= | ||||
|  | ||||
| detective@^5.2.0: | ||||
|   version "5.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/detective/-/detective-5.2.0.tgz#feb2a77e85b904ecdea459ad897cc90a99bd2a7b" | ||||
| @@ -1234,6 +1259,20 @@ flatted@^3.1.0: | ||||
|   resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" | ||||
|   integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== | ||||
|  | ||||
| follow-redirects@^1.14.9: | ||||
|   version "1.15.0" | ||||
|   resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.0.tgz#06441868281c86d0dda4ad8bdaead2d02dca89d4" | ||||
|   integrity sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ== | ||||
|  | ||||
| form-data@^4.0.0: | ||||
|   version "4.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" | ||||
|   integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== | ||||
|   dependencies: | ||||
|     asynckit "^0.4.0" | ||||
|     combined-stream "^1.0.8" | ||||
|     mime-types "^2.1.12" | ||||
|  | ||||
| fraction.js@^4.2.0: | ||||
|   version "4.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" | ||||
| @@ -1665,6 +1704,18 @@ micromatch@^4.0.4: | ||||
|     braces "^3.0.2" | ||||
|     picomatch "^2.3.1" | ||||
|  | ||||
| mime-db@1.52.0: | ||||
|   version "1.52.0" | ||||
|   resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" | ||||
|   integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== | ||||
|  | ||||
| mime-types@^2.1.12: | ||||
|   version "2.1.35" | ||||
|   resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" | ||||
|   integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== | ||||
|   dependencies: | ||||
|     mime-db "1.52.0" | ||||
|  | ||||
| mime@^1.4.1: | ||||
|   version "1.6.0" | ||||
|   resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user