From b2c8ffd6167ed307aa86d50f9bfbbfbf69764910 Mon Sep 17 00:00:00 2001 From: Tyler Jeong Date: Wed, 29 Oct 2025 13:04:27 +0900 Subject: [PATCH] Add 1.2.0. --- CHANGELOG.md | 5 + README.md | 4 +- lib/fonts/SendbirdIcons.ttf | Bin 15252 -> 15428 bytes .../sbu_bottom_sheet_user_component.dart | 4 +- .../dialog/sbu_delayed_connecting_dialog.dart | 181 ++++++++++++++++++ .../internal/resource/sbu_text_styles.dart | 11 ++ .../internal/utils/sbu_time_extensions.dart | 18 ++ lib/src/public/resource/sbu_icons.dart | 76 ++++---- .../public/resource/sbu_string_provider.dart | 19 ++ .../sbu_group_channel_create_screen.dart | 5 +- lib/src/public/sendbird_uikit.dart | 80 +++++++- pubspec.yaml | 4 +- 12 files changed, 363 insertions(+), 44 deletions(-) create mode 100644 lib/src/internal/component/dialog/sbu_delayed_connecting_dialog.dart create mode 100644 lib/src/internal/utils/sbu_time_extensions.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index cb9945b..e952e78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## v1.2.0 (Oct 29, 2025) + +### Features +- Added a `navigatorKey` parameter in `SendbirdUIKit.init()` to show the delayed connecting dialog + ## v1.1.0 (Jul 30, 2025) ### Features diff --git a/README.md b/README.md index c6cc096..3c56bf6 100644 --- a/README.md +++ b/README.md @@ -38,8 +38,8 @@ Add following dependencies and fonts for `SendbirdIcons` in `pubspec.yaml`. ```yaml dependencies: - sendbird_uikit: ^1.1.0 - sendbird_chat_sdk: ^4.5.1 + sendbird_uikit: ^1.2.0 + sendbird_chat_sdk: ^4.7.0 flutter: fonts: diff --git a/lib/fonts/SendbirdIcons.ttf b/lib/fonts/SendbirdIcons.ttf index b0283a0c07e8696c1a03b2cec31ecb8800bed305..6a03236161d1566c42b6fa214827d44705acdab3 100644 GIT binary patch delta 955 zcmY*XZAcSg9RELen_D{F=H?VXm}zR(MrPCbGN*(=;52%(=mk67qg(8@bvI259EG2v z7wat4FC~QZr4MoveK08zKPgD`!AK&+K*Z<;gdlPKZ#xN}<9E;R?f)Ei+|Z5L-oe6{ z3_$JyKx+rjMZTXKEdXGa0W@#Af_g?w*ojce#-gm>pvH;`xQ~?M?>dfA0nSZ z?DzB0-rr^MIG(qP`cE+2!JQxR9s|$~q3-9o-UvAb&oIwHogd;PVw+eYO6v&FJ2QG1heCwiuHNWz$ngW@WRf{+sjJZ;QBM7L(T?M$1tAHxxDxey<3aCM@0&0<~05@_K zP$v!P8r^BLhKq(T=|cMRjJ%9s#*(qYIB485<(L{x^X5Erzj-FJIMbgwY-zDPu*_M9 zt&3T~tSQ?8+Z_Peq}OIkw~r3UWBcqx9?91eIcx6#krxUsq)6XNUr0rzv-16eULsZ7 z2c%DjeDZty7At9;5&3PIhs2&RanM389LDcZXwG((u;s2wSEaM0xTLs1m!eCtX4|rD z#H!E&#dIohxneTC6R<$YlR`u5e_+c%C}QN+!3P4 zbx~6?3HzwPMFZiGxJNYvDwWm@dXr^=b_!JVrzJ9h^5Gt8R(T}Y=jaRsgVdM$-$@ol z$_X9*Zd%lBnG1XZoWOl1%i%HI7E}}Xn>~~iL^VUoDt|zgKm)u H_OX&6GfU074+JhLFJAS)}9F8blLeY!QzHqP1BtUxcM zi?A@h(Oo~#jow7#7>Ni4c~N%>5h7j)8XUanLJFdw^`3L24<4TPd7k%uzjHWexmdbA z(=ss+K&Am;I3|hN(%TO?0B#k)vN$?6KH{J2ISF8M0|ep;D#qKNZB}FN2BIs0hP97> zg!K~QP(sQTzn`vDaNic{A7h!Ac;edG`vBGw>U)w{%#tB^j`=>+&1q4h+Iq#`8!v^>Qyio;^Yp{0>EHH}$Hgka%(jr<^e-#b1E=|xY z;}FcVP-LzAU0hJb%KR_(p0~Rkddh7WJph8bV42`9b>TPybnZ3*I)_bw&OIhT=ZFc= zSug>;$War39xGYFu|*{bu^4SOBl zLGP4r*tb(ZSieyJ+kZs$+4k&JR}M}Q^;5Hrs85>$M7`W{rHWl>TW00MFH}$a5Mkc} zaYh4^F9(7a^-V_~VX4q7_VDN`YiOEc107klq4O$FqO1_Uqwa)fNvAs*%cO%+CQfBB zm&~M<>Rm&o4zr?)B98tS(oHHWY%?;`U^il!N}0lLD$@~}DhW2-yWelFQD{1D_9;}9 wV+r=I_c*H&8awj}m7T_dd|D5Z1?n}g6XjG;RD$`mjK6G+;pGxkqWCTT0YS*x0{{R3 diff --git a/lib/src/internal/component/basic/sbu_bottom_sheet_user_component.dart b/lib/src/internal/component/basic/sbu_bottom_sheet_user_component.dart index 88a7106..dbb5c6e 100644 --- a/lib/src/internal/component/basic/sbu_bottom_sheet_user_component.dart +++ b/lib/src/internal/component/basic/sbu_bottom_sheet_user_component.dart @@ -81,7 +81,9 @@ class SBUBottomSheetUserComponentState ..name = '' ..isDistinct = false, ).then((channel) { - Navigator.pop(context); + if (context.mounted) { + Navigator.pop(context); + } on1On1ChannelCreated(channel); }); diff --git a/lib/src/internal/component/dialog/sbu_delayed_connecting_dialog.dart b/lib/src/internal/component/dialog/sbu_delayed_connecting_dialog.dart new file mode 100644 index 0000000..529e1e5 --- /dev/null +++ b/lib/src/internal/component/dialog/sbu_delayed_connecting_dialog.dart @@ -0,0 +1,181 @@ +// Copyright (c) 2025 Sendbird, Inc. All rights reserved. + +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:sendbird_uikit/sendbird_uikit.dart'; +import 'package:sendbird_uikit/src/internal/component/base/sbu_base_component.dart'; +import 'package:sendbird_uikit/src/internal/component/basic/sbu_text_button_component.dart'; +import 'package:sendbird_uikit/src/internal/component/basic/sbu_text_component.dart'; +import 'package:sendbird_uikit/src/internal/resource/sbu_text_styles.dart'; +import 'package:sendbird_uikit/src/internal/utils/sbu_time_extensions.dart'; + +class SBUDelayedConnectingDialog extends SBUStatefulComponent { + final int retryAfter; + final bool showCloseButton; + final void Function()? onCloseButtonClicked; + final String? closeButtonText; + + const SBUDelayedConnectingDialog({ + required this.retryAfter, + this.showCloseButton = false, + this.onCloseButtonClicked, + this.closeButtonText, + super.key, + }); + + @override + State createState() => SBUDelayedConnectingDialogState(); +} + +class SBUDelayedConnectingDialogState + extends State { + late int currentRetryAfter; + late final DateTime startTime; + Timer? _timer; + + @override + void initState() { + super.initState(); + currentRetryAfter = widget.retryAfter; + startTime = DateTime.now(); + _startTimer(); + } + + void _startTimer() { + _timer = Timer.periodic(const Duration(seconds: 1), (timer) { + updateRetryAfter(); + if (currentRetryAfter <= 0) { + _timer?.cancel(); + } + }); + } + + @override + void dispose() { + _timer?.cancel(); + super.dispose(); + } + + void updateRetryAfter() { + final now = DateTime.now(); + final elapsedTime = now.difference(startTime).inMilliseconds; + final updatedRetryAfter = widget.retryAfter - elapsedTime / 1000; + + setState(() { + currentRetryAfter = updatedRetryAfter > 0 ? updatedRetryAfter.ceil() : 0; + }); + } + + @override + Widget build(BuildContext context) { + final isLightTheme = context.watch().isLight(); + final strings = context.watch().strings; + + return PopScope( + canPop: false, + child: Container( + width: double.maxFinite, + height: double.maxFinite, + color: SBUColors.overlayLight, + child: Center( + child: Container( + width: 280, + decoration: BoxDecoration( + color: isLightTheme + ? SBUColors.background50 + : SBUColors.background500, + borderRadius: const BorderRadius.all(Radius.circular(4)), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 24), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24), + child: DefaultTextStyle.merge( + style: kIsWeb + ? const TextStyle(decoration: TextDecoration.none) + : null, + child: SBUTextComponent( + text: strings.youWillBeReconnectedShortly, + textType: SBUTextType.heading1, + textColorType: SBUTextColorType.text01, + maxLines: 3, + ), + ), + ), + const SizedBox(height: 16), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24), + child: DefaultTextStyle.merge( + style: kIsWeb + ? const TextStyle(decoration: TextDecoration.none) + : null, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + SBUTextComponent( + text: currentRetryAfter > 0 + ? strings.estimatedWaitingTime + : '', + textType: SBUTextType.body3, + textColorType: SBUTextColorType.text02, + ), + const SizedBox(width: 4), + SBUTextComponent( + text: currentRetryAfter > 0 + ? currentRetryAfter.toTimeString() + : '', + textType: SBUTextType.body3Bold, + textColorType: SBUTextColorType.text02, + ), + ], + ), + ), + ), + const SizedBox(height: 24), + if (widget.showCloseButton) + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Container( + margin: const EdgeInsets.only(right: 8, bottom: 4), + child: DefaultTextStyle.merge( + style: kIsWeb + ? const TextStyle( + decoration: TextDecoration.none) + : null, + child: SBUTextButtonComponent( + height: 32, + padding: const EdgeInsets.all(8), + text: SBUTextComponent( + text: (widget.closeButtonText != null) + ? widget.closeButtonText! + : strings.close, + textType: SBUTextType.button, + textColorType: SBUTextColorType.primary, + ), + onButtonClicked: () async { + Navigator.pop(context); + + if (widget.onCloseButtonClicked != null) { + widget.onCloseButtonClicked!(); + } + }, + ), + ), + ), + ], + ), + const SizedBox(height: 12), + ], + ), + ), + ), + )); + } +} diff --git a/lib/src/internal/resource/sbu_text_styles.dart b/lib/src/internal/resource/sbu_text_styles.dart index 6105fd0..f495352 100644 --- a/lib/src/internal/resource/sbu_text_styles.dart +++ b/lib/src/internal/resource/sbu_text_styles.dart @@ -12,6 +12,7 @@ enum SBUTextType { body1, body2, body3, + body3Bold, button, caption1, caption2, @@ -123,6 +124,16 @@ class SBUTextStyles { decorationThickness: 0, leadingDistribution: TextLeadingDistribution.even, ); + case SBUTextType.body3Bold: + return TextStyle( + fontFamily: fontFamily, + fontWeight: FontWeight.w700, + fontSize: 14, + height: 1.428, + color: color, + decorationThickness: 0, + leadingDistribution: TextLeadingDistribution.even, + ); case SBUTextType.button: return TextStyle( fontFamily: fontFamily, diff --git a/lib/src/internal/utils/sbu_time_extensions.dart b/lib/src/internal/utils/sbu_time_extensions.dart new file mode 100644 index 0000000..c81eaa4 --- /dev/null +++ b/lib/src/internal/utils/sbu_time_extensions.dart @@ -0,0 +1,18 @@ +// Copyright (c) 2025 Sendbird, Inc. All rights reserved. + +extension SBUTimeExtensions on int { + String toTimeString() { + final int hours = this ~/ 3600; + final int minutes = (this % 3600) ~/ 60; + final int seconds = this % 60; + + if (hours == 0) { + return '${minutes.toString().padLeft(2, '0')}:' + '${seconds.toString().padLeft(2, '0')}'; + } + + return '${hours.toString().padLeft(2, '0')}:' + '${minutes.toString().padLeft(2, '0')}:' + '${seconds.toString().padLeft(2, '0')}'; + } +} diff --git a/lib/src/public/resource/sbu_icons.dart b/lib/src/public/resource/sbu_icons.dart index b266e0f..f142b9f 100644 --- a/lib/src/public/resource/sbu_icons.dart +++ b/lib/src/public/resource/sbu_icons.dart @@ -84,62 +84,64 @@ class SBUIcons { const IconData(0xe81e, fontFamily: _kFontFam, fontPackage: _kFontPkg); static IconData leave = const IconData(0xe81f, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData moderations = + static IconData markAsUnread = const IconData(0xe820, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData more = + static IconData members = const IconData(0xe821, fontFamily: _kFontFam, fontPackage: _kFontPkg); static IconData message = const IconData(0xe822, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData members = + static IconData moderations = const IconData(0xe823, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData mute = + static IconData more = const IconData(0xe824, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData notificationsFilled = + static IconData mute = const IconData(0xe825, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData notificationsOffFilled = + static IconData notificationsFilled = const IconData(0xe826, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData notifications = + static IconData notificationsOffFilled = const IconData(0xe827, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData operator = + static IconData notifications = const IconData(0xe828, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData photo = + static IconData operator = const IconData(0xe829, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData play = + static IconData photo = const IconData(0xe82a, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData plus = + static IconData play = const IconData(0xe82b, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData question = + static IconData plus = const IconData(0xe82c, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData remove = + static IconData question = const IconData(0xe82d, fontFamily: _kFontFam, fontPackage: _kFontPkg); static IconData refresh = const IconData(0xe82e, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData replyFilled = + static IconData remove = const IconData(0xe82f, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData reply = + static IconData replyFilled = const IconData(0xe830, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData send = + static IconData reply = const IconData(0xe831, fontFamily: _kFontFam, fontPackage: _kFontPkg); static IconData search = const IconData(0xe832, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData settingFilled = + static IconData send = const IconData(0xe833, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData spinner = + static IconData settingFilled = const IconData(0xe834, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static IconData spinner = + const IconData(0xe835, fontFamily: _kFontFam, fontPackage: _kFontPkg); static IconData streaming = const IconData(0xe836, fontFamily: _kFontFam, fontPackage: _kFontPkg); static IconData supergroup = const IconData(0xe837, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData thumbnailNone = + static IconData theme = const IconData(0xe838, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData user = + static IconData thumbnailNone = const IconData(0xe839, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData unarchive = + static IconData time = const IconData(0xe83a, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData markAsUnread = + static IconData unarchive = + const IconData(0xe83b, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static IconData user = const IconData(0xe83c, fontFamily: _kFontFam, fontPackage: _kFontPkg); - static IconData theme = - const IconData(0xe83d, fontFamily: _kFontFam, fontPackage: _kFontPkg); /// Sets icons. static void setIcons({ @@ -175,10 +177,11 @@ class SBUIcons { required IconData gif, required IconData info, required IconData leave, + required IconData markAsUnread, + required IconData members, + required IconData message, required IconData moderations, required IconData more, - required IconData message, - required IconData members, required IconData mute, required IconData notificationsFilled, required IconData notificationsOffFilled, @@ -192,17 +195,17 @@ class SBUIcons { required IconData refresh, required IconData replyFilled, required IconData reply, - required IconData send, required IconData search, + required IconData send, required IconData settingFilled, required IconData spinner, required IconData streaming, required IconData supergroup, + required IconData theme, required IconData thumbnailNone, - required IconData user, + required IconData time, required IconData unarchive, - required IconData markAsUnread, - required IconData theme, + required IconData user, }) { SBUIcons.add = add; SBUIcons.archive = archive; @@ -236,10 +239,11 @@ class SBUIcons { SBUIcons.gif = gif; SBUIcons.info = info; SBUIcons.leave = leave; + SBUIcons.markAsUnread = markAsUnread; + SBUIcons.members = members; + SBUIcons.message = message; SBUIcons.moderations = moderations; SBUIcons.more = more; - SBUIcons.message = message; - SBUIcons.members = members; SBUIcons.mute = mute; SBUIcons.notificationsFilled = notificationsFilled; SBUIcons.notificationsOffFilled = notificationsOffFilled; @@ -253,16 +257,16 @@ class SBUIcons { SBUIcons.refresh = refresh; SBUIcons.replyFilled = replyFilled; SBUIcons.reply = reply; - SBUIcons.send = send; SBUIcons.search = search; + SBUIcons.send = send; SBUIcons.settingFilled = settingFilled; SBUIcons.spinner = spinner; SBUIcons.streaming = streaming; SBUIcons.supergroup = supergroup; + SBUIcons.theme = theme; SBUIcons.thumbnailNone = thumbnailNone; - SBUIcons.user = user; + SBUIcons.time = time; SBUIcons.unarchive = unarchive; - SBUIcons.markAsUnread = markAsUnread; - SBUIcons.theme = theme; + SBUIcons.user = user; } } diff --git a/lib/src/public/resource/sbu_string_provider.dart b/lib/src/public/resource/sbu_string_provider.dart index a99b406..0b6faed 100644 --- a/lib/src/public/resource/sbu_string_provider.dart +++ b/lib/src/public/resource/sbu_string_provider.dart @@ -117,6 +117,12 @@ class SBUStrings { String inviteMembers; String invite; + // Waiting for connection + String youWillBeReconnectedShortly; + String estimatedWaitingTime; + String refresh; + String close; + SBUStrings({ // GroupChannel list required this.channels, @@ -210,6 +216,12 @@ class SBUStrings { // GroupChannel invite required this.inviteMembers, required this.invite, + + // Waiting for connection + required this.youWillBeReconnectedShortly, + required this.estimatedWaitingTime, + required this.refresh, + required this.close, }); static SBUStrings defaultStrings = SBUStrings( @@ -311,5 +323,12 @@ class SBUStrings { // GroupChannel invite inviteMembers: 'Invite members', invite: 'Invite', + + // Waiting for connection + youWillBeReconnectedShortly: + 'Something went wrong.\nYou\'ll be reconnected shortly.', + estimatedWaitingTime: 'Estimated waiting time:', + refresh: 'Refresh', + close: 'Close', ); } diff --git a/lib/src/public/screen/group_channel/channel_list/sbu_group_channel_create_screen.dart b/lib/src/public/screen/group_channel/channel_list/sbu_group_channel_create_screen.dart index 18ad069..1cbffe8 100644 --- a/lib/src/public/screen/group_channel/channel_list/sbu_group_channel_create_screen.dart +++ b/lib/src/public/screen/group_channel/channel_list/sbu_group_channel_create_screen.dart @@ -118,7 +118,10 @@ class SBUGroupChannelCreateScreenState ..name = '' ..isDistinct = false, ).then((channel) { - Navigator.pop(context); + if (context.mounted) { + Navigator.pop(context); + } + if (widget.onChannelCreated != null) { widget.onChannelCreated!(channel); } diff --git a/lib/src/public/sendbird_uikit.dart b/lib/src/public/sendbird_uikit.dart index 4371ba1..6be1352 100644 --- a/lib/src/public/sendbird_uikit.dart +++ b/lib/src/public/sendbird_uikit.dart @@ -2,11 +2,12 @@ import 'dart:async'; -import 'package:flutter/widgets.dart'; +import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:provider/provider.dart'; import 'package:sendbird_chat_sdk/sendbird_chat_sdk.dart'; import 'package:sendbird_uikit/sendbird_uikit.dart'; +import 'package:sendbird_uikit/src/internal/component/dialog/sbu_delayed_connecting_dialog.dart'; import 'package:sendbird_uikit/src/internal/provider/sbu_group_channel_collection_provider.dart'; import 'package:sendbird_uikit/src/internal/provider/sbu_message_collection_provider.dart'; import 'package:sendbird_uikit/src/internal/resource/sbu_text_styles.dart'; @@ -20,7 +21,7 @@ import 'package:sendbird_uikit/src/internal/utils/sbu_reply_manager.dart'; /// SendbirdUIKit class SendbirdUIKit { /// UIKit version - static const version = '1.1.0'; + static const version = '1.2.0'; SendbirdUIKit._(); @@ -30,6 +31,11 @@ class SendbirdUIKit { bool _isInitialized = false; + // DelayedConnectingDialog + GlobalKey? _navigatorKey; + BuildContext? _currentDialogContext; + bool? _addCloseButtonInDelayedConnectingDialog; + Future Function()? _takePhoto; Future Function()? get takePhoto => _takePhoto; @@ -97,6 +103,9 @@ class SendbirdUIKit { required String appId, SendbirdChatOptions? options, SBUTheme? theme, + GlobalKey? + navigatorKey, // To show the delayed connecting dialog + bool addCloseButtonInDelayedConnectingDialog = false, Future Function()? takePhoto, Future Function()? takeVideo, Future Function()? choosePhoto, @@ -119,11 +128,18 @@ class SendbirdUIKit { options: options, ); + SendbirdChat.addConnectionHandler( + 'sendbird-uikit-flutter', _MyConnectionHandler()); + await SBUPreferences().initialize(); if (theme != null) { SBUThemeProvider().setTheme(theme); } + _uikit._navigatorKey = navigatorKey; + _uikit._addCloseButtonInDelayedConnectingDialog = + addCloseButtonInDelayedConnectingDialog; + _uikit._takePhoto = takePhoto; _uikit._takeVideo = takeVideo; _uikit._choosePhoto = choosePhoto; @@ -204,4 +220,64 @@ class SendbirdUIKit { static void setFontFamily(String fontFamily) { SBUTextStyles.fontFamily = fontFamily; } + + // Shows the delayed connecting dialog with retryAfter time. + static void _showDelayedConnectingDialog(int retryAfter) { + final context = _uikit._navigatorKey?.currentContext; + if (context != null) { + if (_uikit._currentDialogContext != null) { + Navigator.of(_uikit._currentDialogContext!, rootNavigator: true).pop(); + _uikit._currentDialogContext = null; + } + + showDialog( + context: context, + barrierDismissible: false, + builder: (dialogContext) { + _uikit._currentDialogContext = dialogContext; + return SBUDelayedConnectingDialog( + retryAfter: retryAfter, + showCloseButton: + _uikit._addCloseButtonInDelayedConnectingDialog ?? false, + ); + }, + ).then((_) { + _uikit._currentDialogContext = null; + }); + } + } + + // Dismisses the delayed connecting dialog if it is currently shown. + static void _dismissDelayedConnectingDialog() { + if (_uikit._currentDialogContext != null) { + Navigator.of(_uikit._currentDialogContext!, rootNavigator: true).pop(); + _uikit._currentDialogContext = null; + } + } +} + +class _MyConnectionHandler extends ConnectionHandler { + @override + void onConnected(String userId) {} + + @override + void onDisconnected(String userId) {} + + @override + void onReconnectFailed() {} + + @override + void onReconnectStarted() {} + + @override + void onReconnectSucceeded() { + SendbirdUIKit._dismissDelayedConnectingDialog(); + } + + @override + void onConnectionDelayed(int retryAfter) { + if (retryAfter > 0) { + SendbirdUIKit._showDelayedConnectingDialog(retryAfter); + } + } } diff --git a/pubspec.yaml b/pubspec.yaml index 70267c7..700eb82 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: sendbird_uikit description: With Sendbird UIKit for Flutter, you can easily build an in-app chat with all the essential messaging features. -version: 1.1.0 +version: 1.2.0 homepage: https://sendbird.com repository: https://github.com/sendbird/sendbird-uikit-flutter documentation: https://sendbird.com/docs/chat/uikit/v3/flutter/overview @@ -17,7 +17,7 @@ dependencies: flutter: sdk: flutter - sendbird_chat_sdk: ^4.5.1 + sendbird_chat_sdk: ^4.7.0 provider: ^6.1.2 intl: '>=0.18.1 <1.0.0' collection: ^1.18.0