164 lines
5.1 KiB
Dart
164 lines
5.1 KiB
Dart
// Expected API:
|
|
// POST /api/auth/login body: {"token":"..."} → {"user_id":"..."}
|
|
// GET /api/channels header: Authorization: Bearer TOKEN
|
|
// → [{"id":"1","name":"Alpha","member_count":3}]
|
|
// POST /api/channels/join body: {"key":"..."} → {"id":"...","name":"..."}
|
|
// GET /api/channels/{id}/livekit-token → {"url":"wss://...","token":"eyJ..."}
|
|
|
|
import 'dart:convert';
|
|
import 'package:http/http.dart' as http;
|
|
import '../config/app_config.dart';
|
|
import '../models/channel.dart';
|
|
import 'auth_service.dart';
|
|
|
|
// ── LiveKit credentials model ─────────────────────────────────────────────
|
|
class LivekitCredentials {
|
|
final String url;
|
|
final String token;
|
|
const LivekitCredentials({required this.url, required this.token});
|
|
}
|
|
|
|
// ── Fake data (only used when AppConfig.debug == true) ────────────────────
|
|
const _fakeChannels = [
|
|
{'id': '1', 'name': 'تیم آلفا', 'member_count': 4},
|
|
{'id': '2', 'name': 'پشتیبانی میدانی', 'member_count': 2},
|
|
{'id': '3', 'name': 'فرماندهی', 'member_count': 7},
|
|
{'id': '4', 'name': 'گروه لجستیک', 'member_count': 3},
|
|
{'id': '5', 'name': 'واحد امنیت', 'member_count': 5},
|
|
];
|
|
// ─────────────────────────────────────────────────────────────────────────
|
|
|
|
class ApiService {
|
|
final AuthService _auth;
|
|
|
|
ApiService(this._auth);
|
|
|
|
Future<Map<String, String>> _headers() async {
|
|
final token = await _auth.getToken();
|
|
return {
|
|
'Content-Type': 'application/json',
|
|
if (token != null) 'Authorization': 'Bearer $token',
|
|
};
|
|
}
|
|
|
|
Future<bool> login(String token) async {
|
|
if (AppConfig.debug) {
|
|
await Future.delayed(const Duration(milliseconds: 600));
|
|
await _auth.saveAuth(token: token, userId: 'debug_user');
|
|
return true;
|
|
}
|
|
|
|
try {
|
|
final res = await http
|
|
.post(
|
|
Uri.parse('${AppConfig.baseUrl}/api/auth/login'),
|
|
headers: {'Content-Type': 'application/json'},
|
|
body: jsonEncode({'token': token}),
|
|
)
|
|
.timeout(const Duration(seconds: 10));
|
|
|
|
if (res.statusCode == 200) {
|
|
final data = jsonDecode(res.body) as Map<String, dynamic>;
|
|
await _auth.saveAuth(
|
|
token: token,
|
|
userId: data['user_id']?.toString(),
|
|
);
|
|
return true;
|
|
}
|
|
return false;
|
|
} catch (_) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<List<Channel>> getChannels() async {
|
|
if (AppConfig.debug) {
|
|
await Future.delayed(const Duration(milliseconds: 500));
|
|
return _fakeChannels
|
|
.map((e) => Channel.fromJson(e as Map<String, dynamic>))
|
|
.toList();
|
|
}
|
|
|
|
try {
|
|
final res = await http
|
|
.get(
|
|
Uri.parse('${AppConfig.baseUrl}/api/channels'),
|
|
headers: await _headers(),
|
|
)
|
|
.timeout(const Duration(seconds: 10));
|
|
|
|
if (res.statusCode == 200) {
|
|
final list = jsonDecode(res.body) as List;
|
|
return list
|
|
.map((e) => Channel.fromJson(e as Map<String, dynamic>))
|
|
.toList();
|
|
}
|
|
return [];
|
|
} catch (_) {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
Future<Channel?> joinPrivateChannel(String key) async {
|
|
if (AppConfig.debug) {
|
|
await Future.delayed(const Duration(milliseconds: 700));
|
|
// کلید صحیح در حالت دیباگ: هر چیزی غیر از "wrong"
|
|
if (key.toLowerCase() == 'wrong') return null;
|
|
return Channel(
|
|
id: 'private_${key.hashCode}',
|
|
name: 'کانال خصوصی ($key)',
|
|
memberCount: 1,
|
|
);
|
|
}
|
|
|
|
try {
|
|
final res = await http
|
|
.post(
|
|
Uri.parse('${AppConfig.baseUrl}/api/channels/join'),
|
|
headers: await _headers(),
|
|
body: jsonEncode({'key': key}),
|
|
)
|
|
.timeout(const Duration(seconds: 10));
|
|
|
|
if (res.statusCode == 200) {
|
|
return Channel.fromJson(
|
|
jsonDecode(res.body) as Map<String, dynamic>);
|
|
}
|
|
return null;
|
|
} catch (_) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
Future<LivekitCredentials?> getLivekitToken(String channelId) async {
|
|
if (AppConfig.debug) {
|
|
await Future.delayed(const Duration(milliseconds: 300));
|
|
return const LivekitCredentials(
|
|
url: 'wss://fake.livekit.io',
|
|
token: 'debug_livekit_token',
|
|
);
|
|
}
|
|
|
|
try {
|
|
final res = await http
|
|
.get(
|
|
Uri.parse(
|
|
'${AppConfig.baseUrl}/api/channels/$channelId/livekit-token'),
|
|
headers: await _headers(),
|
|
)
|
|
.timeout(const Duration(seconds: 10));
|
|
|
|
if (res.statusCode == 200) {
|
|
final data = jsonDecode(res.body) as Map<String, dynamic>;
|
|
return LivekitCredentials(
|
|
url: data['url'] as String,
|
|
token: data['token'] as String,
|
|
);
|
|
}
|
|
return null;
|
|
} catch (_) {
|
|
return null;
|
|
}
|
|
}
|
|
}
|