1.全员观看http接口以及socket回调
2.用户开闭麦接口 3.用户开闭摄像头接口 4.视频-右上角观看自己 5.视频-大屏远端观看别人
This commit is contained in:
parent
e1e6550e31
commit
3a3f9cb665
|
|
@ -67,4 +67,26 @@ abstract class RetrofitClient {
|
||||||
@Field("roomNum") String roomNum,
|
@Field("roomNum") String roomNum,
|
||||||
@Field("userId") String userId,
|
@Field("userId") String userId,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// 获取当前全员观看视频主播
|
||||||
|
@GET("/room/show-user")
|
||||||
|
Future<BaseStructureResult<String>> getTvAnchor(
|
||||||
|
@Query("roomNum") String roomNum,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// 用户开闭麦
|
||||||
|
@GET("/room/oper-micr")
|
||||||
|
Future<BaseStructureResult<String>> setMicr(
|
||||||
|
@Query("roomNum") String roomNum,
|
||||||
|
@Query("enableMicr") bool enableMicr,
|
||||||
|
@Query("uid") String uid,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// 用户开闭摄像头
|
||||||
|
@GET("/room/oper-camera")
|
||||||
|
Future<BaseStructureResult<String>> setCamera(
|
||||||
|
@Query("roomNum") String roomNum,
|
||||||
|
@Query("enableCamera") bool enableCamera,
|
||||||
|
@Query("uid") String uid,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import 'package:get/get.dart';
|
||||||
import 'package:signalr_core/signalr_core.dart';
|
import 'package:signalr_core/signalr_core.dart';
|
||||||
import 'package:wgshare/common/store/user_store.dart';
|
import 'package:wgshare/common/store/user_store.dart';
|
||||||
import 'package:wgshare/utils/count_microphone_volume.dart';
|
import 'package:wgshare/utils/count_microphone_volume.dart';
|
||||||
|
import 'package:wgshare/utils/storage.dart';
|
||||||
import '../../common/config/request_config.dart';
|
import '../../common/config/request_config.dart';
|
||||||
import '../../common/mixins/request_tool_mixin.dart';
|
import '../../common/mixins/request_tool_mixin.dart';
|
||||||
import '../../common/models/common/base_structure_result.dart';
|
import '../../common/models/common/base_structure_result.dart';
|
||||||
|
|
@ -135,14 +136,27 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
|
||||||
BaseStructureResult res = await getClient().applySpeak(state.roomNumber.value);
|
BaseStructureResult res = await getClient().applySpeak(state.roomNumber.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 用户开闭麦
|
||||||
|
Future<void> doHttpSetMicr() async {
|
||||||
|
BaseStructureResult res = await getClient().setMicr(state.roomNumber.value, state.isOpenMicrophone.value, UserStore.to.userInfoEntity.value!.uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 用户开闭摄像头
|
||||||
|
Future<void> doHttpSetCamer() async {
|
||||||
|
BaseStructureResult res = await getClient().setCamera(state.roomNumber.value, state.isOpenCamera.value, UserStore.to.userInfoEntity.value!.uid);
|
||||||
|
}
|
||||||
|
|
||||||
/// 结束发言
|
/// 结束发言
|
||||||
Future<void> doHttpCancelSpeak() async {
|
Future<void> doHttpCancelSpeak() async {
|
||||||
BaseStructureResult res = await getClient().cancelSpeak(state.meetingRoomInfo.value!.id, state.meetingRoomInfo.value!.roomNum, UserStore.to.userInfoEntity.value!.uid);
|
BaseStructureResult res = await getClient().cancelSpeak(state.meetingRoomInfo.value!.id, state.meetingRoomInfo.value!.roomNum, UserStore.to.userInfoEntity.value!.uid);
|
||||||
setClientRole("观众");
|
setClientRole("观众");
|
||||||
|
setMicrophoneOpen(false);
|
||||||
|
setCameraOpen(false);
|
||||||
|
changePageState(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 设置麦克风是否开启
|
/// 设置麦克风是否开启
|
||||||
void setMicrophoneOpen(bool isOpen){
|
Future<void> setMicrophoneOpen(bool isOpen) async{
|
||||||
state.isOpenMicrophone.value = isOpen;
|
state.isOpenMicrophone.value = isOpen;
|
||||||
for(var i = 0; i < state.cacheUsers.value.length; i++){
|
for(var i = 0; i < state.cacheUsers.value.length; i++){
|
||||||
if(state.cacheUsers.value[i].uid == UserStore.to.userInfoEntity.value!.uid){
|
if(state.cacheUsers.value[i].uid == UserStore.to.userInfoEntity.value!.uid){
|
||||||
|
|
@ -150,21 +164,42 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.users.value = state.cacheUsers.value;
|
state.users.value = state.cacheUsers.value;
|
||||||
if(isOpen == true){
|
setEnableLocalAudio(isOpen);
|
||||||
setClientRole("主播");
|
doHttpSetMicr();
|
||||||
}else{
|
|
||||||
setClientRole("观众");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 设置视频是否打开
|
/// 设置视频是否打开
|
||||||
void setCameraOpen(bool isOpen){
|
void setCameraOpen(bool isOpen){
|
||||||
state.isOpenCamera.value = isOpen;
|
state.isOpenCamera.value = isOpen;
|
||||||
|
setEnableLocalVideo(isOpen);
|
||||||
|
if(state.isOpenMicrophone.value == false){
|
||||||
|
setMicrophoneOpen(isOpen);
|
||||||
|
}
|
||||||
if(isOpen == true){
|
if(isOpen == true){
|
||||||
setEnableLocalVideo(isOpen);
|
|
||||||
setClientRole("主播");
|
setClientRole("主播");
|
||||||
|
changePageState(1);
|
||||||
|
doHttpGetTvAnchor();
|
||||||
}else{
|
}else{
|
||||||
setClientRole("观众");
|
changePageState(0);
|
||||||
|
}
|
||||||
|
doHttpSetCamer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 获取当前全员观看视频主播
|
||||||
|
Future<void> doHttpGetTvAnchor() async {
|
||||||
|
BaseStructureResult res = await getClient().getTvAnchor(state.roomNumber.value);
|
||||||
|
if(res.data!.toString().length != 9){
|
||||||
|
state.remoteUid.value = res.data!;
|
||||||
|
changePageState(1);
|
||||||
|
/*var isSaveLive = false;
|
||||||
|
for(MeetingRoomUser mru in state.cacheUsers.value){
|
||||||
|
if(mru.uid == state.remoteUid.value){
|
||||||
|
isSaveLive = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(isSaveLive == true){
|
||||||
|
changePageState(1);
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -230,6 +265,8 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
|
||||||
state.isSpeak.value = true;
|
state.isSpeak.value = true;
|
||||||
state.isOpenMicrophone.value = true;
|
state.isOpenMicrophone.value = true;
|
||||||
setClientRole("主播");
|
setClientRole("主播");
|
||||||
|
setEnableLocalAudio(true);
|
||||||
|
doHttpSetMicr();
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
debugPrint("wgs输出===:Socket-停止发言:${e?[0]}--${e?[1]}");
|
debugPrint("wgs输出===:Socket-停止发言:${e?[0]}--${e?[1]}");
|
||||||
|
|
@ -244,6 +281,8 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
|
||||||
state.isSpeak.value = false;
|
state.isSpeak.value = false;
|
||||||
state.isOpenMicrophone.value = false;
|
state.isOpenMicrophone.value = false;
|
||||||
setClientRole("观众");
|
setClientRole("观众");
|
||||||
|
setEnableLocalAudio(false);
|
||||||
|
doHttpSetMicr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
update();
|
update();
|
||||||
|
|
@ -317,6 +356,18 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
|
||||||
state.isOpenMicrophone.value = false;
|
state.isOpenMicrophone.value = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/// 设置新的全员观看视频主播回调
|
||||||
|
state.hubConnection.value?.on("ShowUser", (e){
|
||||||
|
// var jsonStr = const Utf8Decoder().convert(json.encode(e).runes.toList());
|
||||||
|
var jsonStr = json.encode(e);
|
||||||
|
List list = json.decode(jsonStr);
|
||||||
|
/*if(list[0].toString().length != 9){
|
||||||
|
state.remoteUid.value = list[0].toString();
|
||||||
|
}*/
|
||||||
|
doHttpGetTvAnchor();
|
||||||
|
debugPrint("wgs输出===:Socket-设置新的全员观看视频主播:${list[0]}");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 加入会议室
|
/// 加入会议室
|
||||||
|
|
@ -365,7 +416,7 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
|
||||||
// 打开用户音量回调
|
// 打开用户音量回调
|
||||||
await state.rctEngine.value?.enableAudioVolumeIndication(interval: 200, smooth: 3, reportVad: true);
|
await state.rctEngine.value?.enableAudioVolumeIndication(interval: 200, smooth: 3, reportVad: true);
|
||||||
// 启用音频模块
|
// 启用音频模块
|
||||||
await state.rctEngine.value?.enableAudio();
|
setEnableLocalAudio(true);
|
||||||
|
|
||||||
joinMeetingToRtc();
|
joinMeetingToRtc();
|
||||||
|
|
||||||
|
|
@ -503,9 +554,19 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
|
||||||
await state.rctEngine.value?.setEnableSpeakerphone(mode == 1 ? false : true);
|
await state.rctEngine.value?.setEnableSpeakerphone(mode == 1 ? false : true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 设置是否打开本地视频采集
|
/// 设置是否启用音频模块
|
||||||
|
Future<void> setEnableLocalAudio(bool enabled) async {
|
||||||
|
if(enabled == true){
|
||||||
|
// 启用音频模块
|
||||||
|
await state.rctEngine.value?.enableAudio();
|
||||||
|
}else{
|
||||||
|
// 关闭音频模块
|
||||||
|
await state.rctEngine.value?.disableAudio();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 设置是否启用视频模块
|
||||||
Future<void> setEnableLocalVideo(bool enabled) async {
|
Future<void> setEnableLocalVideo(bool enabled) async {
|
||||||
state.isOpenCamera.value = enabled;
|
|
||||||
if(enabled == true){
|
if(enabled == true){
|
||||||
// 启用视频模块
|
// 启用视频模块
|
||||||
await state.rctEngine.value?.enableVideo();
|
await state.rctEngine.value?.enableVideo();
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,8 @@ class MeetingMainState {
|
||||||
late RxDouble microphoneVolume = 0.0.obs;
|
late RxDouble microphoneVolume = 0.0.obs;
|
||||||
/// 是否打开摄像头
|
/// 是否打开摄像头
|
||||||
late RxBool isOpenCamera = false.obs;
|
late RxBool isOpenCamera = false.obs;
|
||||||
|
/// 当前视频主播ID
|
||||||
|
late RxString remoteUid = "".obs;
|
||||||
|
|
||||||
/// 聊天数据
|
/// 聊天数据
|
||||||
late RxList<MeetingRoomMsg> meetingRoomMsgs = RxList([]);
|
late RxList<MeetingRoomMsg> meetingRoomMsgs = RxList([]);
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,12 @@ class MeetingMainPage extends StatelessWidget {
|
||||||
Visibility(
|
Visibility(
|
||||||
visible: state.pageState.value == 1,
|
visible: state.pageState.value == 1,
|
||||||
child: null != state.rctEngine.value
|
child: null != state.rctEngine.value
|
||||||
? MeetingMainVideoComponent(rtcEngine: state.rctEngine.value!, channelId: state.roomNumber.value,isOpenCamera: state.isOpenCamera.value)
|
? MeetingMainVideoComponent(
|
||||||
|
rtcEngine: state.rctEngine.value!,
|
||||||
|
channelId: state.roomNumber.value,
|
||||||
|
isOpenCamera: state.isOpenCamera.value,
|
||||||
|
remoteUid: state.remoteUid.value,
|
||||||
|
)
|
||||||
: Container()
|
: Container()
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,16 @@ import 'meeting_main_video_logic.dart';
|
||||||
import 'meeting_main_video_state.dart';
|
import 'meeting_main_video_state.dart';
|
||||||
|
|
||||||
class MeetingMainVideoComponent extends StatelessWidget {
|
class MeetingMainVideoComponent extends StatelessWidget {
|
||||||
MeetingMainVideoComponent({super.key, required this.rtcEngine, required this.channelId, required this.isOpenCamera});
|
MeetingMainVideoComponent(
|
||||||
|
{super.key,
|
||||||
|
required this.rtcEngine,
|
||||||
|
required this.channelId,
|
||||||
|
required this.isOpenCamera,
|
||||||
|
required this.remoteUid});
|
||||||
|
|
||||||
final RtcEngine rtcEngine;
|
final RtcEngine rtcEngine;
|
||||||
final String channelId;
|
final String channelId;
|
||||||
|
final String remoteUid;
|
||||||
final bool isOpenCamera;
|
final bool isOpenCamera;
|
||||||
|
|
||||||
final MeetingMainVideoLogic logic = Get.put(MeetingMainVideoLogic());
|
final MeetingMainVideoLogic logic = Get.put(MeetingMainVideoLogic());
|
||||||
|
|
@ -38,82 +44,81 @@ class MeetingMainVideoComponent extends StatelessWidget {
|
||||||
debugPrint('wgs输出===:$index');
|
debugPrint('wgs输出===:$index');
|
||||||
},
|
},
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Container(
|
Stack(
|
||||||
child: Stack(
|
alignment: Alignment.center,
|
||||||
alignment: Alignment.center,
|
children: [
|
||||||
children: [
|
remoteUid != ""
|
||||||
Container(
|
? AgoraVideoView(
|
||||||
decoration: BoxDecoration(
|
controller: VideoViewController.remote(
|
||||||
image: DecorationImage(
|
rtcEngine: rtcEngine,
|
||||||
fit: BoxFit.fill,
|
canvas: VideoCanvas(uid: int.tryParse(remoteUid)),
|
||||||
image: NetworkImage(
|
connection: RtcConnection(channelId: channelId),
|
||||||
"https://tse4-mm.cn.bing.net/th/id/OIP-C.acWMNnQ04Ks6Bh2b9Zq8XwHaKF?rs=1&pid=ImgDetMain",
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)),
|
)
|
||||||
Positioned(
|
: const CircularProgressIndicator(),
|
||||||
bottom: 110,
|
Positioned(
|
||||||
child: Image.asset(
|
bottom: 110,
|
||||||
'assets/images/meeting_main_hang_up.png',
|
child: Image.asset(
|
||||||
width: 50.w,
|
'assets/images/meeting_main_hang_up.png',
|
||||||
height: 50.h,
|
width: 50.w,
|
||||||
|
height: 50.h,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
top: 16,
|
||||||
|
right: 16,
|
||||||
|
child: Container(
|
||||||
|
height: 30,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
color: ColorUtil.Color_0_0_0_96),
|
||||||
|
padding: const EdgeInsets.only(left: 12, right: 12),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'正在讲话:',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10.sp,
|
||||||
|
color: ColorUtil.Color_185_184_184),
|
||||||
|
),
|
||||||
|
Image.asset(
|
||||||
|
'assets/images/meeting_main_speak2.png',
|
||||||
|
width: 20.w,
|
||||||
|
height: 20.h,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'晓晓',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10.sp,
|
||||||
|
color: ColorUtil.Color_185_184_184),
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Positioned(
|
),
|
||||||
top: 16,
|
|
||||||
right: 16,
|
/// 右上角小窗
|
||||||
child: Container(
|
Visibility(
|
||||||
height: 30,
|
visible: isOpenCamera,
|
||||||
decoration: BoxDecoration(
|
child: Positioned(
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
color: ColorUtil.Color_0_0_0_96),
|
|
||||||
padding: const EdgeInsets.only(left: 12, right: 12),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'正在讲话:',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 10.sp,
|
|
||||||
color: ColorUtil.Color_185_184_184),
|
|
||||||
),
|
|
||||||
Image.asset(
|
|
||||||
'assets/images/meeting_main_speak2.png',
|
|
||||||
width: 20.w,
|
|
||||||
height: 20.h,
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
'晓晓',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 10.sp,
|
|
||||||
color: ColorUtil.Color_185_184_184),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
/// 右上角小窗
|
|
||||||
Positioned(
|
|
||||||
top: 58,
|
top: 58,
|
||||||
right: 12,
|
right: 13,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
Visibility(
|
SizedBox(
|
||||||
visible: isOpenCamera,
|
width: 120,
|
||||||
child: SizedBox(
|
height: 150,
|
||||||
width: 120.w,
|
|
||||||
height: 150.h,
|
|
||||||
child: Center(
|
child: Center(
|
||||||
child: isOpenCamera
|
child: isOpenCamera
|
||||||
? AgoraVideoView(
|
? AgoraVideoView(
|
||||||
controller: VideoViewController(
|
controller: VideoViewController(
|
||||||
rtcEngine: rtcEngine,
|
rtcEngine: rtcEngine,
|
||||||
canvas: VideoCanvas(uid: int.parse(UserStore.to.userInfoEntity.value!.uid)),
|
canvas: const VideoCanvas(uid: 0),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: const CircularProgressIndicator(),
|
: const CircularProgressIndicator(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
Positioned(
|
Positioned(
|
||||||
left: 4,
|
left: 4,
|
||||||
bottom: 4,
|
bottom: 4,
|
||||||
|
|
@ -127,20 +132,22 @@ class MeetingMainVideoComponent extends StatelessWidget {
|
||||||
Container(
|
Container(
|
||||||
height: 15,
|
height: 15,
|
||||||
margin: const EdgeInsets.only(left: 4),
|
margin: const EdgeInsets.only(left: 4),
|
||||||
padding: const EdgeInsets.only(left: 4, right: 4),
|
padding:
|
||||||
|
const EdgeInsets.only(left: 4, right: 4),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(2),
|
borderRadius: BorderRadius.circular(2),
|
||||||
color: ColorUtil.Color_0_0_0_96),
|
color: ColorUtil.Color_0_0_0_96),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Image.asset(
|
/*Image.asset(
|
||||||
'assets/images/meeting_main_microphone_open.png',
|
'assets/images/meeting_main_microphone_open.png',
|
||||||
width: 13.w,
|
width: 13.w,
|
||||||
height: 14.h,
|
height: 14.h,
|
||||||
),
|
),
|
||||||
SizedBox(width: 4.w),
|
SizedBox(width: 4.w),*/
|
||||||
Text(
|
Text(
|
||||||
'晓晓',
|
UserStore
|
||||||
|
.to.userInfoEntity.value!.userName,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 10.sp,
|
fontSize: 10.sp,
|
||||||
color: ColorUtil.Color_185_184_184),
|
color: ColorUtil.Color_185_184_184),
|
||||||
|
|
@ -153,15 +160,14 @@ class MeetingMainVideoComponent extends StatelessWidget {
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
],
|
)
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
color: ColorUtil.Color_57_57_57,
|
color: ColorUtil.Color_57_57_57,
|
||||||
child: GridView.builder(
|
child: GridView.builder(
|
||||||
gridDelegate:
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
SliverGridDelegateWithFixedCrossAxisCount(
|
|
||||||
crossAxisCount: 2,
|
crossAxisCount: 2,
|
||||||
childAspectRatio: 0.8,
|
childAspectRatio: 0.8,
|
||||||
crossAxisSpacing: 0),
|
crossAxisSpacing: 0),
|
||||||
|
|
@ -178,8 +184,7 @@ class MeetingMainVideoComponent extends StatelessWidget {
|
||||||
"https://tse1-mm.cn.bing.net/th/id/OIP-C.hdhK40Dw3yN_2mjNQNqFCgAAAA?w=186&h=186&c=7&r=0&o=5&pid=1.7",
|
"https://tse1-mm.cn.bing.net/th/id/OIP-C.hdhK40Dw3yN_2mjNQNqFCgAAAA?w=186&h=186&c=7&r=0&o=5&pid=1.7",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)),
|
||||||
),
|
|
||||||
Positioned(
|
Positioned(
|
||||||
left: 4,
|
left: 4,
|
||||||
bottom: 4,
|
bottom: 4,
|
||||||
|
|
@ -193,7 +198,8 @@ class MeetingMainVideoComponent extends StatelessWidget {
|
||||||
Container(
|
Container(
|
||||||
height: 15,
|
height: 15,
|
||||||
margin: const EdgeInsets.only(left: 4),
|
margin: const EdgeInsets.only(left: 4),
|
||||||
padding: const EdgeInsets.only(left: 4, right: 4),
|
padding:
|
||||||
|
const EdgeInsets.only(left: 4, right: 4),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(2),
|
borderRadius: BorderRadius.circular(2),
|
||||||
color: ColorUtil.Color_0_0_0_96),
|
color: ColorUtil.Color_0_0_0_96),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue