@@ -2,10 +2,13 @@ import { StrictMode } from 'react'
22import ReactDOM , { render } from 'react-dom'
33
44import Clock from './Clock'
5+ import Random from './Random'
56import { getRoot , isBetaUI } from './utils'
7+ import { findElement } from '../../utils'
68
7- let root : HTMLDivElement | null = null
8- let titleSlug = ''
9+ let root : HTMLDivElement | null = null ,
10+ randomRoot : HTMLDivElement | null = null ,
11+ titleSlug = ''
912
1013async function load ( ) {
1114 titleSlug = location . pathname . split ( '/' ) . filter ( Boolean ) [ 1 ]
@@ -14,7 +17,6 @@ async function load() {
1417 if ( beta ) {
1518 // 使用新版 UI
1619 if ( parent && parent instanceof HTMLElement ) {
17- // parent.style.justifyContent = 'space-between'
1820 root = document . createElement ( 'div' )
1921 parent . prepend ( root )
2022 root . style . display = 'flex'
@@ -47,6 +49,37 @@ async function load() {
4749 }
4850}
4951
52+ /** 加载`随机一题`按钮
53+ *
54+ * 旧版答题页已经有`随机一题`的按钮,所以只需要在新版答题页中添加即可,
55+ * 新版答题页中的`上一题`和`下一题`按钮是放在上方导航栏处,
56+ * 所以`随机一题`按钮也跟它们一起放在导航栏处。
57+ *
58+ * 因为导航栏在进行题目切换的时候,并不会变化,
59+ * 所以不用像计时组件那样,每次在切换题目的时候都需要卸载后重新加载,
60+ * 只需要考虑跟其他非答题页之间进行切换的逻辑即可。
61+ */
62+ async function loadRandom ( ) {
63+ const beta = await isBetaUI ( )
64+ if ( beta ) {
65+ if ( ! randomRoot ) {
66+ const nav = await findElement (
67+ '#__next > div > div > div > nav > div > div > div:nth-child(2)'
68+ )
69+ randomRoot = document . createElement ( 'div' )
70+ randomRoot . style . lineHeight = '0'
71+ nav . append ( randomRoot )
72+
73+ render (
74+ < StrictMode >
75+ < Random />
76+ </ StrictMode > ,
77+ randomRoot
78+ )
79+ }
80+ }
81+ }
82+
5083const isProblemPage = ( ) => {
5184 const strs = location . pathname . split ( '/' ) . filter ( Boolean )
5285 return strs [ 0 ] === 'problems'
@@ -56,6 +89,7 @@ void (async function main() {
5689 if ( isProblemPage ( ) ) {
5790 const beta = await isBetaUI ( )
5891 if ( beta ) {
92+ loadRandom ( )
5993 const params = location . pathname . split ( '/' ) . filter ( Boolean )
6094 // 新版 UI 中,如果一开始打开的就是题解页面,则当前并不存在提交栏,也就无法也不需要去挂载即使组件
6195 if ( params [ 2 ] === 'solutions' && params [ 3 ] ) return
@@ -64,10 +98,11 @@ void (async function main() {
6498 }
6599} ) ( )
66100
67- function unmount ( ) {
68- if ( root ) {
69- ReactDOM . unmountComponentAtNode ( root )
70- root = null
101+ function unmount ( el : HTMLElement | null ) {
102+ if ( el ) {
103+ ReactDOM . unmountComponentAtNode ( el )
104+ el . remove ( )
105+ el = null
71106 titleSlug = ''
72107 }
73108}
@@ -89,21 +124,23 @@ if (isProblemPage() || location.pathname === '/problemset/all/') {
89124
90125 if ( ! isProblemPage ( ) ) {
91126 // 从答题页跳转到非答题页时,卸载计时组件
92- unmount ( )
127+ unmount ( root )
128+ unmount ( randomRoot )
93129 } else {
94130 const beta = await isBetaUI ( )
95131 if ( beta ) {
132+ loadRandom ( )
96133 const params = location . pathname . split ( '/' ) . filter ( Boolean )
97134 // 新版 UI 中,跳转到题解页面之后,如果跳转回去,会导致提交栏发生变化,需要先卸载掉。
98135 if ( params [ 2 ] === 'solutions' && params [ 3 ] ) {
99- unmount ( )
136+ unmount ( root )
100137 return
101138 }
102139 }
103140 // 在答题页之间相互跳转,如果还是在同一题,则不做任何操作,如果是跳转另外一题则重新开始计时
104141 const curSlug = location . pathname . split ( '/' ) . filter ( Boolean ) [ 1 ]
105142 if ( curSlug !== titleSlug ) {
106- unmount ( )
143+ unmount ( root )
107144 load ( )
108145 }
109146 }
0 commit comments