@@ -19,6 +19,7 @@ import {
1919} from 'react-native' ;
2020import { SafeAreaView } from 'react-native-safe-area-context' ;
2121import { useRouter } from 'expo-router' ;
22+ import { useTranslation } from 'react-i18next' ;
2223import { useDevConnectionConfig } from '@/hooks/useDevConnectionConfig' ;
2324import AsyncStorage from '@react-native-async-storage/async-storage' ;
2425
@@ -38,6 +39,7 @@ const Icons = {
3839export default function ServerConfigScreen ( ) {
3940 const router = useRouter ( ) ;
4041 const { config, isLoaded, setConfig } = useDevConnectionConfig ( ) ;
42+ const { t } = useTranslation ( ) ;
4143
4244 // Form state
4345 const [ host , setHost ] = useState ( '' ) ;
@@ -61,15 +63,15 @@ export default function ServerConfigScreen() {
6163
6264 // Validation
6365 if ( ! trimmedHost ) {
64- Alert . alert ( '错误' , '请输入服务器地址' ) ;
66+ Alert . alert ( t ( 'common.error' ) , t ( 'serverConfig.enterHost' ) ) ;
6567 return ;
6668 }
6769 if ( ! portNum || portNum < 1 || portNum > 65535 ) {
68- Alert . alert ( '错误' , '请输入有效的端口号 (1-65535)' ) ;
70+ Alert . alert ( t ( 'common.error' ) , t ( 'serverConfig.enterValidPort' ) ) ;
6971 return ;
7072 }
7173 if ( ! characterName . trim ( ) ) {
72- Alert . alert ( '错误' , '请输入角色名称' ) ;
74+ Alert . alert ( t ( 'common.error' ) , t ( 'serverConfig.enterCharacter' ) ) ;
7375 return ;
7476 }
7577
@@ -85,26 +87,30 @@ export default function ServerConfigScreen() {
8587 await setConfig ( newConfig ) ;
8688
8789 Alert . alert (
88- '保存成功' ,
89- `服务器地址已设置为:\n${ trimmedHost } :${ portNum } \n角色: ${ characterName . trim ( ) } ` ,
90- [ { text : '确定' , onPress : ( ) => router . back ( ) } ]
90+ t ( 'serverConfig.saved' ) ,
91+ t ( 'serverConfig.savedMessage' , {
92+ host : trimmedHost ,
93+ port : portNum ,
94+ character : characterName . trim ( ) ,
95+ } ) ,
96+ [ { text : t ( 'common.ok' ) , onPress : ( ) => router . back ( ) } ]
9197 ) ;
9298 } catch ( error ) {
93- Alert . alert ( '保存失败' , String ( error ) ) ;
99+ Alert . alert ( t ( 'serverConfig.saveFailed' ) , String ( error ) ) ;
94100 } finally {
95101 setSaving ( false ) ;
96102 }
97- } , [ host , port , characterName , setConfig , router ] ) ;
103+ } , [ host , port , characterName , setConfig , router , t ] ) ;
98104
99105 // Reset to default
100106 const handleReset = useCallback ( ( ) => {
101107 Alert . alert (
102- '恢复默认' ,
103- '确定要恢复默认配置吗?' ,
108+ t ( 'serverConfig.resetDefault' ) ,
109+ t ( 'serverConfig.resetConfirm' ) ,
104110 [
105- { text : '取消' , style : 'cancel' } ,
111+ { text : t ( 'common.cancel' ) , style : 'cancel' } ,
106112 {
107- text : '确定' ,
113+ text : t ( 'common.confirm' ) ,
108114 style : 'destructive' ,
109115 onPress : async ( ) => {
110116 await AsyncStorage . removeItem ( STORAGE_KEY ) ;
@@ -115,7 +121,7 @@ export default function ServerConfigScreen() {
115121 } ,
116122 ]
117123 ) ;
118- } , [ ] ) ;
124+ } , [ t ] ) ;
119125
120126 // Quick fill common local IP patterns
121127 const quickFillLocalhost = ( ) => {
@@ -132,7 +138,7 @@ export default function ServerConfigScreen() {
132138 return (
133139 < SafeAreaView style = { styles . container } >
134140 < View style = { styles . loadingContainer } >
135- < Text style = { styles . loadingText } > 加载中... </ Text >
141+ < Text style = { styles . loadingText } > { t ( 'common.loading' ) } </ Text >
136142 </ View >
137143 </ SafeAreaView >
138144 ) ;
@@ -149,7 +155,7 @@ export default function ServerConfigScreen() {
149155 < TouchableOpacity onPress = { ( ) => router . back ( ) } style = { styles . backButton } >
150156 < Text style = { styles . backButtonText } > { Icons . back } </ Text >
151157 </ TouchableOpacity >
152- < Text style = { styles . headerTitle } > 服务器配置 </ Text >
158+ < Text style = { styles . headerTitle } > { t ( 'serverConfig.title' ) } </ Text >
153159 < TouchableOpacity onPress = { handleSave } disabled = { saving } style = { styles . saveButton } >
154160 < Text style = { styles . saveButtonText } > { Icons . save } </ Text >
155161 </ TouchableOpacity >
@@ -158,17 +164,17 @@ export default function ServerConfigScreen() {
158164 < ScrollView style = { styles . content } keyboardShouldPersistTaps = "handled" >
159165 { /* Instructions */ }
160166 < View style = { styles . instructionCard } >
161- < Text style = { styles . instructionTitle } > 如何获取服务器地址 </ Text >
167+ < Text style = { styles . instructionTitle } > { t ( 'serverConfig.instructions' ) } </ Text >
162168 < Text style = { styles . instructionText } >
163- 1. 在电脑上启动 Nekotong 应用 { '\n' }
164- 2. 在应用界面左上角查看"连接地址" { '\n' }
165- 3. 输入下方显示的 IP 地址和端口号
169+ { t ( 'serverConfig.instruction1' ) } { '\n' }
170+ { t ( 'serverConfig.instruction2' ) } { '\n' }
171+ { t ( 'serverConfig.instruction3' ) }
166172 </ Text >
167173 </ View >
168174
169175 { /* Quick Fill Buttons */ }
170176 < View style = { styles . quickFillContainer } >
171- < Text style = { styles . quickFillLabel } > 快速填充: </ Text >
177+ < Text style = { styles . quickFillLabel } > { t ( 'serverConfig.quickFill' ) } </ Text >
172178 < View style = { styles . quickFillButtons } >
173179 < TouchableOpacity style = { styles . quickFillButton } onPress = { quickFillLocalhost } >
174180 < Text style = { styles . quickFillButtonText } > localhost</ Text >
@@ -183,30 +189,32 @@ export default function ServerConfigScreen() {
183189 < View style = { styles . section } >
184190 < View style = { styles . sectionHeader } >
185191 < Text style = { styles . sectionIcon } > { Icons . server } </ Text >
186- < Text style = { styles . sectionTitle } > 服务器地址 </ Text >
192+ < Text style = { styles . sectionTitle } > { t ( 'serverConfig.serverAddress' ) } </ Text >
187193 </ View >
188194 < View style = { styles . card } >
189195 < View style = { styles . field } >
190- < Text style = { styles . label } > IP 地址 / 主机名 </ Text >
196+ < Text style = { styles . label } > { t ( 'serverConfig.ipHostname' ) } </ Text >
191197 < TextInput
192198 style = { styles . input }
193199 value = { host }
194200 onChangeText = { setHost }
195- placeholder = "例如: 192.168.1.100"
201+ placeholder = { t ( 'serverConfig.hostPlaceholder' ) }
202+ placeholderTextColor = "#666"
196203 autoCapitalize = "none"
197204 autoCorrect = { false }
198205 keyboardType = "default"
199206 />
200- < Text style = { styles . hint } > 输入 Nekotong 显示连接地址中的 IP 部分 </ Text >
207+ < Text style = { styles . hint } > { t ( 'serverConfig.ipHint' ) } </ Text >
201208 </ View >
202209
203210 < View style = { styles . field } >
204- < Text style = { styles . label } > 端口号 </ Text >
211+ < Text style = { styles . label } > { t ( 'serverConfig.portNumber' ) } </ Text >
205212 < TextInput
206213 style = { styles . input }
207214 value = { port }
208215 onChangeText = { setPort }
209- placeholder = "例如: 48911"
216+ placeholder = { t ( 'serverConfig.portPlaceholder' ) }
217+ placeholderTextColor = "#666"
210218 keyboardType = "number-pad"
211219 maxLength = { 5 }
212220 />
@@ -218,20 +226,21 @@ export default function ServerConfigScreen() {
218226 < View style = { styles . section } >
219227 < View style = { styles . sectionHeader } >
220228 < Text style = { styles . sectionIcon } > { Icons . user } </ Text >
221- < Text style = { styles . sectionTitle } > 角色设置 </ Text >
229+ < Text style = { styles . sectionTitle } > { t ( 'serverConfig.characterSettings' ) } </ Text >
222230 </ View >
223231 < View style = { styles . card } >
224232 < View style = { styles . field } >
225- < Text style = { styles . label } > 角色名称 </ Text >
233+ < Text style = { styles . label } > { t ( 'serverConfig.character' ) } </ Text >
226234 < TextInput
227235 style = { styles . input }
228236 value = { characterName }
229237 onChangeText = { setCharacterName }
230- placeholder = "例如: test"
238+ placeholder = { t ( 'serverConfig.characterPlaceholder' ) }
239+ placeholderTextColor = "#666"
231240 autoCapitalize = "none"
232241 autoCorrect = { false }
233242 />
234- < Text style = { styles . hint } > Nekotong 中配置的角色名 </ Text >
243+ < Text style = { styles . hint } > { t ( 'serverConfig.characterHint' ) } </ Text >
235244 </ View >
236245 </ View >
237246 </ View >
@@ -240,13 +249,13 @@ export default function ServerConfigScreen() {
240249 < View style = { styles . section } >
241250 < View style = { styles . sectionHeader } >
242251 < Text style = { styles . sectionIcon } > { Icons . refresh } </ Text >
243- < Text style = { styles . sectionTitle } > 当前配置 </ Text >
252+ < Text style = { styles . sectionTitle } > { t ( 'serverConfig.currentConfig' ) } </ Text >
244253 </ View >
245254 < View style = { styles . card } >
246255 { config . p2p ? (
247256 < >
248257 < View style = { styles . infoRow } >
249- < Text style = { styles . infoLabel } > P2P 连接模式 </ Text >
258+ < Text style = { styles . infoLabel } > { t ( 'serverConfig.p2pMode' ) } </ Text >
250259 </ View >
251260 < Text style = { styles . wsUrl } >
252261 { config . host } :{ config . port }
@@ -258,7 +267,7 @@ export default function ServerConfigScreen() {
258267 ) : (
259268 < >
260269 < View style = { styles . infoRow } >
261- < Text style = { styles . infoLabel } > WebSocket URL </ Text >
270+ < Text style = { styles . infoLabel } > { t ( 'serverConfig.websocketUrl' ) } </ Text >
262271 </ View >
263272 < Text style = { styles . wsUrl } >
264273 ws://{ config . host } :{ config . port } /ws/{ config . characterName }
@@ -276,22 +285,22 @@ export default function ServerConfigScreen() {
276285 disabled = { saving }
277286 >
278287 < Text style = { styles . primaryButtonText } >
279- { saving ? '保存中...' : `${ Icons . check } 保存配置 ` }
288+ { saving ? t ( 'serverConfig.saving' ) : `${ Icons . check } ${ t ( 'serverConfig.save' ) } ` }
280289 </ Text >
281290 </ TouchableOpacity >
282291
283292 < TouchableOpacity style = { styles . secondaryButton } onPress = { handleReset } >
284- < Text style = { styles . secondaryButtonText } > 恢复默认 </ Text >
293+ < Text style = { styles . secondaryButtonText } > { t ( 'serverConfig.resetDefault' ) } </ Text >
285294 </ TouchableOpacity >
286295 </ View >
287296
288297 { /* Tips */ }
289298 < View style = { styles . tipsContainer } >
290- < Text style = { styles . tipsTitle } > 💡 提示 </ Text >
299+ < Text style = { styles . tipsTitle } > 💡 { t ( 'serverConfig.tips' ) } </ Text >
291300 < Text style = { styles . tipsText } >
292- • 确保手机和电脑在同一 WiFi 网络下 { '\n' }
293- • 如果连接失败,请检查防火墙设置 { '\n' }
294- • 也可以使用扫码配置功能自动填充
301+ • { t ( 'serverConfig.tip1' ) } { '\n' }
302+ • { t ( 'serverConfig.tip2' ) } { '\n' }
303+ • { t ( 'serverConfig.tip3' ) }
295304 </ Text >
296305 </ View >
297306 </ ScrollView >
0 commit comments