libretranslatr
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../services/settings_service.dart';
|
||||
import '../services/translate_service.dart';
|
||||
|
||||
class SettingsScreen extends StatefulWidget {
|
||||
final bool isFirstRun;
|
||||
const SettingsScreen({super.key, this.isFirstRun = false});
|
||||
|
||||
@override
|
||||
State<SettingsScreen> createState() => _SettingsScreenState();
|
||||
}
|
||||
|
||||
class _SettingsScreenState extends State<SettingsScreen> {
|
||||
final _settings = SettingsService();
|
||||
final _urlController = TextEditingController();
|
||||
final _apiKeyController = TextEditingController();
|
||||
|
||||
bool _testing = false;
|
||||
String? _statusMessage;
|
||||
bool? _statusSuccess;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_load();
|
||||
_urlController.addListener(() => setState(() {}));
|
||||
}
|
||||
|
||||
Future<void> _load() async {
|
||||
final url = await _settings.getServerUrl();
|
||||
final key = await _settings.getApiKey();
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_urlController.text = url ?? '';
|
||||
_apiKeyController.text = key ?? '';
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _testConnection() async {
|
||||
setState(() {
|
||||
_testing = true;
|
||||
_statusMessage = null;
|
||||
});
|
||||
|
||||
// Test için önce girilen değerleri geçici olarak kaydediyoruz.
|
||||
await _settings.save(
|
||||
serverUrl: _urlController.text,
|
||||
apiKey: _apiKeyController.text,
|
||||
);
|
||||
|
||||
try {
|
||||
final service = TranslateService(_settings);
|
||||
final langs = await service.fetchLanguages();
|
||||
setState(() {
|
||||
_statusSuccess = true;
|
||||
_statusMessage = 'Bağlantı başarılı — ${langs.length} dil bulundu.';
|
||||
});
|
||||
} catch (e) {
|
||||
setState(() {
|
||||
_statusSuccess = false;
|
||||
_statusMessage = 'Bağlanamadı: $e';
|
||||
});
|
||||
} finally {
|
||||
setState(() => _testing = false);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _saveAndReturn() async {
|
||||
await _settings.save(
|
||||
serverUrl: _urlController.text,
|
||||
apiKey: _apiKeyController.text,
|
||||
);
|
||||
if (!mounted) return;
|
||||
Navigator.of(context).pop(true);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Sunucu Ayarları'),
|
||||
automaticallyImplyLeading: !widget.isFirstRun,
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
if (widget.isFirstRun) ...[
|
||||
Text(
|
||||
'LibreTranslate Sunucunuza Bağlanın',
|
||||
style: Theme.of(context).textTheme.headlineSmall,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Uygulamanın çeviri yapabilmesi için kendi LibreTranslate sunucunuzun adresini girin.',
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
],
|
||||
TextField(
|
||||
controller: _urlController,
|
||||
keyboardType: TextInputType.url,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Sunucu Adresi',
|
||||
hintText: 'https://translate.benimsunucum.com',
|
||||
prefixIcon: Icon(Icons.dns_outlined),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 14),
|
||||
TextField(
|
||||
controller: _apiKeyController,
|
||||
obscureText: true,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'API Key (opsiyonel)',
|
||||
hintText: 'Boş bırakılırsa gönderilmez',
|
||||
prefixIcon: Icon(Icons.key_outlined),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
OutlinedButton.icon(
|
||||
onPressed: _testing ? null : _testConnection,
|
||||
icon: _testing
|
||||
? const SizedBox(
|
||||
width: 16,
|
||||
height: 16,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
)
|
||||
: const Icon(Icons.wifi_tethering),
|
||||
label: Text(_testing ? 'Test ediliyor...' : 'Bağlantıyı Test Et'),
|
||||
),
|
||||
if (_statusMessage != null) ...[
|
||||
const SizedBox(height: 12),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: (_statusSuccess == true
|
||||
? Colors.green
|
||||
: Colors.red)
|
||||
.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Text(
|
||||
_statusMessage!,
|
||||
style: TextStyle(
|
||||
color: _statusSuccess == true
|
||||
? Colors.green.shade700
|
||||
: Colors.red.shade700,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
const SizedBox(height: 24),
|
||||
FilledButton.icon(
|
||||
onPressed: _urlController.text.trim().isEmpty ? null : _saveAndReturn,
|
||||
icon: const Icon(Icons.check),
|
||||
label: const Text('Kaydet'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user