Add Android quick streaming and logout confirmation

This commit is contained in:
2026-04-22 11:44:15 +08:00
parent b07f243c88
commit c5b7451fc6
8 changed files with 672 additions and 63 deletions

View File

@@ -5,10 +5,13 @@ import 'package:flutter/services.dart';
import '../providers/auth_provider.dart';
import '../providers/settings_provider.dart';
import '../services/api_service.dart';
import '../widgets/android_quick_stream_panel.dart';
class MyStreamPage extends StatefulWidget {
const MyStreamPage({super.key});
@override
_MyStreamPageState createState() => _MyStreamPageState();
State<MyStreamPage> createState() => _MyStreamPageState();
}
class _MyStreamPageState extends State<MyStreamPage> {
@@ -29,13 +32,23 @@ class _MyStreamPageState extends State<MyStreamPage> {
try {
final response = await api.getMyRoom();
if (!mounted) {
return;
}
if (response.statusCode == 200) {
setState(() => _roomInfo = jsonDecode(response.body));
}
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Failed to fetch room info")));
if (!mounted) {
return;
}
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text("Failed to fetch room info")));
} finally {
setState(() => _isLoading = false);
if (mounted) {
setState(() => _isLoading = false);
}
}
}
@@ -48,59 +61,76 @@ class _MyStreamPageState extends State<MyStreamPage> {
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),
),
],
),
),
],
? 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: 24),
AndroidQuickStreamPanel(
rtmpBaseUrl: settings.rtmpUrl,
streamKey: _roomInfo!['stream_key'],
),
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),
),
],
),
),
],
),
),
);
}