feat: enable Windows app internet access and improve server discovery
This commit is contained in:
1 parent
443a930b57
commit
aebfeca342
5 files changed
+52
-19
No files matched your search
+3
-3
@@ -54,11 +54,11 @@ app.use('/api/ocr', ocrRoutes);
|
||||
app.use('/api/notifications', notificationRoutes);
|
||||
app.use('/api/backup', backupRoutes);
|
||||
|
||||
app.get('/', (req, res) => {
|
||||
app.get(['/', '/api'], (req, res) => {
|
||||
res.set('X-TIS-RMS', 'true');
|
||||
res.json({ message: 'TIS RMS API is running' });
|
||||
});
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log(`Server running on port ${PORT}`);
|
||||
app.listen(PORT, '0.0.0.0', () => {
|
||||
console.log(`Server running on port ${PORT} (0.0.0.0)`);
|
||||
});
|
||||
@@ -2,8 +2,8 @@ class ApiConstants {
|
||||
static const int port = 18484;
|
||||
|
||||
// Runtime-mutable base URL — set by ServerDiscoveryService before first use.
|
||||
// Default: localhost for Windows desktop, Android will discover via LAN scan.
|
||||
static String _baseUrl = 'http://127.0.0.1:$port/api';
|
||||
// Default: remote internet/configured server IP or domain.
|
||||
static String _baseUrl = 'http://198.252.107.197:$port/api';
|
||||
|
||||
static String get baseUrl => _baseUrl;
|
||||
|
||||
|
||||
@@ -33,9 +33,12 @@ class ServerDiscoveryService {
|
||||
|
||||
static Future<bool> ping(String baseUrl) async {
|
||||
try {
|
||||
final rootUrl = baseUrl
|
||||
.replaceAll(RegExp(r'/+$'), '')
|
||||
.replaceAll(RegExp(r'/api$'), '');
|
||||
final dio = Dio(
|
||||
BaseOptions(
|
||||
baseUrl: baseUrl,
|
||||
baseUrl: rootUrl,
|
||||
connectTimeout: _pingTimeout,
|
||||
receiveTimeout: _pingTimeout,
|
||||
),
|
||||
|
||||
@@ -458,7 +458,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen> with SingleTickerProv
|
||||
controller: controller,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Server URL',
|
||||
hintText: 'http://192.168.1.x:18484/api',
|
||||
hintText: 'http://198.252.107.197:18484/api',
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
@@ -467,6 +467,16 @@ class _LoginScreenState extends ConsumerState<LoginScreen> with SingleTickerProv
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
const defaultUrl = 'http://198.252.107.197:18484/api';
|
||||
ApiConstants.setBaseUrl(defaultUrl);
|
||||
await ServerDiscoveryService.save(ApiConstants.baseUrl);
|
||||
if (mounted) setState(() {});
|
||||
Navigator.pop(ctx);
|
||||
},
|
||||
child: const Text('Reset to Default'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(ctx),
|
||||
child: const Text('Cancel'),
|
||||
|
||||
@@ -83,13 +83,7 @@ class _SplashScreenState extends ConsumerState<SplashScreen>
|
||||
// ── Server resolution logic ────────────────────────────────────────────────
|
||||
|
||||
Future<void> _resolveServer() async {
|
||||
// Windows: always local, no need to scan
|
||||
if (!kIsWeb && Platform.isWindows) {
|
||||
ApiConstants.setBaseUrl('http://127.0.0.1:${ApiConstants.port}');
|
||||
return;
|
||||
}
|
||||
|
||||
// Android / other: check saved URL first
|
||||
// 1. Check saved URL first (all platforms including Windows)
|
||||
final saved = await ServerDiscoveryService.getSaved();
|
||||
if (saved != null) {
|
||||
setState(() => _statusText = 'Connecting to saved server…');
|
||||
@@ -98,11 +92,35 @@ class _SplashScreenState extends ConsumerState<SplashScreen>
|
||||
ApiConstants.setBaseUrl(saved);
|
||||
return;
|
||||
}
|
||||
// Saved server is gone — clear it and scan
|
||||
// Saved server is unreachable — clear it and continue discovery
|
||||
await ServerDiscoveryService.clear();
|
||||
}
|
||||
|
||||
// Run subnet scan
|
||||
// 2. Check default configured internet/remote server in ApiConstants
|
||||
final defaultRoot =
|
||||
ApiConstants.baseUrl.replaceAll(RegExp(r'/api/?$'), '');
|
||||
setState(() => _statusText = 'Connecting to remote server…');
|
||||
final defaultAlive = await ServerDiscoveryService.ping(defaultRoot);
|
||||
if (defaultAlive) {
|
||||
await ServerDiscoveryService.save(defaultRoot);
|
||||
ApiConstants.setBaseUrl(defaultRoot);
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. On desktop platforms, check localhost as a fallback (if running local backend)
|
||||
if (!kIsWeb &&
|
||||
(Platform.isWindows || Platform.isLinux || Platform.isMacOS)) {
|
||||
const localUrl = 'http://127.0.0.1:${ApiConstants.port}';
|
||||
setState(() => _statusText = 'Checking local server…');
|
||||
final localAlive = await ServerDiscoveryService.ping(localUrl);
|
||||
if (localAlive) {
|
||||
await ServerDiscoveryService.save(localUrl);
|
||||
ApiConstants.setBaseUrl(localUrl);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Run subnet scan (or prompt for manual entry if nothing found)
|
||||
await _runScan();
|
||||
}
|
||||
|
||||
@@ -193,8 +211,8 @@ class _SplashScreenState extends ConsumerState<SplashScreen>
|
||||
controller: controller,
|
||||
keyboardType: TextInputType.url,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Server IP Address',
|
||||
hintText: '192.168.1.x',
|
||||
labelText: 'Server IP / Domain',
|
||||
hintText: '198.252.107.197 or domain.com',
|
||||
prefixIcon: const Icon(Icons.dns_outlined),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
@@ -227,7 +245,9 @@ class _SplashScreenState extends ConsumerState<SplashScreen>
|
||||
if (ip.isNotEmpty) {
|
||||
final url = ip.startsWith('http')
|
||||
? ip
|
||||
: 'http://$ip:${ApiConstants.port}';
|
||||
: ip.contains(':')
|
||||
? 'http://$ip'
|
||||
: 'http://$ip:${ApiConstants.port}';
|
||||
ServerDiscoveryService.save(url);
|
||||
ApiConstants.setBaseUrl(url);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user