example app design update & show active speaker
This commit is contained in:
@@ -151,56 +151,74 @@ class _ControlsWidgetState extends State<ControlsWidget> {
|
||||
final videoPub = participant.videoTracks.firstOrNull;
|
||||
final videoEnabled = videoPub != null && !videoPub.muted;
|
||||
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: _unpublishAll,
|
||||
icon: const Icon(EvaIcons.closeCircleOutline),
|
||||
),
|
||||
if (canMute)
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 15,
|
||||
horizontal: 15,
|
||||
),
|
||||
child: Wrap(
|
||||
alignment: WrapAlignment.center,
|
||||
spacing: 5,
|
||||
runSpacing: 5,
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: _muteAudio,
|
||||
icon: const Icon(EvaIcons.mic),
|
||||
)
|
||||
else
|
||||
IconButton(
|
||||
onPressed: _unmuteAudio,
|
||||
icon: const Icon(EvaIcons.micOff),
|
||||
onPressed: _unpublishAll,
|
||||
icon: const Icon(EvaIcons.closeCircleOutline),
|
||||
tooltip: 'Unpublish all',
|
||||
),
|
||||
if (videoEnabled)
|
||||
if (canMute)
|
||||
IconButton(
|
||||
onPressed: _muteAudio,
|
||||
icon: const Icon(EvaIcons.mic),
|
||||
tooltip: 'mute audio',
|
||||
)
|
||||
else
|
||||
IconButton(
|
||||
onPressed: _unmuteAudio,
|
||||
icon: const Icon(EvaIcons.micOff),
|
||||
tooltip: 'un-mute audio',
|
||||
),
|
||||
if (videoEnabled)
|
||||
IconButton(
|
||||
onPressed: _muteVideo,
|
||||
icon: const Icon(EvaIcons.video),
|
||||
tooltip: 'mute video',
|
||||
)
|
||||
else
|
||||
IconButton(
|
||||
onPressed: _unmuteVideo,
|
||||
icon: const Icon(EvaIcons.videoOff),
|
||||
tooltip: 'un-mute video',
|
||||
),
|
||||
IconButton(
|
||||
onPressed: _muteVideo,
|
||||
icon: const Icon(EvaIcons.video),
|
||||
)
|
||||
else
|
||||
IconButton(
|
||||
onPressed: _unmuteVideo,
|
||||
icon: const Icon(EvaIcons.videoOff),
|
||||
icon: Icon(position == CameraPosition.back
|
||||
? EvaIcons.camera
|
||||
: EvaIcons.person),
|
||||
onPressed: () => _toggleCamera(),
|
||||
tooltip: 'toggle camera',
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(position == CameraPosition.back
|
||||
? EvaIcons.camera
|
||||
: EvaIcons.person),
|
||||
onPressed: () => _toggleCamera(),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(EvaIcons.monitor),
|
||||
onPressed: () => _shareScreen(),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: _onTapDisconnect,
|
||||
icon: const Icon(EvaIcons.closeCircle),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: _onTapSendData,
|
||||
icon: const Icon(EvaIcons.paperPlane),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: _onTapReconnect,
|
||||
icon: const Icon(EvaIcons.refresh),
|
||||
),
|
||||
],
|
||||
IconButton(
|
||||
icon: const Icon(EvaIcons.monitor),
|
||||
onPressed: () => _shareScreen(),
|
||||
tooltip: 'share screen (experimental)',
|
||||
),
|
||||
IconButton(
|
||||
onPressed: _onTapDisconnect,
|
||||
icon: const Icon(EvaIcons.closeCircle),
|
||||
tooltip: 'disconnect',
|
||||
),
|
||||
IconButton(
|
||||
onPressed: _onTapSendData,
|
||||
icon: const Icon(EvaIcons.paperPlane),
|
||||
tooltip: 'send demo data',
|
||||
),
|
||||
IconButton(
|
||||
onPressed: _onTapReconnect,
|
||||
icon: const Icon(EvaIcons.refresh),
|
||||
tooltip: 're-connect',
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ import 'package:eva_icons_flutter/eva_icons_flutter.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:livekit_example/theme.dart';
|
||||
|
||||
class NoVideoWidget extends StatelessWidget {
|
||||
//
|
||||
const NoVideoWidget({Key? key}) : super(key: key);
|
||||
@@ -12,7 +14,7 @@ class NoVideoWidget extends StatelessWidget {
|
||||
child: LayoutBuilder(
|
||||
builder: (ctx, constraints) => Icon(
|
||||
EvaIcons.videoOffOutline,
|
||||
color: Theme.of(ctx).colorScheme.secondary,
|
||||
color: LKColors.lkBlue,
|
||||
size: math.min(constraints.maxHeight, constraints.maxWidth) * 0.3,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:eva_icons_flutter/eva_icons_flutter.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_webrtc/flutter_webrtc.dart';
|
||||
import 'package:livekit_client/livekit_client.dart';
|
||||
import 'package:livekit_example/theme.dart';
|
||||
|
||||
import 'no_video.dart';
|
||||
import 'participant_info.dart';
|
||||
@@ -64,7 +65,17 @@ class _ParticipantWidgetState extends State<ParticipantWidget> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext ctx) => Container(
|
||||
color: Theme.of(ctx).cardColor,
|
||||
foregroundDecoration: BoxDecoration(
|
||||
border: widget.participant.isSpeaking
|
||||
? Border.all(
|
||||
width: 5,
|
||||
color: LKColors.lkBlue,
|
||||
)
|
||||
: null,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(ctx).cardColor,
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
// Video
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class LKTextField extends StatelessWidget {
|
||||
final String label;
|
||||
final TextEditingController? ctrl;
|
||||
const LKTextField({
|
||||
required this.label,
|
||||
this.ctrl,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 10),
|
||||
child: Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 15,
|
||||
horizontal: 15,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
width: 1,
|
||||
color: Colors.white.withOpacity(.3),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: TextField(
|
||||
controller: ctrl,
|
||||
decoration: const InputDecoration.collapsed(
|
||||
hintText: '',
|
||||
),
|
||||
keyboardType: TextInputType.url,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user