feat(frontend): add multi-language support (en, zh-Hans, zh-Hant, ja)
This commit is contained in:
@@ -2,6 +2,7 @@ import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import '../l10n/app_localizations.dart';
|
||||
import '../providers/auth_provider.dart';
|
||||
import '../providers/settings_provider.dart';
|
||||
import '../services/api_service.dart';
|
||||
@@ -42,9 +43,10 @@ class _MyStreamPageState extends State<MyStreamPage> {
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
final l10n = AppLocalizations.of(context);
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text("Failed to fetch room info")));
|
||||
).showSnackBar(SnackBar(content: Text(l10n?.failedToFetchRoomInfo ?? "Failed to fetch room info")));
|
||||
} finally {
|
||||
if (mounted) {
|
||||
setState(() => _isLoading = false);
|
||||
@@ -55,46 +57,47 @@ class _MyStreamPageState extends State<MyStreamPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final settings = context.watch<SettingsProvider>();
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text("My Stream Console")),
|
||||
appBar: AppBar(title: Text(l10n.myStreamConsole)),
|
||||
body: _isLoading
|
||||
? Center(child: CircularProgressIndicator())
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: _roomInfo == null
|
||||
? Center(child: Text("No room info found."))
|
||||
? Center(child: Text(l10n.noRoomInfo))
|
||||
: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(20),
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildInfoCard(
|
||||
title: "Room Title",
|
||||
title: l10n.roomTitle,
|
||||
value: _roomInfo!['title'],
|
||||
icon: Icons.edit,
|
||||
onTap: () {
|
||||
// TODO: Implement title update API later
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text("Title editing coming soon!")),
|
||||
const SnackBar(content: Text("Title editing coming soon!")),
|
||||
);
|
||||
},
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
const SizedBox(height: 20),
|
||||
_buildInfoCard(
|
||||
title: "RTMP Server URL",
|
||||
title: l10n.rtmpServerUrl,
|
||||
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"),
|
||||
content: Text(l10n.copiedToClipboard),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
const SizedBox(height: 20),
|
||||
_buildInfoCard(
|
||||
title: "Stream Key (Keep Secret!)",
|
||||
title: l10n.streamKey,
|
||||
value: _roomInfo!['stream_key'],
|
||||
icon: Icons.copy,
|
||||
isSecret: true,
|
||||
@@ -104,18 +107,18 @@ class _MyStreamPageState extends State<MyStreamPage> {
|
||||
);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text("Stream Key copied to clipboard"),
|
||||
content: Text(l10n.copiedToClipboard),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
SizedBox(height: 24),
|
||||
const SizedBox(height: 24),
|
||||
AndroidQuickStreamPanel(
|
||||
rtmpBaseUrl: settings.rtmpUrl,
|
||||
streamKey: _roomInfo!['stream_key'],
|
||||
),
|
||||
SizedBox(height: 30),
|
||||
Center(
|
||||
const SizedBox(height: 30),
|
||||
const Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(Icons.info_outline, color: Colors.grey),
|
||||
@@ -143,10 +146,10 @@ class _MyStreamPageState extends State<MyStreamPage> {
|
||||
}) {
|
||||
return Card(
|
||||
child: ListTile(
|
||||
title: Text(title, style: TextStyle(fontSize: 12, color: Colors.grey)),
|
||||
title: Text(title, style: const TextStyle(fontSize: 12, color: Colors.grey)),
|
||||
subtitle: Text(
|
||||
isSecret ? "••••••••••••••••" : value,
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
|
||||
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
|
||||
),
|
||||
trailing: IconButton(icon: Icon(icon), onPressed: onTap),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user