126 lines
4.5 KiB
Dart
126 lines
4.5 KiB
Dart
import 'dart:convert';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:flutter/services.dart';
|
|
import '../providers/auth_provider.dart';
|
|
import '../providers/settings_provider.dart';
|
|
import '../services/api_service.dart';
|
|
|
|
class MyStreamPage extends StatefulWidget {
|
|
@override
|
|
_MyStreamPageState createState() => _MyStreamPageState();
|
|
}
|
|
|
|
class _MyStreamPageState extends State<MyStreamPage> {
|
|
Map<String, dynamic>? _roomInfo;
|
|
bool _isLoading = false;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_fetchMyRoom();
|
|
}
|
|
|
|
Future<void> _fetchMyRoom() async {
|
|
setState(() => _isLoading = true);
|
|
final settings = context.read<SettingsProvider>();
|
|
final auth = context.read<AuthProvider>();
|
|
final api = ApiService(settings, auth.token);
|
|
|
|
try {
|
|
final response = await api.getMyRoom();
|
|
if (response.statusCode == 200) {
|
|
setState(() => _roomInfo = jsonDecode(response.body));
|
|
}
|
|
} catch (e) {
|
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Failed to fetch room info")));
|
|
} finally {
|
|
setState(() => _isLoading = false);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final settings = context.watch<SettingsProvider>();
|
|
|
|
return Scaffold(
|
|
appBar: AppBar(title: Text("My Stream Console")),
|
|
body: _isLoading
|
|
? Center(child: CircularProgressIndicator())
|
|
: _roomInfo == null
|
|
? Center(child: Text("No room info found."))
|
|
: SingleChildScrollView(
|
|
padding: EdgeInsets.all(20),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
_buildInfoCard(
|
|
title: "Room Title",
|
|
value: _roomInfo!['title'],
|
|
icon: Icons.edit,
|
|
onTap: () {
|
|
// TODO: Implement title update API later
|
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Title editing coming soon!")));
|
|
},
|
|
),
|
|
SizedBox(height: 20),
|
|
_buildInfoCard(
|
|
title: "RTMP Server URL",
|
|
value: settings.rtmpUrl,
|
|
icon: Icons.copy,
|
|
onTap: () {
|
|
Clipboard.setData(ClipboardData(text: settings.rtmpUrl));
|
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Server URL copied to clipboard")));
|
|
},
|
|
),
|
|
SizedBox(height: 20),
|
|
_buildInfoCard(
|
|
title: "Stream Key (Keep Secret!)",
|
|
value: _roomInfo!['stream_key'],
|
|
icon: Icons.copy,
|
|
isSecret: true,
|
|
onTap: () {
|
|
Clipboard.setData(ClipboardData(text: _roomInfo!['stream_key']));
|
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Stream Key copied to clipboard")));
|
|
},
|
|
),
|
|
SizedBox(height: 30),
|
|
Center(
|
|
child: Column(
|
|
children: [
|
|
Icon(Icons.info_outline, color: Colors.grey),
|
|
SizedBox(height: 8),
|
|
Text(
|
|
"Use OBS or other tools to stream to this address.",
|
|
textAlign: TextAlign.center,
|
|
style: TextStyle(color: Colors.grey, fontSize: 12),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildInfoCard({
|
|
required String title,
|
|
required String value,
|
|
required IconData icon,
|
|
bool isSecret = false,
|
|
VoidCallback? onTap,
|
|
}) {
|
|
return Card(
|
|
child: ListTile(
|
|
title: Text(title, style: TextStyle(fontSize: 12, color: Colors.grey)),
|
|
subtitle: Text(
|
|
isSecret ? "••••••••••••••••" : value,
|
|
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
|
|
),
|
|
trailing: IconButton(icon: Icon(icon), onPressed: onTap),
|
|
),
|
|
);
|
|
}
|
|
}
|