libretranslatr

This commit is contained in:
y1lm0z
2026-07-14 17:37:17 +03:00
parent 1b8149a4cf
commit 8a562e5bf6
46 changed files with 2040 additions and 106 deletions
+164
View File
@@ -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'),
),
],
),
),
);
}
}