aboutsummaryrefslogtreecommitdiffstats
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/Settings.js1
-rw-r--r--src/components/WifiCard.js13
-rw-r--r--src/components/style.css7
-rw-r--r--src/components/useHashParam.js48
4 files changed, 64 insertions, 5 deletions
diff --git a/src/components/Settings.js b/src/components/Settings.js
index 837b4f0..0485aaf 100644
--- a/src/components/Settings.js
+++ b/src/components/Settings.js
@@ -20,6 +20,7 @@ export const Settings = (props) => {
20 { label: 'WEP', value: 'WEP' }, 20 { label: 'WEP', value: 'WEP' },
21 ]; 21 ];
22 const eapMethods = [{ label: 'PWD', value: 'PWD' }]; 22 const eapMethods = [{ label: 'PWD', value: 'PWD' }];
23
23 const langSelectDefaultValue = () => { 24 const langSelectDefaultValue = () => {
24 const t = Translations.filter((t) => t.id === i18n.language); 25 const t = Translations.filter((t) => t.id === i18n.language);
25 if (t.length !== 1) { 26 if (t.length !== 1) {
diff --git a/src/components/WifiCard.js b/src/components/WifiCard.js
index 70e1189..e977ac8 100644
--- a/src/components/WifiCard.js
+++ b/src/components/WifiCard.js
@@ -8,7 +8,7 @@ import {
8 Text, 8 Text,
9 TextareaField, 9 TextareaField,
10} from 'evergreen-ui'; 10} from 'evergreen-ui';
11import QRCode from 'qrcode.react'; 11import { QRCodeSVG as QRCode } from 'qrcode.react';
12import { useEffect, useState } from 'react'; 12import { useEffect, useState } from 'react';
13import { useTranslation } from 'react-i18next'; 13import { useTranslation } from 'react-i18next';
14import logo from '../../src/images/wifi.png'; 14import logo from '../../src/images/wifi.png';
@@ -71,6 +71,9 @@ export const WifiCard = (props) => {
71 return !eapIdentityFieldLabel() ? '' : t('wifi.encryption.eapMethod'); 71 return !eapIdentityFieldLabel() ? '' : t('wifi.encryption.eapMethod');
72 }; 72 };
73 73
74 const keyid = props.keyid || '';
75 const suffixKeyID = (prefix) => `${prefix}-${keyid}`;
76
74 return ( 77 return (
75 <Card 78 <Card
76 className="card-print" 79 className="card-print"
@@ -102,7 +105,7 @@ export const WifiCard = (props) => {
102 105
103 <Pane width={'100%'}> 106 <Pane width={'100%'}>
104 <TextareaField 107 <TextareaField
105 id="ssid" 108 id={suffixKeyID('ssid')}
106 type="text" 109 type="text"
107 marginBottom={5} 110 marginBottom={5}
108 autoComplete="off" 111 autoComplete="off"
@@ -120,7 +123,7 @@ export const WifiCard = (props) => {
120 {props.settings.encryptionMode === 'WPA2-EAP' && ( 123 {props.settings.encryptionMode === 'WPA2-EAP' && (
121 <> 124 <>
122 <TextareaField 125 <TextareaField
123 id="eapmethod" 126 id={suffixKeyID('eapmethod')}
124 type="text" 127 type="text"
125 marginBottom={5} 128 marginBottom={5}
126 readOnly={true} 129 readOnly={true}
@@ -130,7 +133,7 @@ export const WifiCard = (props) => {
130 /> 133 />
131 134
132 <TextareaField 135 <TextareaField
133 id="identity" 136 id={suffixKeyID('identity')}
134 type="text" 137 type="text"
135 marginBottom={5} 138 marginBottom={5}
136 autoComplete="off" 139 autoComplete="off"
@@ -150,7 +153,7 @@ export const WifiCard = (props) => {
150 )} 153 )}
151 {!(props.settings.hidePassword || !props.settings.encryptionMode) && ( 154 {!(props.settings.hidePassword || !props.settings.encryptionMode) && (
152 <TextareaField 155 <TextareaField
153 id="password" 156 id={suffixKeyID('password')}
154 type="text" 157 type="text"
155 maxLength="63" 158 maxLength="63"
156 autoComplete="off" 159 autoComplete="off"
diff --git a/src/components/style.css b/src/components/style.css
index 10eac9b..87ba63a 100644
--- a/src/components/style.css
+++ b/src/components/style.css
@@ -67,6 +67,13 @@ button {
67 #print-area, 67 #print-area,
68 #print-area * { 68 #print-area * {
69 visibility: visible; 69 visibility: visible;
70 /* For printing, use a font stack that prioritizes system fonts
71 to ensure CJK characters are rendered correctly in Chrome. */
72 font-family:
73 'PingFang SC', 'Noto Sans SC', 'Noto Sans TC', 'Noto Sans JP',
74 'Noto Sans KR', 'Microsoft YaHei', serif;
75 font-weight: 500;
76 font-style: semibold;
70 } 77 }
71 #print-area { 78 #print-area {
72 position: absolute; 79 position: absolute;
diff --git a/src/components/useHashParam.js b/src/components/useHashParam.js
new file mode 100644
index 0000000..e43e1e4
--- /dev/null
+++ b/src/components/useHashParam.js
@@ -0,0 +1,48 @@
1import { useState, useEffect, useCallback } from 'react';
2
3const getHashSearchParams = (location) => {
4 const hash = location.hash.slice(1);
5 const [prefix, query] = hash.split('?');
6
7 return [prefix, new URLSearchParams(query)];
8};
9
10const getHashParam = (key, location = window.location) => {
11 const [_, searchParams] = getHashSearchParams(location);
12 return searchParams.get(key);
13};
14
15const setHashParam = (key, value, location = window.location) => {
16 const [prefix, searchParams] = getHashSearchParams(location);
17
18 if (typeof value === 'undefined') {
19 searchParams.delete(key);
20 } else {
21 searchParams.set(key, value);
22 }
23
24 const search = searchParams.toString();
25 location.hash = search ? `${prefix}?${search}` : prefix;
26};
27
28const useHashParam = (key) => {
29 const [innerValue, setInnerValue] = useState();
30
31 useEffect(() => {
32 const handleHashChange = () => setInnerValue(getHashParam(key));
33 handleHashChange();
34 window.addEventListener('hashchange', handleHashChange);
35 return () => window.removeEventListener('hashchange', handleHashChange);
36 }, [key]);
37
38 const setValue = useCallback(
39 (value) => {
40 setHashParam(key, value);
41 },
42 [key]
43 );
44
45 return [innerValue, setValue];
46};
47
48export default useHashParam;