Skip to content

Commit

Permalink
feat: voice calls UI and signaler (#83)
Browse files Browse the repository at this point in the history
* fix: resolve errors thrown due to late initialized promises

* feat(call): add voice call UI and signaler

* chore: remove .g.dart files from remote

* refact: update call screen and signaler

* fix: refactor settings menu in chat screen

* feat: add more settings menu to chat info page

---------

Co-authored-by: marwan2232004 <[email protected]>
  • Loading branch information
Mo2Hefny and marwan2232004 authored Dec 11, 2024
1 parent 83aa956 commit 0cd7389
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 214 deletions.
51 changes: 51 additions & 0 deletions lib/core/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -301,3 +301,54 @@ void vibrate() {
}
});
}

String getRandomLottieAnimation() {
// List of Lottie animation paths
List<String> lottieAnimations = [
'assets/tgs/curious_pigeon.tgs',
'assets/tgs/fruity_king.tgs',
'assets/tgs/graceful_elmo.tgs',
'assets/tgs/hello_anteater.tgs',
'assets/tgs/hello_astronaut.tgs',
'assets/tgs/hello_badger.tgs',
'assets/tgs/hello_bee.tgs',
'assets/tgs/hello_cat.tgs',
'assets/tgs/hello_clouds.tgs',
'assets/tgs/hello_duck.tgs',
'assets/tgs/hello_elmo.tgs',
'assets/tgs/hello_fish.tgs',
'assets/tgs/hello_flower.tgs',
'assets/tgs/hello_food.tgs',
'assets/tgs/hello_fridge.tgs',
'assets/tgs/hello_ghoul.tgs',
'assets/tgs/hello_king.tgs',
'assets/tgs/hello_lama.tgs',
'assets/tgs/hello_monkey.tgs',
'assets/tgs/hello_pigeon.tgs',
'assets/tgs/hello_possum.tgs',
'assets/tgs/hello_rat.tgs',
'assets/tgs/hello_seal.tgs',
'assets/tgs/hello_shawn_sheep.tgs',
'assets/tgs/hello_snail_rabbit.tgs',
'assets/tgs/hello_virus.tgs',
'assets/tgs/hello_water_animal.tgs',
'assets/tgs/hello_whales.tgs',
'assets/tgs/muscles_wizard.tgs',
'assets/tgs/plague_doctor.tgs',
'assets/tgs/screaming_elmo.tgs',
'assets/tgs/shy_elmo.tgs',
'assets/tgs/sick_wizard.tgs',
'assets/tgs/snowman.tgs',
'assets/tgs/spinny_jelly.tgs',
'assets/tgs/sus_moon.tgs',
'assets/tgs/toiletpaper.tgs',
];

// Generate a random index
Random random = Random();
int randomIndex =
random.nextInt(lottieAnimations.length); // Gets a random index

// Return the randomly chosen Lottie animation path
return lottieAnimations[randomIndex];
}
3 changes: 1 addition & 2 deletions lib/core/view/widget/popup_menu_item_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class PopupMenuItemWidget extends StatelessWidget {
return Container(
color: Palette.secondary,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 6.0),
padding: const EdgeInsets.only(left: 12.0, top: 6.0, bottom: 6, right: 2.0),
child: Row(
children: [
Icon(icon, color: color ?? Palette.accentText,),
Expand All @@ -34,7 +34,6 @@ class PopupMenuItemWidget extends StatelessWidget {
fontSize: 16,
),
),
const SizedBox(width: 20),
Expanded(
child: Align(
alignment: Alignment.centerRight,
Expand Down
5 changes: 3 additions & 2 deletions lib/core/view/widget/popup_menu_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@ class PopupMenuWidget extends StatelessWidget {

static void showPopupMenu({
required BuildContext context,
Offset? position,
required List<dynamic> items,
required Function onSelected,
}) {
final RenderBox renderBox = context.findRenderObject() as RenderBox;
final position = renderBox.localToGlobal(Offset.zero); // Get position on screen
position ??= renderBox.localToGlobal(Offset.zero);

showMenu(
context: context,
color: Palette.secondary,
position: RelativeRect.fromLTRB(position.dx, position.dy + renderBox.size.height / 2, position.dx + 100, position.dy),
position: RelativeRect.fromLTRB(position.dx, position.dy - renderBox.size.height, position.dx + 100, position.dy),
items: <PopupMenuEntry<dynamic>>[
...items.map((item) {
return PopupMenuItem<dynamic>(
Expand Down
142 changes: 91 additions & 51 deletions lib/features/chat/view/screens/chat_info_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class _ChatInfoScreen extends ConsumerState<ChatInfoScreen>
late final Future<List<UserModel?>> usersInfoFuture;
late ChatModel chat = widget.chatModel;
late TabController _tabController;
bool showAutoDeleteOptions = false;

Future<List<UserModel?>> getUsersInfo() async {
final ChatModel chat = widget.chatModel;
Expand Down Expand Up @@ -93,6 +94,39 @@ class _ChatInfoScreen extends ConsumerState<ChatInfoScreen>
}
}

void _showMoreSettings() {
var items = [];
if (showAutoDeleteOptions) {
items.addAll([
{'icon': Icons.arrow_back, 'text': 'Back', 'value': 'no-close'},
{'icon': Icons.timer_sharp, 'text': '1 day', 'value': 'auto-1d'},
{'icon': Icons.access_time_rounded, 'text': '1 week', 'value': 'auto-1w'},
{'icon': Icons.share_arrival_time_outlined, 'text': '1 month', 'value': 'auto-1m'},
{'icon': Icons.tune_outlined, 'text': 'Customize', 'value': 'customize'},
{'icon': Icons.do_disturb_alt, 'text': 'Disable', 'value': 'disable-auto', 'color': Palette.error},
]);
} else {
items.addAll([
{'icon': Icons.more_time, 'text': 'Auto-Delete', 'value': 'no-close',
'trailing': const Icon(Icons.arrow_forward_ios, color: Palette.inactiveSwitch, size: 16)},
{'icon': Icons.voice_chat_outlined, 'text': 'Start Video chat', 'value': 'video-call'},
{'icon': Icons.search, 'text': 'Search Members', 'value': 'search'},
{'icon': Icons.logout_outlined, 'text': 'Delete and Leave Group', 'value': 'delete-group'},
{'icon': Icons.add_home_outlined, 'text': 'Add to Home Screen', 'value': 'add-home'},
]);
}

final renderBox = context.findRenderObject() as RenderBox;
final position = Offset(renderBox.size.width, -350);

PopupMenuWidget.showPopupMenu(
context: context,
position: position,
items: items,
onSelected: _handlePopupMenuSelection
);
}

void _showNotificationSettings(BuildContext context) {
var items = !chat.isMuted ? [
{'icon': Icons.music_off_outlined, 'text': 'Disable sound', 'value': 'disable-sound'},
Expand All @@ -109,54 +143,59 @@ class _ChatInfoScreen extends ConsumerState<ChatInfoScreen>
PopupMenuWidget.showPopupMenu(
context: context,
items: items,
onSelected: (value) {
switch (value) {
case 'mute-30m':
_setChatMute(true, DateTime.now().add(const Duration(minutes: 30)));
break;
case 'mute-custom':
DatePicker.showDatePicker(
context,
pickerTheme: const DateTimePickerTheme(
backgroundColor: Palette.secondary,
itemTextStyle: TextStyle(
color: Palette.primaryText,
fontSize: 20,
fontWeight: FontWeight.w600,
),
confirm: Text(
'Confirm',
style: TextStyle(
color: Palette.primary,
fontSize: 18,
fontWeight: FontWeight.w500,
),
),
),
pickerMode: DateTimePickerMode.time,
minDateTime: DateTime.now(),
maxDateTime: DateTime.now().add(const Duration(days: 365)),
initialDateTime: DateTime.now(),
dateFormat: 'dd-MMMM-yyyy',
locale: DateTimePickerLocale.en_us,
onConfirm: (date, time) {
_setChatMute(true, date);
},
);
break;
case 'mute-forever':
_setChatMute(true, null);
break;
case 'unmute':
_setChatMute(false, null);
break;
default:
showToastMessage('Coming soon');
}
}
onSelected: _handlePopupMenuSelection
);
}

void _handlePopupMenuSelection(dynamic value) {
switch (value) {
case 'no-close':
showAutoDeleteOptions = !showAutoDeleteOptions;
break;
case 'mute-30m':
_setChatMute(true, DateTime.now().add(const Duration(minutes: 30)));
break;
case 'mute-custom':
DatePicker.showDatePicker(
context,
pickerTheme: const DateTimePickerTheme(
backgroundColor: Palette.secondary,
itemTextStyle: TextStyle(
color: Palette.primaryText,
fontSize: 20,
fontWeight: FontWeight.w600,
),
confirm: Text(
'Confirm',
style: TextStyle(
color: Palette.primary,
fontSize: 18,
fontWeight: FontWeight.w500,
),
),
),
pickerMode: DateTimePickerMode.time,
minDateTime: DateTime.now(),
maxDateTime: DateTime.now().add(const Duration(days: 365)),
initialDateTime: DateTime.now(),
dateFormat: 'dd-MMMM-yyyy',
locale: DateTimePickerLocale.en_us,
onConfirm: (date, time) {
_setChatMute(true, date);
},
);
break;
case 'mute-forever':
_setChatMute(true, null);
break;
case 'unmute':
_setChatMute(false, null);
break;
default:
showToastMessage('Coming soon');
}
}

void _addMembers() {
// TODO: Implement this
context.go('/add-members', extra: {'chatId': chat.id});
Expand Down Expand Up @@ -190,9 +229,7 @@ class _ChatInfoScreen extends ConsumerState<ChatInfoScreen>
),
const SizedBox(width: 16),
IconButton(
onPressed: () {
// Create popup menu and stuff
},
onPressed: _showMoreSettings,
icon: const Icon(Icons.more_vert)),
],
flexibleSpace: LayoutBuilder(
Expand Down Expand Up @@ -265,10 +302,12 @@ class _ChatInfoScreen extends ConsumerState<ChatInfoScreen>
return Column(
children: [
for (final UserModel? user in users) ...[
user == null ?
const SizedBox.shrink() :
Container(
color: Palette.secondary,
child: MemberTileWidget(
imagePath: user!.photo,
imagePath: user.photo,
text: '${user.screenFirstName} ${user.screenLastName}',
subtext: user.status,
showDivider: false,
Expand Down Expand Up @@ -312,12 +351,13 @@ class _ChatInfoScreen extends ConsumerState<ChatInfoScreen>
],

),
Flexible(
fit: FlexFit.loose,
ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 300),
child: TabBarView(
controller: _tabController,
children: List.generate(2, (index) {
return const Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expand Down
Loading

0 comments on commit 0cd7389

Please sign in to comment.