1
1
import React , { useEffect , useState } from 'react' ;
2
2
import { Notification } from '@jupyterlab/apputils' ;
3
+ import {
4
+ IconChevronDown ,
5
+ IconBrandChrome ,
6
+ IconBrandFirefox ,
7
+ IconBrandEdge ,
8
+ IconBrandSafari ,
9
+ IconBrandOpera ,
10
+ IconBrandVivaldi ,
11
+ IconBrandArc ,
12
+ IconWorldWww
13
+ } from '@tabler/icons-react' ;
14
+ import { Button , Menu , useMantineTheme } from '@mantine/core' ;
3
15
import { getCookie } from '../services/cookie' ;
4
- import Bowser from 'bowser' ;
5
16
6
- const BrowserCookie : React . FC < {
7
- setCookieLoggedIn : ( b : string ) => void ;
8
- } > = ( { setCookieLoggedIn } ) => {
9
- const browsers = [
10
- 'Chrome' ,
11
- 'Firefox' ,
12
- 'Safari' ,
13
- 'Edge' ,
14
- 'Opera' ,
15
- 'Brave' ,
16
- 'Vivaldi' ,
17
- 'Chromium' ,
18
- 'Arc' ,
19
- 'LibreWolf' ,
20
- 'Opera GX'
21
- ] ;
17
+ const BROWSERS = [
18
+ {
19
+ name : 'Chrome' ,
20
+ icon : ( color : string ) => (
21
+ < IconBrandChrome size = { 16 } color = { color } stroke = { 1.5 } />
22
+ )
23
+ } ,
24
+ {
25
+ name : 'Firefox' ,
26
+ icon : ( color : string ) => (
27
+ < IconBrandFirefox size = { 16 } color = { color } stroke = { 1.5 } />
28
+ )
29
+ } ,
30
+ {
31
+ name : 'Safari' ,
32
+ icon : ( color : string ) => (
33
+ < IconBrandSafari size = { 16 } color = { color } stroke = { 1.5 } />
34
+ )
35
+ } ,
36
+ {
37
+ name : 'Edge' ,
38
+ icon : ( color : string ) => (
39
+ < IconBrandEdge size = { 16 } color = { color } stroke = { 1.5 } />
40
+ )
41
+ } ,
42
+ {
43
+ name : 'Opera' ,
44
+ icon : ( color : string ) => (
45
+ < IconBrandOpera size = { 16 } color = { color } stroke = { 1.5 } />
46
+ )
47
+ } ,
48
+ {
49
+ name : 'Brave' ,
50
+ icon : ( color : string ) => (
51
+ < IconWorldWww size = { 16 } color = { color } stroke = { 1.5 } />
52
+ )
53
+ } ,
54
+ {
55
+ name : 'Vivaldi' ,
56
+ icon : ( color : string ) => (
57
+ < IconBrandVivaldi size = { 16 } color = { color } stroke = { 1.5 } />
58
+ )
59
+ } ,
60
+ {
61
+ name : 'Chromium' ,
62
+ icon : ( color : string ) => (
63
+ < IconBrandChrome size = { 16 } color = { color } stroke = { 1.5 } />
64
+ )
65
+ } ,
66
+ {
67
+ name : 'Arc' ,
68
+ icon : ( color : string ) => (
69
+ < IconBrandArc size = { 16 } color = { color } stroke = { 1.5 } />
70
+ )
71
+ } ,
72
+ {
73
+ name : 'LibreWolf' ,
74
+ icon : ( color : string ) => (
75
+ < IconWorldWww size = { 16 } color = { color } stroke = { 1.5 } />
76
+ )
77
+ } ,
78
+ {
79
+ name : 'Opera GX' ,
80
+ icon : ( color : string ) => (
81
+ < IconBrandOpera size = { 16 } color = { color } stroke = { 1.5 } />
82
+ )
83
+ }
84
+ ] ;
22
85
23
- const normalizeBrowserName = ( name : string ) =>
24
- name . toLowerCase ( ) . replace ( / \s + / g, '_' ) ;
86
+ const normalizeBrowserName = ( name : string ) =>
87
+ name . toLowerCase ( ) . replace ( / \s + / g, '_' ) ;
25
88
89
+ const BrowserCookie : React . FC < {
90
+ className ?: string ;
91
+ setCookieLoggedIn : ( b : string ) => void ;
92
+ } > = ( { className, setCookieLoggedIn } ) => {
26
93
const [ browser , setBrowser ] = useState ( '' ) ;
27
94
const [ checked , setChecked ] = useState ( false ) ;
28
95
29
- // set browser value by detecting current browser
30
96
useEffect ( ( ) => {
31
- const browserName = Bowser . getParser (
32
- window . navigator . userAgent
33
- ) . getBrowserName ( true ) ;
34
- if ( browserName ) {
35
- const firstMatch = browsers . find ( b =>
36
- new RegExp ( b , 'i' ) . test ( browserName )
37
- ) ;
38
- if ( firstMatch ) {
39
- setBrowser ( normalizeBrowserName ( firstMatch ) ) ;
40
- }
41
- }
42
- } , [ ] ) ;
43
-
44
- useEffect ( ( ) => {
45
- if ( checked ) {
46
- setCookieLoggedIn ( browser ) ;
47
- }
48
- } , [ checked , setCookieLoggedIn ] ) ;
49
-
50
- const checkCookie = ( ) => {
51
97
if ( ! browser ) {
52
- Notification . error ( 'Please select a browser.' , { autoClose : 3000 } ) ;
53
98
return ;
54
99
}
55
100
if ( browser === 'safari' ) {
@@ -62,37 +107,56 @@ const BrowserCookie: React.FC<{
62
107
63
108
getCookie ( browser )
64
109
. then ( resp => {
110
+ if ( ! resp [ 'checked' ] ) {
111
+ Notification . error (
112
+ `Failed to check cookie for ${ browser } . Please ensure you are logged in to LeetCode in this browser.` ,
113
+ { autoClose : 3000 }
114
+ ) ;
115
+ }
65
116
setChecked ( resp [ 'checked' ] ) ;
66
117
} )
67
118
. catch ( e => Notification . error ( e . message , { autoClose : 3000 } ) ) ;
68
- } ;
119
+ } , [ browser ] ) ;
120
+
121
+ useEffect ( ( ) => {
122
+ if ( checked ) {
123
+ setCookieLoggedIn ( browser ) ;
124
+ }
125
+ } , [ checked ] ) ;
69
126
127
+ const theme = useMantineTheme ( ) ;
70
128
return (
71
- < div >
72
- < label htmlFor = "browser-selector" >
73
- Choose your browser that has LeetCode logged in:
74
- </ label >
75
- < select
76
- id = "browser-selector"
77
- required
78
- value = { browser }
79
- onChange = { e => setBrowser ( e . target . value ) }
80
- >
81
- < option value = "" disabled >
82
- Select a browser
83
- </ option >
84
- { browsers . map ( browser => (
85
- < option
86
- key = { browser . toLowerCase ( ) }
87
- value = { normalizeBrowserName ( browser ) }
129
+ < Menu
130
+ transitionProps = { { transition : 'pop-top-right' } }
131
+ position = "bottom-end"
132
+ width = { 220 }
133
+ withinPortal
134
+ radius = "md"
135
+ >
136
+ < Menu . Target >
137
+ < Button
138
+ rightSection = { < IconChevronDown size = { 18 } stroke = { 1.5 } /> }
139
+ pr = { 12 }
140
+ radius = "md"
141
+ size = "md"
142
+ className = { className }
143
+ >
144
+ Load from browser
145
+ </ Button >
146
+ </ Menu . Target >
147
+ < Menu . Dropdown >
148
+ < Menu . Label > With LeetCode logged in</ Menu . Label >
149
+ { BROWSERS . map ( ( { name, icon } , i ) => (
150
+ < Menu . Item
151
+ key = { name }
152
+ leftSection = { icon ( theme . colors . blue [ 6 ] ) }
153
+ onClick = { ( ) => setBrowser ( normalizeBrowserName ( name ) ) }
88
154
>
89
- { browser }
90
- </ option >
155
+ { name }
156
+ </ Menu . Item >
91
157
) ) }
92
- </ select >
93
- < button onClick = { checkCookie } > Check</ button >
94
- < p > Checked: { checked ? 'Yes' : 'No' } </ p >
95
- </ div >
158
+ </ Menu . Dropdown >
159
+ </ Menu >
96
160
) ;
97
161
} ;
98
162
0 commit comments