Skip to content

Commit

Permalink
fix(problems): 添加比赛答题页中禁用快捷键的选项
Browse files Browse the repository at this point in the history
  • Loading branch information
XYShaoKang committed Jan 16, 2023
1 parent 74334a3 commit c7e79f4
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 21 deletions.
22 changes: 20 additions & 2 deletions src/content/pages/global/optionSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ interface OptionState {
problemRating: {
enable: boolean
}
contestProblem: {
disableShortcutKey: boolean
}
}

const initialState: OptionState = {
Expand All @@ -28,6 +31,9 @@ const initialState: OptionState = {
problemRating: {
enable: true,
},
contestProblem: {
disableShortcutKey: false,
},
}

export const optionSlice = createSlice({
Expand All @@ -48,11 +54,19 @@ export const optionSlice = createSlice({
enableProblemRating(state) {
state.problemRating.enable = true
},
toggleContestProblemShortcutKeyOption(state) {
state.contestProblem.disableShortcutKey =
!state.contestProblem.disableShortcutKey
},
},
})

export const { setRandomOption, disableProblemRating, enableProblemRating } =
optionSlice.actions
export const {
setRandomOption,
disableProblemRating,
enableProblemRating,
toggleContestProblemShortcutKeyOption,
} = optionSlice.actions

export const selectRandomOption = (
state: RootState,
Expand All @@ -63,4 +77,8 @@ export const selectProblemRatingOption = (
state: RootState
): OptionState['problemRating'] => state.option.problemRating

export const selectContestProblemShortcutKeyOption = (
state: RootState
): OptionState['contestProblem'] => state.option.contestProblem

export default optionSlice.reducer
95 changes: 95 additions & 0 deletions src/content/pages/problems/ShortcutKeyOption.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { useEffect, useState, FC } from 'react'
import { Portal } from '@/components/Portal'
import { findElement } from '@/utils'
import { css } from 'styled-components/macro'
import { useAppDispatch, useAppSelector } from '@/hooks'
import {
selectContestProblemShortcutKeyOption,
toggleContestProblemShortcutKeyOption,
} from '../global/optionSlice'
import { withRoot } from '@/hoc'

const ShortcutKeyOption: FC = () => {
const [optionEl, setOptionEl] = useState<HTMLElement>()
const { disableShortcutKey } = useAppSelector(
selectContestProblemShortcutKeyOption
)
const dispatch = useAppDispatch()

const toggle = () => {
dispatch(toggleContestProblemShortcutKeyOption())
}
useEffect(() => {
let settingBtn: HTMLElement
const handleClick = async () => {
const content = await findElement(
'.rc-dialog-body>.modal-body.description__21Ft'
)
setOptionEl(content)
}
handleClick()

void (async function () {
settingBtn = await findElement('.setting-btn')
settingBtn.addEventListener('click', handleClick)
})()
return () => {
settingBtn && settingBtn.removeEventListener('click', handleClick)
}
}, [])

useEffect(() => {
if (!disableShortcutKey) return
let editor: HTMLElement | null = null
const handleClick = (e: KeyboardEvent) => {
e.preventDefault()
e.stopPropagation()
}
void (async function () {
editor = await findElement('.editor-base')
editor.addEventListener('keydown', handleClick)
})()
return () => {
editor && editor.removeEventListener('keydown', handleClick)
}
}, [disableShortcutKey])

if (!optionEl) return <div />
return (
<Portal container={optionEl}>
<hr className="base-line__Agul line dotted" />
<div
css={css`
display: flex;
align-items: center;
justify-content: space-between;
font-weight: bold;
font-size: 16px;
`}
>
<div>禁用快捷键</div>

<svg
viewBox="0 0 24 24"
style={{ width: 50, height: 50, cursor: 'pointer' }}
onClick={toggle}
>
{disableShortcutKey ? (
<path
d="M17 7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h10c2.76 0 5-2.24 5-5s-2.24-5-5-5zm0 8c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3z"
fill="currentColor"
color="rgb(144, 202, 249)"
/>
) : (
<path
d="M17 7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h10c2.76 0 5-2.24 5-5s-2.24-5-5-5zM7 15c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3z"
fill="currentColor"
/>
)}
</svg>
</div>
</Portal>
)
}

export default withRoot(ShortcutKeyOption)
24 changes: 5 additions & 19 deletions src/content/pages/problems/index.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,17 @@
import ReactDOM, { render } from 'react-dom'

import { IS_MAC, findElement, isBetaUI } from '@/utils'
import { findElement, isBetaUI } from '@/utils'

import Clock from './Clock'
import Random from './Random'
import { getRoot } from './utils'
import { fixBack } from './fixBack'
import ShortcutKeyOption from './ShortcutKeyOption'

let root: HTMLDivElement | null = null,
randomRoot: HTMLDivElement | null = null,
titleSlug = ''

/** 阻止按 CMD(Win 中为 Ctrl) + s 键时,弹出浏览器自带的保存页面
*/
const handlePreventSave = (e: KeyboardEvent) => {
if (e.altKey || e.shiftKey) return
if (IS_MAC) {
if (!e.ctrlKey && e.metaKey && e.code === 'KeyS') {
e.preventDefault()
}
} else {
if (!e.metaKey && e.ctrlKey && e.code === 'KeyS') {
e.preventDefault()
}
}
}
async function load() {
titleSlug = location.pathname.split('/').filter(Boolean)[1]
const beta = await isBetaUI()
Expand Down Expand Up @@ -115,10 +102,9 @@ void (async function main() {
load()
}
if (isContestProblemPage()) {
const monacoEditor = await findElement('.CodeMirror')
if (monacoEditor) {
monacoEditor.addEventListener('keydown', handlePreventSave)
}
const root = document.createElement('div')
render(<ShortcutKeyOption />, root)
document.body.append(root)
}
})()

Expand Down

0 comments on commit c7e79f4

Please sign in to comment.