This commit is contained in:
@@ -3,6 +3,7 @@ import YoutubeEmbed from 'react-youtube'
|
|||||||
|
|
||||||
import NicoViewer from '@/components/NicoViewer'
|
import NicoViewer from '@/components/NicoViewer'
|
||||||
import TwitterEmbed from '@/components/TwitterEmbed'
|
import TwitterEmbed from '@/components/TwitterEmbed'
|
||||||
|
import { useDialogue } from '@/components/dialogues/DialogueProvider'
|
||||||
|
|
||||||
import type { FC, RefObject } from 'react'
|
import type { FC, RefObject } from 'react'
|
||||||
|
|
||||||
@@ -16,6 +17,8 @@ type Props = {
|
|||||||
|
|
||||||
|
|
||||||
export default (({ ref, post, onLoadComplete, onMetadataChange }: Props) => {
|
export default (({ ref, post, onLoadComplete, onMetadataChange }: Props) => {
|
||||||
|
const dialogue = useDialogue ()
|
||||||
|
|
||||||
const url = new URL (post.url)
|
const url = new URL (post.url)
|
||||||
|
|
||||||
switch (url.hostname.split ('.').slice (-2).join ('.'))
|
switch (url.hostname.split ('.').slice (-2).join ('.'))
|
||||||
@@ -82,12 +85,17 @@ export default (({ ref, post, onLoadComplete, onMetadataChange }: Props) => {
|
|||||||
height={360}/>)
|
height={360}/>)
|
||||||
: (
|
: (
|
||||||
<div>
|
<div>
|
||||||
<a href="#" onClick={e => {
|
<a href="#" onClick={async e => {
|
||||||
e.preventDefault ()
|
e.preventDefault ()
|
||||||
setFramed (confirm ('未確認の外部ページを表示します。\n'
|
|
||||||
+ '悪意のあるスクリプトが実行される可能性があります。\n'
|
setFramed (await dialogue.confirm ({
|
||||||
+ '表示しますか?'))
|
title: '未確認の外部ページを表示します。',
|
||||||
return
|
description: (
|
||||||
|
<div>
|
||||||
|
<p>悪意のあるスクリプトが実行される可能性があります。</p>
|
||||||
|
<p>表示しますか?</p>
|
||||||
|
</div>),
|
||||||
|
confirmText: '表示' }))
|
||||||
}}>
|
}}>
|
||||||
外部ページを表示
|
外部ページを表示
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ type Props = Omit<ComponentPropsWithoutRef<'textarea'>, 'value' | 'onChange' | '
|
|||||||
setTags: (tags: string) => void }
|
setTags: (tags: string) => void }
|
||||||
|
|
||||||
|
|
||||||
export default (({ tags, setTags, onBlur, ...rest }: Props) => {
|
export default (({ tags, setTags, ...rest }: Props) => {
|
||||||
const ref = useRef<HTMLTextAreaElement> (null)
|
const ref = useRef<HTMLTextAreaElement> (null)
|
||||||
|
|
||||||
const [bounds, setBounds] = useState<{ start: number; end: number }> ({ start: 0, end: 0 })
|
const [bounds, setBounds] = useState<{ start: number; end: number }> ({ start: 0, end: 0 })
|
||||||
@@ -85,10 +85,9 @@ export default (({ tags, setTags, onBlur, ...rest }: Props) => {
|
|||||||
await recompute (pos)
|
await recompute (pos)
|
||||||
}}
|
}}
|
||||||
onFocus={() => setFocused (true)}
|
onFocus={() => setFocused (true)}
|
||||||
onBlur={ev => {
|
onBlur={() => {
|
||||||
setFocused (false)
|
setFocused (false)
|
||||||
setSuggestionsVsbl (false)
|
setSuggestionsVsbl (false)
|
||||||
onBlur?.(ev)
|
|
||||||
}}/>
|
}}/>
|
||||||
{focused && (
|
{focused && (
|
||||||
<TagSearchBox
|
<TagSearchBox
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
|
|
||||||
|
import { useDialogue } from '@/components/dialogues/DialogueProvider'
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import { Dialog,
|
import { Dialog,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogTitle } from '@/components/ui/dialog'
|
DialogDescription,
|
||||||
|
DialogHeader,
|
||||||
|
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 { apiPost } from '@/lib/api'
|
import { apiPost } from '@/lib/api'
|
||||||
@@ -16,10 +19,16 @@ type Props = { visible: boolean
|
|||||||
|
|
||||||
|
|
||||||
export default ({ visible, onVisibleChange, setUser }: Props) => {
|
export default ({ visible, onVisibleChange, setUser }: Props) => {
|
||||||
|
const dialogue = useDialogue ()
|
||||||
|
|
||||||
const [inputCode, setInputCode] = useState ('')
|
const [inputCode, setInputCode] = useState ('')
|
||||||
|
|
||||||
const handleTransfer = async () => {
|
const handleTransfer = async () => {
|
||||||
if (!(confirm ('引継ぎを行ってもよろしいですか?\n現在のアカウントからはログアウトされます.')))
|
if (!(await dialogue.confirm ({
|
||||||
|
title: '引継ぎを行ってもよろしいですか?',
|
||||||
|
description: '現在のアカウントからはログアウトされます.',
|
||||||
|
confirmText: '引継ぐ',
|
||||||
|
variant: 'danger' })))
|
||||||
return
|
return
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -44,14 +53,18 @@ export default ({ visible, onVisibleChange, setUser }: Props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={visible} onOpenChange={onVisibleChange}>
|
<Dialog open={visible} onOpenChange={onVisibleChange}>
|
||||||
<DialogContent>
|
<DialogContent className="px-6 pp-6 pt-7">
|
||||||
<DialogTitle>ほかのブラウザから引継ぐ</DialogTitle>
|
<DialogHeader className="pl-8">
|
||||||
<div className="flex gap-2">
|
<DialogTitle>ほかのブラウザから引継ぐ</DialogTitle>
|
||||||
<Input placeholder="引継ぎコードを入力"
|
<DialogDescription asChild>
|
||||||
value={inputCode}
|
<div className="flex gap-2">
|
||||||
onChange={ev => setInputCode (ev.target.value)}/>
|
<Input placeholder="引継ぎコードを入力"
|
||||||
<Button onClick={handleTransfer}>引継ぐ</Button>
|
value={inputCode}
|
||||||
</div>
|
onChange={ev => setInputCode (ev.target.value)}/>
|
||||||
|
<Button onClick={handleTransfer}>引継ぐ</Button>
|
||||||
|
</div>
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>)
|
</Dialog>)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
|
import { useDialogue } from '@/components/dialogues/DialogueProvider'
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import { Dialog,
|
import { Dialog,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
|
DialogDescription,
|
||||||
|
DialogFooter,
|
||||||
|
DialogHeader,
|
||||||
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 { apiPost } from '@/lib/api'
|
import { apiPost } from '@/lib/api'
|
||||||
@@ -14,11 +18,20 @@ type Props = { visible: boolean
|
|||||||
|
|
||||||
|
|
||||||
export default ({ visible, onVisibleChange, user, setUser }: Props) => {
|
export default ({ visible, onVisibleChange, user, setUser }: Props) => {
|
||||||
|
const dialogue = useDialogue ()
|
||||||
|
|
||||||
const handleChange = async () => {
|
const handleChange = async () => {
|
||||||
if (!(user))
|
if (!(user))
|
||||||
return
|
return
|
||||||
|
|
||||||
if (!(confirm ('引継ぎコードを再発行しますか?\n再発行するとほかのブラウザからはログアウトされます.')))
|
if (!(await dialogue.confirm ({
|
||||||
|
title: '引継ぎコードを再発行しますか?',
|
||||||
|
description: (
|
||||||
|
<div>
|
||||||
|
<p>再発行するとほかのブラウザからはログアウトされます.</p>
|
||||||
|
</div>),
|
||||||
|
confirmText: '再発行',
|
||||||
|
variant: 'danger' })))
|
||||||
return
|
return
|
||||||
|
|
||||||
const data = await apiPost<{ code: string }> ('/users/code/renew', { },
|
const data = await apiPost<{ code: string }> ('/users/code/renew', { },
|
||||||
@@ -33,21 +46,26 @@ export default ({ visible, onVisibleChange, user, setUser }: Props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={visible} onOpenChange={onVisibleChange}>
|
<Dialog open={visible} onOpenChange={onVisibleChange}>
|
||||||
<DialogContent>
|
<DialogContent className="px-6 pb-6 pt-7">
|
||||||
<DialogTitle>引継ぎコード</DialogTitle>
|
<DialogHeader className="pl-8">
|
||||||
<div>
|
<DialogTitle>引継ぎコード</DialogTitle>
|
||||||
<p>あなたの引継ぎコードはこちらです:</p>
|
|
||||||
<div className="m-2">{user?.inheritanceCode}</div>
|
<DialogDescription asChild>
|
||||||
<p className="mt-1 text-sm text-red-500">
|
<div>
|
||||||
このコードはほかの人には教えないでください!
|
<p>あなたの引継ぎコードはこちらです:</p>
|
||||||
</p>
|
<div className="m-2">{user?.inheritanceCode}</div>
|
||||||
<div className="my-4">
|
<p className="mt-1 text-sm text-destructive">
|
||||||
<Button onClick={handleChange}
|
このコードはほかの人には教えないでください!
|
||||||
className="px-4 py-2 bg-red-600 text-white rounded disabled:bg-gray-400">
|
</p>
|
||||||
引継ぎコード再発行
|
</div>
|
||||||
</Button>
|
</DialogDescription>
|
||||||
</div>
|
</DialogHeader>
|
||||||
</div>
|
|
||||||
|
<DialogFooter>
|
||||||
|
<Button onClick={handleChange} variant="destructive">
|
||||||
|
引継ぎコード再発行
|
||||||
|
</Button>
|
||||||
|
</DialogFooter>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>)
|
</Dialog>)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import TagLink from '@/components/TagLink'
|
|||||||
import PrefetchLink from '@/components/PrefetchLink'
|
import PrefetchLink from '@/components/PrefetchLink'
|
||||||
import PageTitle from '@/components/common/PageTitle'
|
import PageTitle from '@/components/common/PageTitle'
|
||||||
import Pagination from '@/components/common/Pagination'
|
import Pagination from '@/components/common/Pagination'
|
||||||
|
import { useDialogue } from '@/components/dialogues/DialogueProvider'
|
||||||
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 { SITE_TITLE } from '@/config'
|
import { SITE_TITLE } from '@/config'
|
||||||
@@ -35,6 +36,8 @@ const renderDiff = (diff: { current: string | null; prev: string | null }) => (
|
|||||||
|
|
||||||
|
|
||||||
export default (() => {
|
export default (() => {
|
||||||
|
const dialogue = useDialogue ()
|
||||||
|
|
||||||
const location = useLocation ()
|
const location = useLocation ()
|
||||||
const query = new URLSearchParams (location.search)
|
const query = new URLSearchParams (location.search)
|
||||||
const id = query.get ('id')
|
const id = query.get ('id')
|
||||||
@@ -66,8 +69,11 @@ export default (() => {
|
|||||||
const handleRevert = async (e: MouseEvent<HTMLAnchorElement>, change: PostVersion) => {
|
const handleRevert = async (e: MouseEvent<HTMLAnchorElement>, change: PostVersion) => {
|
||||||
e.preventDefault ()
|
e.preventDefault ()
|
||||||
|
|
||||||
if (!(confirm (`『${ change.title.current || change.url.current }』を版 ${
|
if (!(await dialogue.confirm ({
|
||||||
change.versionNo } に差戻します.\nよろしいですか?`)))
|
title: '差戻の確認',
|
||||||
|
description: `『${ change.title.current || change.url.current }』を版 ${
|
||||||
|
change.versionNo } に差戻します.\nよろしいですか?`,
|
||||||
|
confirmText: '差戻' })))
|
||||||
return
|
return
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|||||||
Reference in New Issue
Block a user