| @@ -1,12 +1,11 @@ | |||||
| import axios from 'axios' | import axios from 'axios' | ||||
| import toCamel from 'camelcase-keys' | |||||
| import { useEffect, useState } from 'react' | import { useEffect, useState } from 'react' | ||||
| import { BrowserRouter, Navigate, Route, Routes, useLocation } from 'react-router-dom' | import { BrowserRouter, Navigate, Route, Routes, useLocation } from 'react-router-dom' | ||||
| import RouteBlockerOverlay from '@/components/RouteBlockerOverlay' | import RouteBlockerOverlay from '@/components/RouteBlockerOverlay' | ||||
| import TopNav from '@/components/TopNav' | import TopNav from '@/components/TopNav' | ||||
| import { Toaster } from '@/components/ui/toaster' | import { Toaster } from '@/components/ui/toaster' | ||||
| import { API_BASE_URL } from '@/config' | |||||
| import { apiPost } from '@/lib/api' | |||||
| import NicoTagListPage from '@/pages/tags/NicoTagListPage' | import NicoTagListPage from '@/pages/tags/NicoTagListPage' | ||||
| import NotFound from '@/pages/NotFound' | import NotFound from '@/pages/NotFound' | ||||
| import PostDetailPage from '@/pages/posts/PostDetailPage' | import PostDetailPage from '@/pages/posts/PostDetailPage' | ||||
| @@ -40,12 +39,11 @@ export default (() => { | |||||
| useEffect (() => { | useEffect (() => { | ||||
| const createUser = async () => { | const createUser = async () => { | ||||
| const res = await axios.post (`${ API_BASE_URL }/users`) | |||||
| const data = res.data as { code: string; user: any } | |||||
| const data = await apiPost<{ code: string; user: User }> ('/users') | |||||
| if (data.code) | if (data.code) | ||||
| { | { | ||||
| localStorage.setItem ('user_code', data.code) | localStorage.setItem ('user_code', data.code) | ||||
| setUser (toCamel (data.user, { deep: true }) as User) | |||||
| setUser (data.user) | |||||
| } | } | ||||
| } | } | ||||
| @@ -55,10 +53,9 @@ export default (() => { | |||||
| void (async () => { | void (async () => { | ||||
| try | try | ||||
| { | { | ||||
| const res = await axios.post (`${ API_BASE_URL }/users/verify`, { code }) | |||||
| const data = res.data as { valid: boolean, user: any } | |||||
| const data = await apiPost<{ valid: boolean; user: User }> ('/users/verify', { code }) | |||||
| if (data.valid) | if (data.valid) | ||||
| setUser (toCamel (data.user, { deep: true })) | |||||
| setUser (data.user) | |||||
| else | else | ||||
| await createUser () | await createUser () | ||||
| } | } | ||||
| @@ -1,11 +1,9 @@ | |||||
| import axios from 'axios' | |||||
| import toCamel from 'camelcase-keys' | |||||
| import { useRef, useState } from 'react' | import { useRef, useState } from 'react' | ||||
| import TagSearchBox from '@/components/TagSearchBox' | import TagSearchBox from '@/components/TagSearchBox' | ||||
| import Label from '@/components/common/Label' | import Label from '@/components/common/Label' | ||||
| import TextArea from '@/components/common/TextArea' | import TextArea from '@/components/common/TextArea' | ||||
| import { API_BASE_URL } from '@/config' | |||||
| import { apiGet } from '@/lib/api' | |||||
| import type { FC, SyntheticEvent } from 'react' | import type { FC, SyntheticEvent } from 'react' | ||||
| @@ -59,8 +57,7 @@ export default (({ tags, setTags }: Props) => { | |||||
| const recompute = async (pos: number, v: string = tags) => { | const recompute = async (pos: number, v: string = tags) => { | ||||
| const { start, end, token } = getTokenAt (v, pos) | const { start, end, token } = getTokenAt (v, pos) | ||||
| setBounds ({ start, end }) | setBounds ({ start, end }) | ||||
| const res = await axios.get (`${ API_BASE_URL }/tags/autocomplete`, { params: { q: token } }) | |||||
| const data = toCamel (res.data as any, { deep: true }) as Tag[] | |||||
| const data = await apiGet<Tag[]> ('/tags/autocomplete', { params: { q: token } }) | |||||
| setSuggestions (data.filter (t => t.postCount > 0)) | setSuggestions (data.filter (t => t.postCount > 0)) | ||||
| setSuggestionsVsbl (suggestions.length > 0) | setSuggestionsVsbl (suggestions.length > 0) | ||||
| } | } | ||||
| @@ -6,8 +6,6 @@ import { DndContext, | |||||
| useSensor, | useSensor, | ||||
| useSensors } from '@dnd-kit/core' | useSensors } from '@dnd-kit/core' | ||||
| import { restrictToWindowEdges } from '@dnd-kit/modifiers' | import { restrictToWindowEdges } from '@dnd-kit/modifiers' | ||||
| import axios from 'axios' | |||||
| import toCamel from 'camelcase-keys' | |||||
| import { AnimatePresence, motion } from 'framer-motion' | import { AnimatePresence, motion } from 'framer-motion' | ||||
| import { useEffect, useRef, useState } from 'react' | import { useEffect, useRef, useState } from 'react' | ||||
| @@ -19,8 +17,8 @@ import SectionTitle from '@/components/common/SectionTitle' | |||||
| import SubsectionTitle from '@/components/common/SubsectionTitle' | import SubsectionTitle from '@/components/common/SubsectionTitle' | ||||
| import SidebarComponent from '@/components/layout/SidebarComponent' | import SidebarComponent from '@/components/layout/SidebarComponent' | ||||
| import { toast } from '@/components/ui/use-toast' | import { toast } from '@/components/ui/use-toast' | ||||
| import { API_BASE_URL } from '@/config' | |||||
| import { CATEGORIES } from '@/consts' | import { CATEGORIES } from '@/consts' | ||||
| import { apiDelete, apiGet, apiPatch, apiPost } from '@/lib/api' | |||||
| import type { DragEndEvent } from '@dnd-kit/core' | import type { DragEndEvent } from '@dnd-kit/core' | ||||
| import type { FC, MutableRefObject, ReactNode } from 'react' | import type { FC, MutableRefObject, ReactNode } from 'react' | ||||
| @@ -132,10 +130,7 @@ const changeCategory = async ( | |||||
| tagId: number, | tagId: number, | ||||
| category: Category, | category: Category, | ||||
| ): Promise<void> => { | ): Promise<void> => { | ||||
| await axios.patch ( | |||||
| `${ API_BASE_URL }/tags/${ tagId }`, | |||||
| { category }, | |||||
| { headers: { 'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } }) | |||||
| await apiPatch (`/tags/${ tagId }`, { category }) | |||||
| } | } | ||||
| @@ -170,12 +165,7 @@ export default (({ post }: Props) => { | |||||
| if (!(post)) | if (!(post)) | ||||
| return | return | ||||
| const res = await axios.get ( | |||||
| `${ API_BASE_URL }/posts/${ post.id }`, | |||||
| { headers: { 'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } }) | |||||
| const data = toCamel (res.data as any, { deep: true }) as Post | |||||
| setTags (buildTagByCategory (data)) | |||||
| setTags (buildTagByCategory (await apiGet<Post> (`/posts/${ post.id }`))) | |||||
| } | } | ||||
| const onDragEnd = async (e: DragEndEvent) => { | const onDragEnd = async (e: DragEndEvent) => { | ||||
| @@ -216,16 +206,9 @@ export default (({ post }: Props) => { | |||||
| return | return | ||||
| if (fromParentId != null) | if (fromParentId != null) | ||||
| { | |||||
| await axios.delete ( | |||||
| `${ API_BASE_URL }/tags/${ fromParentId }/children/${ childId }`, | |||||
| { headers: { 'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } }) | |||||
| } | |||||
| await apiDelete (`/tags/${ fromParentId }/children/${ childId }`) | |||||
| await axios.post ( | |||||
| `${ API_BASE_URL }/tags/${ parentId }/children/${ childId }`, | |||||
| { }, | |||||
| { headers: { 'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } }) | |||||
| await apiPost (`/tags/${ parentId }/children/${ childId }`, { }) | |||||
| await reloadTags () | await reloadTags () | ||||
| toast ({ | toast ({ | ||||
| @@ -245,11 +228,7 @@ export default (({ post }: Props) => { | |||||
| await changeCategory (childId, cat) | await changeCategory (childId, cat) | ||||
| if (fromParentId != null) | if (fromParentId != null) | ||||
| { | |||||
| await axios.delete ( | |||||
| `${ API_BASE_URL }/tags/${ fromParentId }/children/${ childId }`, | |||||
| { headers: { 'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } }) | |||||
| } | |||||
| await apiDelete (`/tags/${ fromParentId }/children/${ childId }`) | |||||
| const fromParent = fromParentId == null ? null : findTag (tags, fromParentId) | const fromParent = fromParentId == null ? null : findTag (tags, fromParentId) | ||||
| @@ -1,20 +1,20 @@ | |||||
| import axios from 'axios' | |||||
| import { useEffect, useState } from 'react' | import { useEffect, useState } from 'react' | ||||
| import PrefetchLink from '@/components/PrefetchLink' | import PrefetchLink from '@/components/PrefetchLink' | ||||
| import { API_BASE_URL } from '@/config' | |||||
| import { LIGHT_COLOUR_SHADE, DARK_COLOUR_SHADE, TAG_COLOUR } from '@/consts' | import { LIGHT_COLOUR_SHADE, DARK_COLOUR_SHADE, TAG_COLOUR } from '@/consts' | ||||
| import { apiGet } from '@/lib/api' | |||||
| import { cn } from '@/lib/utils' | import { cn } from '@/lib/utils' | ||||
| import type { ComponentProps, FC, HTMLAttributes } from 'react' | import type { ComponentProps, FC, HTMLAttributes } from 'react' | ||||
| import type { Tag } from '@/types' | import type { Tag } from '@/types' | ||||
| type CommonProps = { tag: Tag | |||||
| nestLevel?: number | |||||
| withWiki?: boolean | |||||
| withCount?: boolean | |||||
| prefetch?: boolean } | |||||
| type CommonProps = { | |||||
| tag: Tag | |||||
| nestLevel?: number | |||||
| withWiki?: boolean | |||||
| withCount?: boolean | |||||
| prefetch?: boolean } | |||||
| type PropsWithLink = | type PropsWithLink = | ||||
| & CommonProps | & CommonProps | ||||
| @@ -26,7 +26,9 @@ type PropsWithoutLink = | |||||
| & { linkFlg: false } | & { linkFlg: false } | ||||
| & Partial<HTMLAttributes<HTMLSpanElement>> | & Partial<HTMLAttributes<HTMLSpanElement>> | ||||
| type Props = PropsWithLink | PropsWithoutLink | |||||
| type Props = | |||||
| | PropsWithLink | |||||
| | PropsWithoutLink | |||||
| export default (({ tag, | export default (({ tag, | ||||
| @@ -49,7 +51,7 @@ export default (({ tag, | |||||
| try | try | ||||
| { | { | ||||
| await axios.get (`${ API_BASE_URL }/wiki/title/${ encodeURIComponent (tagName) }/exists`) | |||||
| await apiGet (`/wiki/title/${ encodeURIComponent (tagName) }/exists`) | |||||
| setHavingWiki (true) | setHavingWiki (true) | ||||
| } | } | ||||
| catch | catch | ||||
| @@ -1,13 +1,11 @@ | |||||
| import axios from 'axios' | |||||
| import toCamel from 'camelcase-keys' | |||||
| import React, { useEffect, useState } from 'react' | |||||
| import { useEffect, useState } from 'react' | |||||
| import { useNavigate, useLocation } from 'react-router-dom' | import { useNavigate, useLocation } from 'react-router-dom' | ||||
| import { API_BASE_URL } from '@/config' | |||||
| import { apiGet } from '@/lib/api' | |||||
| import TagSearchBox from './TagSearchBox' | import TagSearchBox from './TagSearchBox' | ||||
| import type { FC } from 'react' | |||||
| import type { ChangeEvent, FC, KeyboardEvent } from 'react' | |||||
| import type { Tag } from '@/types' | import type { Tag } from '@/types' | ||||
| @@ -21,7 +19,7 @@ export default (() => { | |||||
| const [suggestions, setSuggestions] = useState<Tag[]> ([]) | const [suggestions, setSuggestions] = useState<Tag[]> ([]) | ||||
| const [suggestionsVsbl, setSuggestionsVsbl] = useState (false) | const [suggestionsVsbl, setSuggestionsVsbl] = useState (false) | ||||
| const whenChanged = async (ev: React.ChangeEvent<HTMLInputElement>) => { | |||||
| const whenChanged = async (ev: ChangeEvent<HTMLInputElement>) => { | |||||
| setSearch (ev.target.value) | setSearch (ev.target.value) | ||||
| const q = ev.target.value.trim ().split (' ').at (-1) | const q = ev.target.value.trim ().split (' ').at (-1) | ||||
| @@ -31,14 +29,13 @@ export default (() => { | |||||
| return | return | ||||
| } | } | ||||
| const res = await axios.get (`${ API_BASE_URL }/tags/autocomplete`, { params: { q } }) | |||||
| const data = toCamel (res.data, { deep: true }) as Tag[] | |||||
| const data = await apiGet<Tag[]> ('/tags/autocomplete', { params: { q } }) | |||||
| setSuggestions (data.filter (t => t.postCount > 0)) | setSuggestions (data.filter (t => t.postCount > 0)) | ||||
| if (suggestions.length > 0) | if (suggestions.length > 0) | ||||
| setSuggestionsVsbl (true) | setSuggestionsVsbl (true) | ||||
| } | } | ||||
| const handleKeyDown = (ev: React.KeyboardEvent<HTMLInputElement>) => { | |||||
| const handleKeyDown = (ev: KeyboardEvent<HTMLInputElement>) => { | |||||
| switch (ev.key) | switch (ev.key) | ||||
| { | { | ||||
| case 'ArrowDown': | case 'ArrowDown': | ||||
| @@ -1,4 +1,3 @@ | |||||
| import axios from 'axios' | |||||
| import { AnimatePresence, motion } from 'framer-motion' | import { AnimatePresence, motion } from 'framer-motion' | ||||
| import { useEffect, useState } from 'react' | import { useEffect, useState } from 'react' | ||||
| import { useLocation, useNavigate } from 'react-router-dom' | import { useLocation, useNavigate } from 'react-router-dom' | ||||
| @@ -7,8 +6,8 @@ import TagLink from '@/components/TagLink' | |||||
| import TagSearch from '@/components/TagSearch' | import TagSearch from '@/components/TagSearch' | ||||
| import SectionTitle from '@/components/common/SectionTitle' | import SectionTitle from '@/components/common/SectionTitle' | ||||
| import SidebarComponent from '@/components/layout/SidebarComponent' | import SidebarComponent from '@/components/layout/SidebarComponent' | ||||
| import { API_BASE_URL } from '@/config' | |||||
| import { CATEGORIES } from '@/consts' | import { CATEGORIES } from '@/consts' | ||||
| import { apiGet } from '@/lib/api' | |||||
| import type { FC, MouseEvent } from 'react' | import type { FC, MouseEvent } from 'react' | ||||
| @@ -77,10 +76,10 @@ export default (({ posts, onClick }: Props) => { | |||||
| void ((async () => { | void ((async () => { | ||||
| try | try | ||||
| { | { | ||||
| const { data } = await axios.get (`${ API_BASE_URL }/posts/random`, | |||||
| { params: { tags: tagsQuery.split (' ').filter (e => e !== '').join (' '), | |||||
| const data = await apiGet<Post> ('/posts/random', | |||||
| { params: { tags: tagsQuery.split (' ').filter (e => e !== '').join (' '), | |||||
| match: (anyFlg ? 'any' : 'all') } }) | match: (anyFlg ? 'any' : 'all') } }) | ||||
| navigate (`/posts/${ (data as Post).id }`) | |||||
| navigate (`/posts/${ data.id }`) | |||||
| } | } | ||||
| catch | catch | ||||
| { | { | ||||
| @@ -1,5 +1,3 @@ | |||||
| import axios from 'axios' | |||||
| import toCamel from 'camelcase-keys' | |||||
| import { useEffect, useMemo, useState } from 'react' | import { useEffect, useMemo, useState } from 'react' | ||||
| import ReactMarkdown from 'react-markdown' | import ReactMarkdown from 'react-markdown' | ||||
| import remarkGFM from 'remark-gfm' | import remarkGFM from 'remark-gfm' | ||||
| @@ -7,7 +5,7 @@ import remarkGFM from 'remark-gfm' | |||||
| import PrefetchLink from '@/components/PrefetchLink' | import PrefetchLink from '@/components/PrefetchLink' | ||||
| import SectionTitle from '@/components/common/SectionTitle' | import SectionTitle from '@/components/common/SectionTitle' | ||||
| import SubsectionTitle from '@/components/common/SubsectionTitle' | import SubsectionTitle from '@/components/common/SubsectionTitle' | ||||
| import { API_BASE_URL } from '@/config' | |||||
| import { apiGet } from '@/lib/api' | |||||
| import remarkWikiAutoLink from '@/lib/remark-wiki-autolink' | import remarkWikiAutoLink from '@/lib/remark-wiki-autolink' | ||||
| import type { FC } from 'react' | import type { FC } from 'react' | ||||
| @@ -43,8 +41,7 @@ export default (({ title, body }: Props) => { | |||||
| void (async () => { | void (async () => { | ||||
| try | try | ||||
| { | { | ||||
| const res = await axios.get (`${ API_BASE_URL }/wiki`) | |||||
| const data: WikiPage[] = toCamel (res.data as any, { deep: true }) | |||||
| const data = await apiGet<WikiPage[]> ('/wiki') | |||||
| setPageNames (data.map (page => page.title).sort ((a, b) => b.length - a.length)) | setPageNames (data.map (page => page.title).sort ((a, b) => b.length - a.length)) | ||||
| } | } | ||||
| catch | catch | ||||
| @@ -1,5 +1,3 @@ | |||||
| import axios from 'axios' | |||||
| import toCamel from 'camelcase-keys' | |||||
| import { useState } from 'react' | import { useState } from 'react' | ||||
| import { Button } from '@/components/ui/button' | import { Button } from '@/components/ui/button' | ||||
| @@ -8,7 +6,7 @@ import { Dialog, | |||||
| DialogTitle } from '@/components/ui/dialog' | DialogTitle } from '@/components/ui/dialog' | ||||
| import { Input } from '@/components/ui/input' | import { Input } from '@/components/ui/input' | ||||
| import { toast } from '@/components/ui/use-toast' | import { toast } from '@/components/ui/use-toast' | ||||
| import { API_BASE_URL } from '@/config' | |||||
| import { apiPost } from '@/lib/api' | |||||
| import type { User } from '@/types' | import type { User } from '@/types' | ||||
| @@ -26,12 +24,12 @@ export default ({ visible, onVisibleChange, setUser }: Props) => { | |||||
| try | try | ||||
| { | { | ||||
| const res = await axios.post (`${ API_BASE_URL }/users/verify`, { code: inputCode }) | |||||
| const data = res.data as { valid: boolean; user: any } | |||||
| const data = await apiPost<{ valid: boolean; user: User }> ( | |||||
| '/users/verify', { code: inputCode }) | |||||
| if (data.valid) | if (data.valid) | ||||
| { | { | ||||
| localStorage.setItem ('user_code', inputCode) | localStorage.setItem ('user_code', inputCode) | ||||
| setUser (toCamel (data.user, { deep: true })) | |||||
| setUser (data.user) | |||||
| toast ({ title: '引継ぎ成功!' }) | toast ({ title: '引継ぎ成功!' }) | ||||
| onVisibleChange (false) | onVisibleChange (false) | ||||
| } | } | ||||
| @@ -1,11 +1,9 @@ | |||||
| import axios from 'axios' | |||||
| import { Button } from '@/components/ui/button' | import { Button } from '@/components/ui/button' | ||||
| import { Dialog, | import { Dialog, | ||||
| DialogContent, | DialogContent, | ||||
| DialogTitle } from '@/components/ui/dialog' | DialogTitle } from '@/components/ui/dialog' | ||||
| import { toast } from '@/components/ui/use-toast' | import { toast } from '@/components/ui/use-toast' | ||||
| import { API_BASE_URL } from '@/config' | |||||
| import { apiPost } from '@/lib/api' | |||||
| import type { User } from '@/types' | import type { User } from '@/types' | ||||
| @@ -23,10 +21,8 @@ export default ({ visible, onVisibleChange, user, setUser }: Props) => { | |||||
| if (!(confirm ('引継ぎコードを再発行しますか?\n再発行するとほかのブラウザからはログアウトされます.'))) | if (!(confirm ('引継ぎコードを再発行しますか?\n再発行するとほかのブラウザからはログアウトされます.'))) | ||||
| return | return | ||||
| const res = await axios.post (`${ API_BASE_URL }/users/code/renew`, { }, { headers: { | |||||
| 'Content-Type': 'multipart/form-data', | |||||
| 'X-Transfer-Code': localStorage.getItem ('user_code') || '' } }) | |||||
| const data = res.data as { code: string } | |||||
| const data = await apiPost<{ code: string }> ('/users/code/renew', { }, | |||||
| { headers: { 'Content-Type': 'multipart/form-data' } }) | |||||
| if (data.code) | if (data.code) | ||||
| { | { | ||||
| localStorage.setItem ('user_code', data.code) | localStorage.setItem ('user_code', data.code) | ||||
| @@ -4,8 +4,9 @@ import toCamel from 'camelcase-keys' | |||||
| import { API_BASE_URL } from '@/config' | import { API_BASE_URL } from '@/config' | ||||
| type Opt = { | type Opt = { | ||||
| params?: Record<string, unknown> | |||||
| headers?: Record<string, string> } | |||||
| params?: Record<string, unknown> | |||||
| headers?: Record<string, string> | |||||
| responseType?: 'blob' } | |||||
| const client = axios.create ({ baseURL: API_BASE_URL }) | const client = axios.create ({ baseURL: API_BASE_URL }) | ||||
| @@ -1,4 +1,3 @@ | |||||
| import axios from 'axios' | |||||
| import { useEffect, useState, useRef } from 'react' | import { useEffect, useState, useRef } from 'react' | ||||
| import { Helmet } from 'react-helmet-async' | import { Helmet } from 'react-helmet-async' | ||||
| import { useNavigate } from 'react-router-dom' | import { useNavigate } from 'react-router-dom' | ||||
| @@ -11,7 +10,8 @@ import PageTitle from '@/components/common/PageTitle' | |||||
| import MainArea from '@/components/layout/MainArea' | import MainArea from '@/components/layout/MainArea' | ||||
| import { Button } from '@/components/ui/button' | import { Button } from '@/components/ui/button' | ||||
| import { toast } from '@/components/ui/use-toast' | import { toast } from '@/components/ui/use-toast' | ||||
| import { API_BASE_URL, SITE_TITLE } from '@/config' | |||||
| import { SITE_TITLE } from '@/config' | |||||
| import { apiGet, apiPost } from '@/lib/api' | |||||
| import Forbidden from '@/pages/Forbidden' | import Forbidden from '@/pages/Forbidden' | ||||
| import type { FC } from 'react' | import type { FC } from 'react' | ||||
| @@ -55,9 +55,7 @@ export default (({ user }: Props) => { | |||||
| try | try | ||||
| { | { | ||||
| await axios.post (`${ API_BASE_URL }/posts`, formData, { headers: { | |||||
| 'Content-Type': 'multipart/form-data', | |||||
| 'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } }) | |||||
| await apiPost ('/posts', formData, { headers: { 'Content-Type': 'multipart/form-data' } }) | |||||
| toast ({ title: '投稿成功!' }) | toast ({ title: '投稿成功!' }) | ||||
| navigate ('/posts') | navigate ('/posts') | ||||
| } | } | ||||
| @@ -91,10 +89,7 @@ export default (({ user }: Props) => { | |||||
| const fetchTitle = async () => { | const fetchTitle = async () => { | ||||
| setTitle ('') | setTitle ('') | ||||
| setTitleLoading (true) | setTitleLoading (true) | ||||
| const res = await axios.get (`${ API_BASE_URL }/preview/title`, { | |||||
| params: { url }, | |||||
| headers: { 'X-Transfer-Code': localStorage.getItem ('user_code') || '' } }) | |||||
| const data = res.data as { title: string } | |||||
| const data = await apiGet<{ title: string }> ('/preview/title', { params: { url } }) | |||||
| setTitle (data.title || '') | setTitle (data.title || '') | ||||
| setTitleLoading (false) | setTitleLoading (false) | ||||
| } | } | ||||
| @@ -105,11 +100,8 @@ export default (({ user }: Props) => { | |||||
| setThumbnailLoading (true) | setThumbnailLoading (true) | ||||
| if (thumbnailPreview) | if (thumbnailPreview) | ||||
| URL.revokeObjectURL (thumbnailPreview) | URL.revokeObjectURL (thumbnailPreview) | ||||
| const res = await axios.get (`${ API_BASE_URL }/preview/thumbnail`, { | |||||
| params: { url }, | |||||
| headers: { 'X-Transfer-Code': localStorage.getItem ('user_code') || '' }, | |||||
| responseType: 'blob' }) | |||||
| const data = res.data as Blob | |||||
| const data = await apiGet<Blob> ('/preview/thumbnail', | |||||
| { params: { url }, responseType: 'blob' }) | |||||
| const imageURL = URL.createObjectURL (data) | const imageURL = URL.createObjectURL (data) | ||||
| setThumbnailPreview (imageURL) | setThumbnailPreview (imageURL) | ||||
| setThumbnailFile (new File ([data], | setThumbnailFile (new File ([data], | ||||
| @@ -1,5 +1,3 @@ | |||||
| import axios from 'axios' | |||||
| import toCamel from 'camelcase-keys' | |||||
| import { useEffect, useRef, useState } from 'react' | import { useEffect, useRef, useState } from 'react' | ||||
| import { Helmet } from 'react-helmet-async' | import { Helmet } from 'react-helmet-async' | ||||
| @@ -8,7 +6,8 @@ import SectionTitle from '@/components/common/SectionTitle' | |||||
| import TextArea from '@/components/common/TextArea' | import TextArea from '@/components/common/TextArea' | ||||
| import MainArea from '@/components/layout/MainArea' | import MainArea from '@/components/layout/MainArea' | ||||
| import { toast } from '@/components/ui/use-toast' | import { toast } from '@/components/ui/use-toast' | ||||
| import { API_BASE_URL, SITE_TITLE } from '@/config' | |||||
| import { SITE_TITLE } from '@/config' | |||||
| import { apiGet, apiPut } from '@/lib/api' | |||||
| import type { NicoTag, Tag, User } from '@/types' | import type { NicoTag, Tag, User } from '@/types' | ||||
| @@ -29,10 +28,8 @@ export default ({ user }: Props) => { | |||||
| const loadMore = async (withCursor: boolean) => { | const loadMore = async (withCursor: boolean) => { | ||||
| setLoading (true) | setLoading (true) | ||||
| const res = await axios.get (`${ API_BASE_URL }/tags/nico`, { | |||||
| params: { ...(withCursor ? { cursor } : { }) } }) | |||||
| const data = toCamel (res.data as any, { deep: true }) as { tags: NicoTag[] | |||||
| nextCursor: string } | |||||
| const data = await apiGet<{ tags: NicoTag[]; nextCursor: string }> ( | |||||
| '/tags/nico', { params: withCursor ? { cursor } : { } }) | |||||
| setNicoTags (tags => [...(withCursor ? tags : []), ...data.tags]) | setNicoTags (tags => [...(withCursor ? tags : []), ...data.tags]) | ||||
| setCursor (data.nextCursor) | setCursor (data.nextCursor) | ||||
| @@ -53,10 +50,8 @@ export default ({ user }: Props) => { | |||||
| const formData = new FormData | const formData = new FormData | ||||
| formData.append ('tags', rawTags[id]) | formData.append ('tags', rawTags[id]) | ||||
| const res = await axios.put (`${ API_BASE_URL }/tags/nico/${ id }`, formData, { headers: { | |||||
| 'Content-Type': 'multipart/form-data', | |||||
| 'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } }) | |||||
| const data = toCamel (res.data as any, { deep: true }) as Tag[] | |||||
| const data = await apiPut<Tag[]> (`/tags/nico/${ id }`, formData, | |||||
| { headers: { 'Content-Type': 'multipart/form-data' } }) | |||||
| setNicoTags (nicoTags => { | setNicoTags (nicoTags => { | ||||
| nicoTags.find (t => t.id === id)!.linkedTags = data | nicoTags.find (t => t.id === id)!.linkedTags = data | ||||
| return [...nicoTags] | return [...nicoTags] | ||||
| @@ -1,4 +1,3 @@ | |||||
| import axios from 'axios' | |||||
| import { useEffect, useState } from 'react' | import { useEffect, useState } from 'react' | ||||
| import { Helmet } from 'react-helmet-async' | import { Helmet } from 'react-helmet-async' | ||||
| @@ -10,7 +9,8 @@ import InheritDialogue from '@/components/users/InheritDialogue' | |||||
| import UserCodeDialogue from '@/components/users/UserCodeDialogue' | import UserCodeDialogue from '@/components/users/UserCodeDialogue' | ||||
| import { Button } from '@/components/ui/button' | import { Button } from '@/components/ui/button' | ||||
| import { toast } from '@/components/ui/use-toast' | import { toast } from '@/components/ui/use-toast' | ||||
| import { API_BASE_URL, SITE_TITLE } from '@/config' | |||||
| import { SITE_TITLE } from '@/config' | |||||
| import { apiPut } from '@/lib/api' | |||||
| import type { User } from '@/types' | import type { User } from '@/types' | ||||
| @@ -32,10 +32,9 @@ export default ({ user, setUser }: Props) => { | |||||
| try | try | ||||
| { | { | ||||
| const res = await axios.put (`${ API_BASE_URL }/users/${ user.id }`, formData, { | |||||
| headers: { 'Content-Type': 'multipart/form-data', | |||||
| 'X-Transfer-Code': localStorage.getItem ('user_code') || '' } }) | |||||
| const data = res.data as User | |||||
| const data = await apiPut<User> ( | |||||
| `/users/${ user.id }`, formData, | |||||
| { headers: { 'Content-Type': 'multipart/form-data' } }) | |||||
| setUser (user => ({ ...user, ...data })) | setUser (user => ({ ...user, ...data })) | ||||
| toast ({ title: '設定を更新しました.' }) | toast ({ title: '設定を更新しました.' }) | ||||
| } | } | ||||
| @@ -1,12 +1,11 @@ | |||||
| import axios from 'axios' | |||||
| import toCamel from 'camelcase-keys' | |||||
| import { useEffect, useState } from 'react' | import { useEffect, useState } from 'react' | ||||
| import { Helmet } from 'react-helmet-async' | import { Helmet } from 'react-helmet-async' | ||||
| import { useLocation, useParams } from 'react-router-dom' | import { useLocation, useParams } from 'react-router-dom' | ||||
| import PageTitle from '@/components/common/PageTitle' | import PageTitle from '@/components/common/PageTitle' | ||||
| import MainArea from '@/components/layout/MainArea' | import MainArea from '@/components/layout/MainArea' | ||||
| import { API_BASE_URL, SITE_TITLE } from '@/config' | |||||
| import { SITE_TITLE } from '@/config' | |||||
| import { apiGet } from '@/lib/api' | |||||
| import { cn } from '@/lib/utils' | import { cn } from '@/lib/utils' | ||||
| import type { WikiPageDiff } from '@/types' | import type { WikiPageDiff } from '@/types' | ||||
| @@ -25,8 +24,7 @@ export default () => { | |||||
| useEffect (() => { | useEffect (() => { | ||||
| void (async () => { | void (async () => { | ||||
| const res = await axios.get (`${ API_BASE_URL }/wiki/${ id }/diff`, { params: { from, to } }) | |||||
| setDiff (toCamel (res.data as any, { deep: true }) as WikiPageDiff) | |||||
| setDiff (await apiGet<WikiPageDiff> (`/wiki/${ id }/diff`, { params: { from, to } })) | |||||
| }) () | }) () | ||||
| }, []) | }, []) | ||||
| @@ -1,4 +1,3 @@ | |||||
| import axios from 'axios' | |||||
| import MarkdownIt from 'markdown-it' | import MarkdownIt from 'markdown-it' | ||||
| import { useEffect, useState } from 'react' | import { useEffect, useState } from 'react' | ||||
| import { Helmet } from 'react-helmet-async' | import { Helmet } from 'react-helmet-async' | ||||
| @@ -7,7 +6,8 @@ import { useParams, useNavigate } from 'react-router-dom' | |||||
| import MainArea from '@/components/layout/MainArea' | import MainArea from '@/components/layout/MainArea' | ||||
| import { toast } from '@/components/ui/use-toast' | import { toast } from '@/components/ui/use-toast' | ||||
| import { API_BASE_URL, SITE_TITLE } from '@/config' | |||||
| import { SITE_TITLE } from '@/config' | |||||
| import { apiGet, apiPut } from '@/lib/api' | |||||
| import Forbidden from '@/pages/Forbidden' | import Forbidden from '@/pages/Forbidden' | ||||
| import 'react-markdown-editor-lite/lib/index.css' | import 'react-markdown-editor-lite/lib/index.css' | ||||
| @@ -40,9 +40,8 @@ export default (({ user }: Props) => { | |||||
| try | try | ||||
| { | { | ||||
| await axios.put (`${ API_BASE_URL }/wiki/${ id }`, formData, { headers: { | |||||
| 'Content-Type': 'multipart/form-data', | |||||
| 'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } }) | |||||
| await apiPut (`/wiki/${ id }`, formData, | |||||
| { headers: { 'Content-Type': 'multipart/form-data' } }) | |||||
| toast ({ title: '投稿成功!' }) | toast ({ title: '投稿成功!' }) | ||||
| navigate (`/wiki/${ title }`) | navigate (`/wiki/${ title }`) | ||||
| } | } | ||||
| @@ -55,8 +54,7 @@ export default (({ user }: Props) => { | |||||
| useEffect (() => { | useEffect (() => { | ||||
| void (async () => { | void (async () => { | ||||
| setLoading (true) | setLoading (true) | ||||
| const res = await axios.get (`${ API_BASE_URL }/wiki/${ id }`) | |||||
| const data = res.data as WikiPage | |||||
| const data = await apiGet<WikiPage> (`/wiki/${ id }`) | |||||
| setTitle (data.title) | setTitle (data.title) | ||||
| setBody (data.body) | setBody (data.body) | ||||
| setLoading (false) | setLoading (false) | ||||
| @@ -1,12 +1,11 @@ | |||||
| import axios from 'axios' | |||||
| import toCamel from 'camelcase-keys' | |||||
| import { useEffect, useState } from 'react' | import { useEffect, useState } from 'react' | ||||
| import { Helmet } from 'react-helmet-async' | import { Helmet } from 'react-helmet-async' | ||||
| import { useLocation } from 'react-router-dom' | import { useLocation } from 'react-router-dom' | ||||
| import PrefetchLink from '@/components/PrefetchLink' | import PrefetchLink from '@/components/PrefetchLink' | ||||
| import MainArea from '@/components/layout/MainArea' | import MainArea from '@/components/layout/MainArea' | ||||
| import { API_BASE_URL, SITE_TITLE } from '@/config' | |||||
| import { SITE_TITLE } from '@/config' | |||||
| import { apiGet } from '@/lib/api' | |||||
| import type { WikiPageChange } from '@/types' | import type { WikiPageChange } from '@/types' | ||||
| @@ -20,9 +19,7 @@ export default () => { | |||||
| useEffect (() => { | useEffect (() => { | ||||
| void (async () => { | void (async () => { | ||||
| const res = await axios.get (`${ API_BASE_URL }/wiki/changes`, | |||||
| { params: { ...(id ? { id } : { }) } }) | |||||
| setChanges (toCamel (res.data as any, { deep: true }) as WikiPageChange[]) | |||||
| setChanges (await apiGet<WikiPageChange[]> ('/wiki/changes', { params: id ? { id } : { } })) | |||||
| }) () | }) () | ||||
| }, [location.search]) | }, [location.search]) | ||||