diff --git a/packages/stream_chat_v1/ios/Runner/Info.plist b/packages/stream_chat_v1/ios/Runner/Info.plist
index d9f250b..a1b8301 100644
--- a/packages/stream_chat_v1/ios/Runner/Info.plist
+++ b/packages/stream_chat_v1/ios/Runner/Info.plist
@@ -62,5 +62,10 @@
UIStatusBarHidden
+ CFBundleLocalizations
+
+ en
+ it
+
\ No newline at end of file
diff --git a/packages/stream_chat_v1/lib/advanced_options_page.dart b/packages/stream_chat_v1/lib/advanced_options_page.dart
index 3fd9a95..f6f6f9f 100644
--- a/packages/stream_chat_v1/lib/advanced_options_page.dart
+++ b/packages/stream_chat_v1/lib/advanced_options_page.dart
@@ -1,4 +1,5 @@
import 'package:example/home_page.dart';
+import 'package:example/localizations.dart';
import 'package:example/routes/routes.dart';
import 'package:example/stream_version.dart';
import 'package:flutter/material.dart';
@@ -40,7 +41,7 @@ class _AdvancedOptionsPageState extends State {
centerTitle: true,
brightness: Theme.of(context).brightness,
title: Text(
- 'Advanced Options',
+ AppLocalizations.of(context).advancedOptions,
style: StreamChatTheme.of(context).textTheme.headlineBold.copyWith(
color: StreamChatTheme.of(context).colorTheme.textHighEmphasis),
),
@@ -74,8 +75,9 @@ class _AdvancedOptionsPageState extends State {
validator: (value) {
if (value!.isEmpty) {
setState(() {
- _apiKeyError =
- 'Please enter the Chat API Key'.toUpperCase();
+ _apiKeyError = AppLocalizations.of(context)
+ .apiKeyError
+ .toUpperCase();
});
return _apiKeyError;
}
@@ -105,8 +107,8 @@ class _AdvancedOptionsPageState extends State {
fillColor: StreamChatTheme.of(context).colorTheme.inputBg,
filled: true,
labelText: _apiKeyError != null
- ? 'CHAT API KEY: $_apiKeyError'
- : 'Chat API Key',
+ ? '${AppLocalizations.of(context).chatApiKey.toUpperCase()}: $_apiKeyError'
+ : AppLocalizations.of(context).chatApiKey,
),
textInputAction: TextInputAction.next,
),
@@ -123,8 +125,9 @@ class _AdvancedOptionsPageState extends State {
validator: (value) {
if (value!.isEmpty) {
setState(() {
- _userIdError =
- 'Please enter the User ID'.toUpperCase();
+ _userIdError = AppLocalizations.of(context)
+ .userIdError
+ .toUpperCase();
});
return _userIdError;
}
@@ -155,8 +158,8 @@ class _AdvancedOptionsPageState extends State {
fillColor: StreamChatTheme.of(context).colorTheme.inputBg,
filled: true,
labelText: _userIdError != null
- ? 'USER ID: $_userIdError'
- : 'User ID',
+ ? '${AppLocalizations.of(context).userId.toUpperCase()}: $_userIdError'
+ : AppLocalizations.of(context).userId,
),
),
SizedBox(height: 8),
@@ -172,8 +175,9 @@ class _AdvancedOptionsPageState extends State {
validator: (value) {
if (value!.isEmpty) {
setState(() {
- _userTokenError =
- 'Please enter the user token'.toUpperCase();
+ _userTokenError = AppLocalizations.of(context)
+ .userTokenError
+ .toUpperCase();
});
return _userTokenError;
}
@@ -204,8 +208,8 @@ class _AdvancedOptionsPageState extends State {
fillColor: StreamChatTheme.of(context).colorTheme.inputBg,
filled: true,
labelText: _userTokenError != null
- ? 'USER TOKEN: $_userTokenError'
- : 'User Token',
+ ? '${AppLocalizations.of(context).userToken.toUpperCase()}: $_userTokenError'
+ : AppLocalizations.of(context).userToken,
),
),
SizedBox(height: 8),
@@ -226,7 +230,7 @@ class _AdvancedOptionsPageState extends State {
),
fillColor: StreamChatTheme.of(context).colorTheme.inputBg,
filled: true,
- labelText: 'Username (optional)',
+ labelText: AppLocalizations.of(context).usernameOptional,
),
),
Spacer(),
@@ -248,7 +252,7 @@ class _AdvancedOptionsPageState extends State {
),
),
child: Text(
- 'Login',
+ AppLocalizations.of(context).login,
style: TextStyle(
fontSize: 16,
color: Theme.of(context).brightness != Brightness.light
@@ -318,7 +322,8 @@ class _AdvancedOptionsPageState extends State {
value: userToken,
);
} catch (e) {
- var errorText = 'Error connecting, retry';
+ var errorText =
+ AppLocalizations.of(context).errorConnecting;
if (e is Map) {
errorText = e['message'] ?? errorText;
}
diff --git a/packages/stream_chat_v1/lib/channel_file_display_screen.dart b/packages/stream_chat_v1/lib/channel_file_display_screen.dart
index 2cffbc8..33394cf 100644
--- a/packages/stream_chat_v1/lib/channel_file_display_screen.dart
+++ b/packages/stream_chat_v1/lib/channel_file_display_screen.dart
@@ -1,3 +1,4 @@
+import 'package:example/localizations.dart';
import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
@@ -56,7 +57,7 @@ class _ChannelFileDisplayScreenState extends State {
elevation: 1,
centerTitle: true,
title: Text(
- 'Files',
+ AppLocalizations.of(context).files,
style: TextStyle(
color: StreamChatTheme.of(context).colorTheme.textHighEmphasis,
fontSize: 16.0),
@@ -107,7 +108,7 @@ class _ChannelFileDisplayScreenState extends State {
),
SizedBox(height: 16.0),
Text(
- 'No Files',
+ AppLocalizations.of(context).noFiles,
style: TextStyle(
fontSize: 14.0,
color:
@@ -116,7 +117,7 @@ class _ChannelFileDisplayScreenState extends State {
),
SizedBox(height: 8.0),
Text(
- 'Files sent in this chat will appear here',
+ AppLocalizations.of(context).filesAppearHere,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14.0,
diff --git a/packages/stream_chat_v1/lib/channel_list.dart b/packages/stream_chat_v1/lib/channel_list.dart
index e054518..5bac6cf 100644
--- a/packages/stream_chat_v1/lib/channel_list.dart
+++ b/packages/stream_chat_v1/lib/channel_list.dart
@@ -1,5 +1,6 @@
import 'dart:async';
+import 'package:example/localizations.dart';
import 'package:example/routes/routes.dart';
import 'package:example/search_text_field.dart';
import 'package:flutter/material.dart';
@@ -67,6 +68,7 @@ class _ChannelList extends State {
child: SearchTextField(
controller: _controller,
showCloseButton: _isSearchActive,
+ hintText: AppLocalizations.of(context).search,
),
),
],
@@ -109,7 +111,7 @@ class _ChannelList extends State {
),
),
Text(
- 'No results...',
+ AppLocalizations.of(context).noResults,
),
],
),
diff --git a/packages/stream_chat_v1/lib/channel_list_page.dart b/packages/stream_chat_v1/lib/channel_list_page.dart
index 76df0fb..f29f96a 100644
--- a/packages/stream_chat_v1/lib/channel_list_page.dart
+++ b/packages/stream_chat_v1/lib/channel_list_page.dart
@@ -1,5 +1,6 @@
import 'dart:async';
+import 'package:example/localizations.dart';
import 'package:example/routes/routes.dart';
import 'package:example/user_mentions_page.dart';
import 'package:flutter/foundation.dart';
@@ -43,7 +44,7 @@ class _ChannelListPageState extends State {
),
],
),
- label: 'Chats',
+ label: AppLocalizations.of(context).chats,
),
BottomNavigationBarItem(
icon: Stack(
@@ -56,7 +57,7 @@ class _ChannelListPageState extends State {
),
],
),
- label: 'Mentions',
+ label: AppLocalizations.of(context).mentions,
),
];
}
@@ -192,7 +193,7 @@ class LeftDrawer extends StatelessWidget {
);
},
title: Text(
- 'New direct message',
+ AppLocalizations.of(context).newDirectMessage,
style: TextStyle(
fontSize: 14.5,
),
@@ -212,7 +213,7 @@ class LeftDrawer extends StatelessWidget {
);
},
title: Text(
- 'New group',
+ AppLocalizations.of(context).newGroup,
style: TextStyle(
fontSize: 14.5,
),
@@ -249,7 +250,7 @@ class LeftDrawer extends StatelessWidget {
.withOpacity(.5),
),
title: Text(
- 'Sign out',
+ AppLocalizations.of(context).signOut,
style: TextStyle(
fontSize: 14.5,
),
diff --git a/packages/stream_chat_v1/lib/channel_media_display_screen.dart b/packages/stream_chat_v1/lib/channel_media_display_screen.dart
index b65df62..9435718 100644
--- a/packages/stream_chat_v1/lib/channel_media_display_screen.dart
+++ b/packages/stream_chat_v1/lib/channel_media_display_screen.dart
@@ -1,3 +1,4 @@
+import 'package:example/localizations.dart';
import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'package:video_player/video_player.dart';
@@ -65,7 +66,7 @@ class _ChannelMediaDisplayScreenState extends State {
elevation: 1,
centerTitle: true,
title: Text(
- 'Photos & Videos',
+ AppLocalizations.of(context).photosAndVideos,
style: TextStyle(
color: StreamChatTheme.of(context).colorTheme.textHighEmphasis,
fontSize: 16.0,
@@ -103,7 +104,7 @@ class _ChannelMediaDisplayScreenState extends State {
),
SizedBox(height: 16.0),
Text(
- 'No Media',
+ AppLocalizations.of(context).noMedia,
style: TextStyle(
fontSize: 14.0,
color:
@@ -112,7 +113,7 @@ class _ChannelMediaDisplayScreenState extends State {
),
SizedBox(height: 8.0),
Text(
- 'Photos or video sent in this chat will \nappear here',
+ AppLocalizations.of(context).photosOrVideosWillAppearHere,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14.0,
diff --git a/packages/stream_chat_v1/lib/chat_info_screen.dart b/packages/stream_chat_v1/lib/chat_info_screen.dart
index 1ac7156..9190479 100644
--- a/packages/stream_chat_v1/lib/chat_info_screen.dart
+++ b/packages/stream_chat_v1/lib/chat_info_screen.dart
@@ -1,4 +1,5 @@
import 'package:collection/collection.dart' show IterableExtension;
+import 'package:example/localizations.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:jiffy/jiffy.dart';
@@ -149,7 +150,7 @@ class _ChatInfoScreenState extends State {
return OptionListTile(
tileColor: StreamChatTheme.of(context).colorTheme.appBg,
- title: 'Mute user',
+ title: AppLocalizations.of(context).muteUser,
titleTextStyle: StreamChatTheme.of(context).textTheme.body,
leading: Padding(
padding: const EdgeInsets.symmetric(horizontal: 22.0),
@@ -201,7 +202,7 @@ class _ChatInfoScreenState extends State {
// onTap: () {},
// ),
OptionListTile(
- title: 'Pinned Messages',
+ title: AppLocalizations.of(context).pinnedMessages,
tileColor: StreamChatTheme.of(context).colorTheme.appBg,
titleTextStyle: StreamChatTheme.of(context).textTheme.body,
leading: Padding(
@@ -262,7 +263,7 @@ class _ChatInfoScreenState extends State {
},
),
OptionListTile(
- title: 'Photos & Videos',
+ title: AppLocalizations.of(context).photosAndVideos,
tileColor: StreamChatTheme.of(context).colorTheme.appBg,
titleTextStyle: StreamChatTheme.of(context).textTheme.body,
leading: Padding(
@@ -323,7 +324,7 @@ class _ChatInfoScreenState extends State {
},
),
OptionListTile(
- title: 'Files',
+ title: AppLocalizations.of(context).files,
tileColor: StreamChatTheme.of(context).colorTheme.appBg,
titleTextStyle: StreamChatTheme.of(context).textTheme.body,
leading: Padding(
@@ -364,7 +365,7 @@ class _ChatInfoScreenState extends State {
},
),
OptionListTile(
- title: 'Shared groups',
+ title: AppLocalizations.of(context).sharedGroups,
tileColor: StreamChatTheme.of(context).colorTheme.appBg,
titleTextStyle: StreamChatTheme.of(context).textTheme.body,
leading: Padding(
@@ -416,10 +417,10 @@ class _ChatInfoScreenState extends State {
void _showDeleteDialog() async {
final res = await showConfirmationDialog(
context,
- title: 'Delete Conversation',
- okText: 'DELETE',
- question: 'Are you sure you want to delete this conversation?',
- cancelText: 'CANCEL',
+ title: AppLocalizations.of(context).deleteConversationTitle,
+ okText: AppLocalizations.of(context).delete.toUpperCase(),
+ question: AppLocalizations.of(context).deleteConversationAreYouSure,
+ cancelText: AppLocalizations.of(context).cancel.toUpperCase(),
icon: StreamSvgIcon.delete(
color: StreamChatTheme.of(context).colorTheme.accentError,
),
@@ -441,7 +442,7 @@ class _ChatInfoScreenState extends State {
if (otherMember != null) {
if (otherMember.online) {
alternativeWidget = Text(
- 'Online',
+ AppLocalizations.of(context).online,
style: TextStyle(
color: StreamChatTheme.of(context)
.colorTheme
@@ -450,7 +451,7 @@ class _ChatInfoScreenState extends State {
);
} else {
alternativeWidget = Text(
- 'Last seen ${Jiffy(otherMember.lastActive).fromNow()}',
+ '${AppLocalizations.of(context).lastSeen} ${Jiffy(otherMember.lastActive).fromNow()}',
style: TextStyle(
color: StreamChatTheme.of(context)
.colorTheme
@@ -511,7 +512,7 @@ class __SharedGroupsScreenState extends State<_SharedGroupsScreen> {
elevation: 1,
centerTitle: true,
title: Text(
- 'Shared Groups',
+ AppLocalizations.of(context).sharedGroups,
style: TextStyle(
color: StreamChatTheme.of(context).colorTheme.textHighEmphasis,
fontSize: 16.0),
@@ -544,7 +545,7 @@ class __SharedGroupsScreenState extends State<_SharedGroupsScreen> {
),
SizedBox(height: 16.0),
Text(
- 'No Shared Groups',
+ AppLocalizations.of(context).noSharedGroups,
style: TextStyle(
fontSize: 14.0,
color: StreamChatTheme.of(context)
@@ -554,7 +555,7 @@ class __SharedGroupsScreenState extends State<_SharedGroupsScreen> {
),
SizedBox(height: 8.0),
Text(
- 'Group shared with User will appear here.',
+ AppLocalizations.of(context).groupSharedWithUserAppearHere,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14.0,
@@ -602,8 +603,8 @@ class __SharedGroupsScreenState extends State<_SharedGroupsScreen> {
child: LayoutBuilder(builder: (context, constraints) {
String? title;
if (extraData['name'] == null) {
- final otherMembers = members.where(
- (member) => member.userId != StreamChat.of(context).currentUser!.id);
+ final otherMembers = members.where((member) =>
+ member.userId != StreamChat.of(context).currentUser!.id);
if (otherMembers.isNotEmpty) {
final maxWidth = constraints.maxWidth;
final maxChars = maxWidth / textStyle.fontSize!;
@@ -649,7 +650,7 @@ class __SharedGroupsScreenState extends State<_SharedGroupsScreen> {
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
- '${channel.memberCount} members',
+ '${channel.memberCount} ${AppLocalizations.of(context).members.toLowerCase()}',
style: TextStyle(
color: StreamChatTheme.of(context)
.colorTheme
diff --git a/packages/stream_chat_v1/lib/chips_input_text_field.dart b/packages/stream_chat_v1/lib/chips_input_text_field.dart
index a67895e..73149c4 100644
--- a/packages/stream_chat_v1/lib/chips_input_text_field.dart
+++ b/packages/stream_chat_v1/lib/chips_input_text_field.dart
@@ -1,3 +1,4 @@
+import 'package:example/localizations.dart';
import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
@@ -75,7 +76,7 @@ class ChipInputTextFieldState extends State> {
Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Text(
- 'TO:',
+ '${AppLocalizations.of(context).to.toUpperCase()}:',
style: StreamChatTheme.of(context)
.textTheme
.footnote
diff --git a/packages/stream_chat_v1/lib/choose_user_page.dart b/packages/stream_chat_v1/lib/choose_user_page.dart
index 7a4f263..7d3ce51 100644
--- a/packages/stream_chat_v1/lib/choose_user_page.dart
+++ b/packages/stream_chat_v1/lib/choose_user_page.dart
@@ -1,5 +1,6 @@
import 'package:example/app_config.dart';
import 'package:example/home_page.dart';
+import 'package:example/localizations.dart';
import 'package:example/stream_version.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
@@ -41,12 +42,12 @@ class ChooseUserPage extends StatelessWidget {
Padding(
padding: const EdgeInsets.only(bottom: 13.0),
child: Text(
- 'Welcome to Stream Chat',
+ AppLocalizations.of(context).welcomeToStreamChat,
style: StreamChatTheme.of(context).textTheme.title,
),
),
Text(
- 'Select a user to try the Flutter SDK:',
+ '${AppLocalizations.of(context).selectUserToTryFlutterSDK}:',
style: StreamChatTheme.of(context).textTheme.body,
),
Expanded(
@@ -135,7 +136,7 @@ class ChooseUserPage extends StatelessWidget {
StreamChatTheme.of(context).textTheme.bodyBold,
),
subtitle: Text(
- 'Stream test account',
+ AppLocalizations.of(context).streamTestAccount,
style: StreamChatTheme.of(context)
.textTheme
.footnote
@@ -166,11 +167,11 @@ class ChooseUserPage extends StatelessWidget {
StreamChatTheme.of(context).colorTheme.borders,
),
title: Text(
- 'Advanced Options',
+ AppLocalizations.of(context).advancedOptions,
style: StreamChatTheme.of(context).textTheme.bodyBold,
),
subtitle: Text(
- 'Custom settings',
+ AppLocalizations.of(context).customSettings,
style: StreamChatTheme.of(context)
.textTheme
.footnote
diff --git a/packages/stream_chat_v1/lib/group_chat_details_screen.dart b/packages/stream_chat_v1/lib/group_chat_details_screen.dart
index b61bf66..6b89937 100644
--- a/packages/stream_chat_v1/lib/group_chat_details_screen.dart
+++ b/packages/stream_chat_v1/lib/group_chat_details_screen.dart
@@ -1,3 +1,4 @@
+import 'package:example/localizations.dart';
import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'package:uuid/uuid.dart';
@@ -66,7 +67,7 @@ class _GroupChatDetailsScreenState extends State {
backgroundColor: StreamChatTheme.of(context).colorTheme.barsBg,
leading: const StreamBackButton(),
title: Text(
- 'Name of Group Chat',
+ AppLocalizations.of(context).nameOfGroupChat,
style: TextStyle(
color: StreamChatTheme.of(context).colorTheme.textHighEmphasis,
fontSize: 16,
@@ -80,7 +81,7 @@ class _GroupChatDetailsScreenState extends State {
child: Row(
children: [
Text(
- 'NAME',
+ AppLocalizations.of(context).name.toUpperCase(),
style: TextStyle(
fontSize: 12,
color: StreamChatTheme.of(context)
@@ -100,7 +101,8 @@ class _GroupChatDetailsScreenState extends State {
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding: const EdgeInsets.all(0),
- hintText: 'Choose a group chat name',
+ hintText:
+ AppLocalizations.of(context).chooseAGroupChatName,
hintStyle: TextStyle(
fontSize: 14,
color: StreamChatTheme.of(context)
@@ -161,14 +163,14 @@ class _GroupChatDetailsScreenState extends State {
switch (status) {
case ConnectionStatus.connected:
- statusString = 'Connected';
+ statusString = AppLocalizations.of(context).connected;
showStatus = false;
break;
case ConnectionStatus.connecting:
- statusString = 'Reconnecting...';
+ statusString = AppLocalizations.of(context).reconnecting;
break;
case ConnectionStatus.disconnected:
- statusString = 'Disconnected';
+ statusString = AppLocalizations.of(context).disconnected;
break;
}
return InfoTile(
@@ -190,7 +192,7 @@ class _GroupChatDetailsScreenState extends State {
horizontal: 8,
),
child: Text(
- '$_totalUsers ${_totalUsers > 1 ? 'Members' : 'Member'}',
+ '$_totalUsers ${_totalUsers > 1 ? AppLocalizations.of(context).members : AppLocalizations.of(context).member}',
style: TextStyle(
color: StreamChatTheme.of(context)
.colorTheme
@@ -293,13 +295,13 @@ class _GroupChatDetailsScreenState extends State {
height: 26.0,
),
Text(
- 'Something went wrong',
+ AppLocalizations.of(context).somethingWentWrongErrorMessage,
style: StreamChatTheme.of(context).textTheme.headlineBold,
),
SizedBox(
height: 7.0,
),
- Text('The operation couldn\'t be completed.'),
+ Text(AppLocalizations.of(context).operationCouldNotBeCompleted),
SizedBox(
height: 36.0,
),
@@ -315,7 +317,7 @@ class _GroupChatDetailsScreenState extends State {
children: [
TextButton(
child: Text(
- 'OK',
+ AppLocalizations.of(context).ok,
style: StreamChatTheme.of(context)
.textTheme
.bodyBold
diff --git a/packages/stream_chat_v1/lib/group_info_screen.dart b/packages/stream_chat_v1/lib/group_info_screen.dart
index 8564afe..9b1c881 100644
--- a/packages/stream_chat_v1/lib/group_info_screen.dart
+++ b/packages/stream_chat_v1/lib/group_info_screen.dart
@@ -1,11 +1,10 @@
import 'dart:async';
import 'package:collection/collection.dart' show IterableExtension;
+import 'package:example/localizations.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:jiffy/jiffy.dart';
-import 'package:stream_chat_flutter/src/option_list_tile.dart';
-import 'package:stream_chat_flutter/src/stream_svg_icon.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'channel_file_display_screen.dart';
@@ -106,7 +105,7 @@ class _GroupInfoScreenState extends State {
builder: (context, state) {
if (!state.hasData) {
return Text(
- 'Loading...',
+ AppLocalizations.of(context).loading,
style: TextStyle(
color: StreamChatTheme.of(context)
.colorTheme
@@ -139,7 +138,7 @@ class _GroupInfoScreenState extends State {
height: 3.0,
),
Text(
- '${channel.channel.memberCount} Members, ${snapshot.data?.where((e) => e.user!.online).length ?? 0} Online',
+ '${channel.channel.memberCount} ${AppLocalizations.of(context).members}, ${snapshot.data?.where((e) => e.user!.online).length ?? 0} ${AppLocalizations.of(context).online}',
style: TextStyle(
color: StreamChatTheme.of(context)
.colorTheme
@@ -260,7 +259,9 @@ class _GroupInfoScreenState extends State {
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
- member.role == 'owner' ? 'Owner' : '',
+ member.role == 'owner'
+ ? AppLocalizations.of(context).owner
+ : '',
style: TextStyle(
color: StreamChatTheme.of(context)
.colorTheme
@@ -313,7 +314,7 @@ class _GroupInfoScreenState extends State {
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
- '${members.length - groupMembersLength} more',
+ '${members.length - groupMembersLength} ${AppLocalizations.of(context).more}',
style: TextStyle(
color: StreamChatTheme.of(context)
.colorTheme
@@ -352,7 +353,7 @@ class _GroupInfoScreenState extends State {
Padding(
padding: const EdgeInsets.all(7.0),
child: Text(
- 'NAME',
+ AppLocalizations.of(context).name.toUpperCase(),
style: StreamChatTheme.of(context).textTheme.footnote.copyWith(
color: StreamChatTheme.of(context)
.colorTheme
@@ -370,7 +371,7 @@ class _GroupInfoScreenState extends State {
cursorColor:
StreamChatTheme.of(context).colorTheme.textHighEmphasis,
decoration: InputDecoration.collapsed(
- hintText: 'Add a group name',
+ hintText: AppLocalizations.of(context).addAGroupName,
hintStyle: StreamChatTheme.of(context)
.textTheme
.bodyBold
@@ -457,7 +458,7 @@ class _GroupInfoScreenState extends State {
return OptionListTile(
tileColor: StreamChatTheme.of(context).colorTheme.appBg,
separatorColor: StreamChatTheme.of(context).colorTheme.disabled,
- title: 'Mute group',
+ title: AppLocalizations.of(context).muteGroup,
titleTextStyle: StreamChatTheme.of(context).textTheme.body,
leading: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
@@ -491,7 +492,7 @@ class _GroupInfoScreenState extends State {
);
}),
OptionListTile(
- title: 'Pinned Messages',
+ title: AppLocalizations.of(context).pinnedMessages,
tileColor: StreamChatTheme.of(context).colorTheme.appBg,
titleTextStyle: StreamChatTheme.of(context).textTheme.body,
leading: Padding(
@@ -554,7 +555,7 @@ class _GroupInfoScreenState extends State {
OptionListTile(
tileColor: StreamChatTheme.of(context).colorTheme.appBg,
separatorColor: StreamChatTheme.of(context).colorTheme.disabled,
- title: 'Photos & Videos',
+ title: AppLocalizations.of(context).photosAndVideos,
titleTextStyle: StreamChatTheme.of(context).textTheme.body,
leading: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
@@ -616,7 +617,7 @@ class _GroupInfoScreenState extends State {
OptionListTile(
tileColor: StreamChatTheme.of(context).colorTheme.appBg,
separatorColor: StreamChatTheme.of(context).colorTheme.disabled,
- title: 'Files',
+ title: AppLocalizations.of(context).files,
titleTextStyle: StreamChatTheme.of(context).textTheme.body,
leading: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
@@ -659,7 +660,7 @@ class _GroupInfoScreenState extends State {
OptionListTile(
tileColor: StreamChatTheme.of(context).colorTheme.appBg,
separatorColor: StreamChatTheme.of(context).colorTheme.disabled,
- title: 'Leave Group',
+ title: AppLocalizations.of(context).leaveGroup,
titleTextStyle: StreamChatTheme.of(context).textTheme.body,
leading: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
@@ -678,10 +679,11 @@ class _GroupInfoScreenState extends State {
onTap: () async {
final res = await showConfirmationDialog(
context,
- title: 'Leave conversation',
- okText: 'LEAVE',
- question: 'Are you sure you want to leave this conversation?',
- cancelText: 'CANCEL',
+ title: AppLocalizations.of(context).leaveConversation,
+ okText: AppLocalizations.of(context).leave.toUpperCase(),
+ question:
+ AppLocalizations.of(context).leaveConversationAreYouSure,
+ cancelText: AppLocalizations.of(context).cancel.toUpperCase(),
icon: StreamSvgIcon.userRemove(
color: StreamChatTheme.of(context).colorTheme.accentError,
),
@@ -777,8 +779,8 @@ class _GroupInfoScreenState extends State {
.textLowEmphasis,
),
),
- Text(
- 'No user matches these keywords...'),
+ Text(AppLocalizations.of(context)
+ .noUserMatchesTheseKeywords),
],
),
),
@@ -815,7 +817,7 @@ class _GroupInfoScreenState extends State {
cursorColor: theme.colorTheme.textHighEmphasis,
autofocus: true,
decoration: InputDecoration(
- hintText: 'Search',
+ hintText: AppLocalizations.of(context).search,
hintStyle: theme.textTheme.body.copyWith(
color: theme.colorTheme.textLowEmphasis,
),
@@ -916,7 +918,7 @@ class _GroupInfoScreenState extends State {
.textLowEmphasis,
size: 24.0,
),
- 'View info',
+ AppLocalizations.of(context).viewInfo,
() async {
var client = StreamChat.of(context).client;
@@ -952,7 +954,7 @@ class _GroupInfoScreenState extends State {
.textLowEmphasis,
size: 24.0,
),
- 'Message',
+ AppLocalizations.of(context).message,
() async {
var client = StreamChat.of(context).client;
@@ -999,14 +1001,16 @@ class _GroupInfoScreenState extends State {
.accentError,
size: 24.0,
),
- 'Remove From Group', () async {
+ AppLocalizations.of(context).removeFromGroup, () async {
final res = await showConfirmationDialog(
context,
- title: 'Remove member',
- okText: 'REMOVE',
+ title: AppLocalizations.of(context).removeMember,
+ okText:
+ AppLocalizations.of(context).remove.toUpperCase(),
question:
- 'Are you sure you want to remove this member?',
- cancelText: 'CANCEL',
+ AppLocalizations.of(context).removeMemberAreYouSure,
+ cancelText:
+ AppLocalizations.of(context).cancel.toUpperCase(),
);
if (res == true) {
@@ -1024,7 +1028,7 @@ class _GroupInfoScreenState extends State {
.textLowEmphasis,
size: 24.0,
),
- 'Cancel', () {
+ AppLocalizations.of(context).cancel, () {
Navigator.pop(context);
}),
],
@@ -1050,7 +1054,7 @@ class _GroupInfoScreenState extends State {
if (otherMember != null) {
if (otherMember.online) {
alternativeWidget = Text(
- 'Online',
+ AppLocalizations.of(context).online,
style: TextStyle(
color: StreamChatTheme.of(context)
.colorTheme
@@ -1059,7 +1063,7 @@ class _GroupInfoScreenState extends State {
);
} else {
alternativeWidget = Text(
- 'Last seen ${Jiffy(otherMember.lastActive).fromNow()}',
+ '${AppLocalizations.of(context).lastSeen} ${Jiffy(otherMember.lastActive).fromNow()}',
style: TextStyle(
color: StreamChatTheme.of(context)
.colorTheme
@@ -1139,7 +1143,7 @@ class _GroupInfoScreenState extends State {
title =
'${currentMembers.map((e) => e.user!.name).join(', ')} ${exceedingMembers > 0 ? '+ $exceedingMembers' : ''}';
} else {
- title = 'No title';
+ title = AppLocalizations.of(context).noTitle;
}
} else {
title = extraData['name'];
@@ -1149,9 +1153,9 @@ class _GroupInfoScreenState extends State {
String _getLastSeen(User user) {
if (user.online) {
- return 'Online';
+ return AppLocalizations.of(context).online;
} else {
- return 'Last seen ${Jiffy(user.lastActive).fromNow()}';
+ return '${AppLocalizations.of(context).lastSeen} ${Jiffy(user.lastActive).fromNow()}';
}
}
}
diff --git a/packages/stream_chat_v1/lib/localizations.dart b/packages/stream_chat_v1/lib/localizations.dart
new file mode 100644
index 0000000..adff28d
--- /dev/null
+++ b/packages/stream_chat_v1/lib/localizations.dart
@@ -0,0 +1,558 @@
+import 'package:flutter/foundation.dart';
+import 'package:flutter/material.dart';
+
+class AppLocalizations {
+ static const _localizedValues = >{
+ 'en': {
+ 'add_a_group_name': 'Add a group name',
+ 'add_group_members': 'Add Group Members',
+ 'advanced_options': 'Advanced Options',
+ 'api_key_error': 'Please enter the Chat API Key',
+ 'attachment': 'attachment',
+ 'attachments': 'attachments',
+ 'cancel': 'Cancel',
+ 'chat_api_key': 'Chat API Key',
+ 'chats': 'Chats',
+ 'choose_a_group_chat_name': 'Choose a group chat name',
+ 'connected': 'Connected',
+ 'create_a_group': 'Create a Group',
+ 'custom_settings': 'Custom settings',
+ 'delete': 'Delete',
+ 'delete_conversation_are_you_sure':
+ 'Are you sure you want to delete this conversation?',
+ 'delete_conversation_title': 'Delete Conversation',
+ 'disconnected': 'Disconnected',
+ 'error_connecting': 'Error connecting, retry',
+ 'files': 'Files',
+ 'files_appear_here': 'Files sent in this chat will appear here',
+ 'group_shared_with_user_appear_here':
+ 'Group shared with User will appear here.',
+ 'last_seen': 'Last seen',
+ 'leave': 'Leave',
+ 'leave_conversation': 'Leave conversation',
+ 'leave_conversation_are_you_sure':
+ 'Are you sure you want to leave this conversation?',
+ 'leave_group': 'Leave Group',
+ 'loading': 'Loading...',
+ 'login': 'Login',
+ 'long_press_message': 'Long-press an important message and\nchoose',
+ 'matches_for': 'Matches for',
+ 'member': 'Member',
+ 'members': 'Members',
+ 'mentions': 'Mentions',
+ 'message': 'Message',
+ 'message_channel_description': 'Channel used for showing messages',
+ 'message_channel_name': 'Message channel',
+ 'more': 'more',
+ 'mute_group': 'Mute group',
+ 'mute_user': 'Mute user',
+ 'name': 'Name',
+ 'name_of_group_chat': 'Name of Group Chat',
+ 'new_chat': 'New Chat',
+ 'new_direct_message': 'New direct message',
+ 'new_group': 'New group',
+ 'no_chats_here_yet': 'No chats here yet...',
+ 'no_files': 'No Files',
+ 'no_media': 'No Media',
+ 'no_mentions_exist_yet': 'No mentions exist yet...',
+ 'no_pinned_items': 'No pinned items',
+ 'no_results': 'No results...',
+ 'no_shared_groups': 'No Shared Groups',
+ 'no_title': 'No title',
+ 'no_user_matches_these_keywords': 'No user matches these keywords...',
+ 'ok': 'OK',
+ 'online': 'Online',
+ 'on_the_platform': 'On the platform',
+ 'operation_could_not_be_completed':
+ 'The operation couldn\'t be completed.',
+ 'owner': 'Owner',
+ 'photos_and_videos': 'Photos & Videos',
+ 'photos_or_videos_will_appear_here':
+ 'Photos or videos sent in this chat will \nappear here',
+ 'pinned_messages': 'Pinned Messages',
+ 'pin_to_conversation': 'Pin to conversation',
+ 'reconnecting': 'Reconnecting...',
+ 'remove': 'Remove',
+ 'remove_from_group': 'Remove From Group',
+ 'remove_member': 'Remove member',
+ 'remove_member_are_you_sure':
+ 'Are you sure you want to remove this member?',
+ 'search': 'Search',
+ 'select_user_to_try_flutter_sdk': 'Select a user to try the Flutter SDK',
+ 'shared_groups': 'Shared Groups',
+ 'sign_out': 'Sign out',
+ 'something_went_wrong_error_message': 'Something went wrong',
+ 'stream_sdk': 'Stream SDK',
+ 'stream_test_account': 'Stream test account',
+ 'to': 'To',
+ 'type_a_name_hint': 'Type a name',
+ 'user_id': 'User ID',
+ 'user_id_error': 'Please enter the User ID',
+ 'username_optional': 'Username (optional)',
+ 'user_token': 'User Token',
+ 'user_token_error': 'Please enter the user token',
+ 'view_info': 'View info',
+ 'welcome_to_stream_chat': 'Welcome to Stream Chat',
+ },
+ // TODO convert EN to IT
+ 'it': {
+ 'add_a_group_name': 'Add a group name',
+ 'add_group_members': 'Add Group Members',
+ 'advanced_options': 'Advanced Options',
+ 'api_key_error': 'Please enter the Chat API Key',
+ 'attachment': 'attachment',
+ 'attachments': 'attachments',
+ 'cancel': 'Cancel',
+ 'chat_api_key': 'Chat API Key',
+ 'chats': 'Chats',
+ 'choose_a_group_chat_name': 'Choose a group chat name',
+ 'connected': 'Connected',
+ 'create_a_group': 'Create a Group',
+ 'custom_settings': 'Custom settings',
+ 'delete': 'Delete',
+ 'delete_conversation_are_you_sure':
+ 'Are you sure you want to delete this conversation?',
+ 'delete_conversation_title': 'Delete Conversation',
+ 'disconnected': 'Disconnected',
+ 'error_connecting': 'Error connecting, retry',
+ 'files': 'Files',
+ 'files_appear_here': 'Files sent in this chat will appear here',
+ 'group_shared_with_user_appear_here':
+ 'Group shared with User will appear here.',
+ 'last_seen': 'Last seen',
+ 'leave': 'Leave',
+ 'leave_conversation': 'Leave conversation',
+ 'leave_conversation_are_you_sure':
+ 'Are you sure you want to leave this conversation?',
+ 'leave_group': 'Leave Group',
+ 'loading': 'Loading...',
+ 'login': 'Login',
+ 'long_press_message': 'Long-press an important message and\nchoose',
+ 'matches_for': 'Matches for',
+ 'member': 'Member',
+ 'members': 'Members',
+ 'mentions': 'Mentions',
+ 'message': 'Message',
+ 'message_channel_description': 'Channel used for showing messages',
+ 'message_channel_name': 'Message channel',
+ 'more': 'more',
+ 'mute_group': 'Mute group',
+ 'mute_user': 'Mute user',
+ 'name': 'Name',
+ 'name_of_group_chat': 'Name of Group Chat',
+ 'new_chat': 'New Chat',
+ 'new_direct_message': 'New direct message',
+ 'new_group': 'New group',
+ 'no_chats_here_yet': 'No chats here yet...',
+ 'no_files': 'No Files',
+ 'no_media': 'No Media',
+ 'no_mentions_exist_yet': 'No mentions exist yet...',
+ 'no_pinned_items': 'No pinned items',
+ 'no_results': 'No results...',
+ 'no_shared_groups': 'No Shared Groups',
+ 'no_title': 'No title',
+ 'no_user_matches_these_keywords': 'No user matches these keywords...',
+ 'ok': 'OK',
+ 'online': 'Online',
+ 'on_the_platform': 'On the platform',
+ 'operation_could_not_be_completed':
+ 'The operation couldn\'t be completed.',
+ 'owner': 'Owner',
+ 'photos_and_videos': 'Photos & Videos',
+ 'photos_or_videos_will_appear_here':
+ 'Photos or videos sent in this chat will \nappear here',
+ 'pinned_messages': 'Pinned Messages',
+ 'pin_to_conversation': 'Pin to conversation',
+ 'reconnecting': 'Reconnecting...',
+ 'remove': 'Remove',
+ 'remove_from_group': 'Remove From Group',
+ 'remove_member': 'Remove member',
+ 'remove_member_are_you_sure':
+ 'Are you sure you want to remove this member?',
+ 'search': 'Search',
+ 'select_user_to_try_flutter_sdk': 'Select a user to try the Flutter SDK',
+ 'shared_groups': 'Shared Groups',
+ 'sign_out': 'Sign out',
+ 'something_went_wrong_error_message': 'Something went wrong',
+ 'stream_sdk': 'Stream SDK',
+ 'stream_test_account': 'Stream test account',
+ 'to': 'To',
+ 'type_a_name_hint': 'Type a name',
+ 'user_id': 'User ID',
+ 'user_id_error': 'Please enter the User ID',
+ 'username_optional': 'Username (optional)',
+ 'user_token': 'User Token',
+ 'user_token_error': 'Please enter the user token',
+ 'view_info': 'View info',
+ 'welcome_to_stream_chat': 'Welcome to Stream Chat',
+ },
+ };
+
+ final Locale locale;
+
+ AppLocalizations(this.locale);
+
+ String get addAGroupName {
+ return _localizedValues[locale.languageCode]!['add_a_group_name']!;
+ }
+
+ String get addGroupMembers {
+ return _localizedValues[locale.languageCode]!['add_group_members']!;
+ }
+
+ String get advancedOptions {
+ return _localizedValues[locale.languageCode]!['advanced_options']!;
+ }
+
+ String get apiKeyError {
+ return _localizedValues[locale.languageCode]!['api_key_error']!;
+ }
+
+ String get attachment {
+ return _localizedValues[locale.languageCode]!['attachment']!;
+ }
+
+ String get attachments {
+ return _localizedValues[locale.languageCode]!['attachments']!;
+ }
+
+ String get cancel {
+ return _localizedValues[locale.languageCode]!['cancel']!;
+ }
+
+ String get chatApiKey {
+ return _localizedValues[locale.languageCode]!['chat_api_key']!;
+ }
+
+ String get chats {
+ return _localizedValues[locale.languageCode]!['chats']!;
+ }
+
+ String get chooseAGroupChatName {
+ return _localizedValues[locale.languageCode]!['choose_a_group_chat_name']!;
+ }
+
+ String get connected {
+ return _localizedValues[locale.languageCode]!['connected']!;
+ }
+
+ String get createAGroup {
+ return _localizedValues[locale.languageCode]!['create_a_group']!;
+ }
+
+ String get customSettings {
+ return _localizedValues[locale.languageCode]!['custom_settings']!;
+ }
+
+ String get delete {
+ return _localizedValues[locale.languageCode]!['delete']!;
+ }
+
+ String get deleteConversationAreYouSure {
+ return _localizedValues[locale.languageCode]![
+ 'delete_conversation_are_you_sure']!;
+ }
+
+ String get deleteConversationTitle {
+ return _localizedValues[locale.languageCode]!['delete_conversation_title']!;
+ }
+
+ String get disconnected {
+ return _localizedValues[locale.languageCode]!['disconnected']!;
+ }
+
+ String get errorConnecting {
+ return _localizedValues[locale.languageCode]!['error_connecting']!;
+ }
+
+ String get files {
+ return _localizedValues[locale.languageCode]!['files']!;
+ }
+
+ String get filesAppearHere {
+ return _localizedValues[locale.languageCode]!['files_appear_here']!;
+ }
+
+ String get groupSharedWithUserAppearHere {
+ return _localizedValues[locale.languageCode]![
+ 'group_shared_with_user_appear_here']!;
+ }
+
+ String get lastSeen {
+ return _localizedValues[locale.languageCode]!['last_seen']!;
+ }
+
+ String get leave {
+ return _localizedValues[locale.languageCode]!['leave']!;
+ }
+
+ String get leaveConversation {
+ return _localizedValues[locale.languageCode]!['leave_conversation']!;
+ }
+
+ String get leaveConversationAreYouSure {
+ return _localizedValues[locale.languageCode]![
+ 'leave_conversation_are_you_sure']!;
+ }
+
+ String get leaveGroup {
+ return _localizedValues[locale.languageCode]!['leave_group']!;
+ }
+
+ String get loading {
+ return _localizedValues[locale.languageCode]!['loading']!;
+ }
+
+ String get login {
+ return _localizedValues[locale.languageCode]!['login']!;
+ }
+
+ String get longPressMessage {
+ return _localizedValues[locale.languageCode]!['long_press_message']!;
+ }
+
+ String get matchesFor {
+ return _localizedValues[locale.languageCode]!['matches_for']!;
+ }
+
+ String get member {
+ return _localizedValues[locale.languageCode]!['member']!;
+ }
+
+ String get members {
+ return _localizedValues[locale.languageCode]!['members']!;
+ }
+
+ String get mentions {
+ return _localizedValues[locale.languageCode]!['mentions']!;
+ }
+
+ String get message {
+ return _localizedValues[locale.languageCode]!['message']!;
+ }
+
+ String get messageChannelDescription {
+ return _localizedValues[locale.languageCode]![
+ 'message_channel_description']!;
+ }
+
+ String get messageChannelName {
+ return _localizedValues[locale.languageCode]!['message_channel_name']!;
+ }
+
+ String get more {
+ return _localizedValues[locale.languageCode]!['more']!;
+ }
+
+ String get muteGroup {
+ return _localizedValues[locale.languageCode]!['mute_group']!;
+ }
+
+ String get muteUser {
+ return _localizedValues[locale.languageCode]!['mute_user']!;
+ }
+
+ String get name {
+ return _localizedValues[locale.languageCode]!['name']!;
+ }
+
+ String get nameOfGroupChat {
+ return _localizedValues[locale.languageCode]!['name_of_group_chat']!;
+ }
+
+ String get newChat {
+ return _localizedValues[locale.languageCode]!['new_chat']!;
+ }
+
+ String get newDirectMessage {
+ return _localizedValues[locale.languageCode]!['new_direct_message']!;
+ }
+
+ String get newGroup {
+ return _localizedValues[locale.languageCode]!['new_group']!;
+ }
+
+ String get noChatsHereYet {
+ return _localizedValues[locale.languageCode]!['no_chats_here_yet']!;
+ }
+
+ String get noFiles {
+ return _localizedValues[locale.languageCode]!['no_files']!;
+ }
+
+ String get noMedia {
+ return _localizedValues[locale.languageCode]!['no_media']!;
+ }
+
+ String get noMentionsExistYet {
+ return _localizedValues[locale.languageCode]!['no_mentions_exist_yet']!;
+ }
+
+ String get noPinnedItems {
+ return _localizedValues[locale.languageCode]!['no_pinned_items']!;
+ }
+
+ String get noResults {
+ return _localizedValues[locale.languageCode]!['no_results']!;
+ }
+
+ String get noSharedGroups {
+ return _localizedValues[locale.languageCode]!['no_shared_groups']!;
+ }
+
+ String get noTitle {
+ return _localizedValues[locale.languageCode]!['no_title']!;
+ }
+
+ String get noUserMatchesTheseKeywords {
+ return _localizedValues[locale.languageCode]![
+ 'no_user_matches_these_keywords']!;
+ }
+
+ String get ok {
+ return _localizedValues[locale.languageCode]!['ok']!;
+ }
+
+ String get online {
+ return _localizedValues[locale.languageCode]!['online']!;
+ }
+
+ String get onThePlatorm {
+ return _localizedValues[locale.languageCode]!['on_the_platform']!;
+ }
+
+ String get operationCouldNotBeCompleted {
+ return _localizedValues[locale.languageCode]![
+ 'operation_could_not_be_completed']!;
+ }
+
+ String get owner {
+ return _localizedValues[locale.languageCode]!['owner']!;
+ }
+
+ String get photosAndVideos {
+ return _localizedValues[locale.languageCode]!['photos_and_videos']!;
+ }
+
+ String get photosOrVideosWillAppearHere {
+ return _localizedValues[locale.languageCode]![
+ 'photos_or_videos_will_appear_here']!;
+ }
+
+ String get pinnedMessages {
+ return _localizedValues[locale.languageCode]!['pinned_messages']!;
+ }
+
+ String get pinToConversation {
+ return _localizedValues[locale.languageCode]!['pin_to_conversation']!;
+ }
+
+ String get reconnecting {
+ return _localizedValues[locale.languageCode]!['reconnecting']!;
+ }
+
+ String get remove {
+ return _localizedValues[locale.languageCode]!['remove']!;
+ }
+
+ String get removeFromGroup {
+ return _localizedValues[locale.languageCode]!['remove_from_group']!;
+ }
+
+ String get removeMember {
+ return _localizedValues[locale.languageCode]!['remove_member']!;
+ }
+
+ String get removeMemberAreYouSure {
+ return _localizedValues[locale.languageCode]![
+ 'remove_member_are_you_sure']!;
+ }
+
+ String get search {
+ return _localizedValues[locale.languageCode]!['search']!;
+ }
+
+ String get selectUserToTryFlutterSDK {
+ return _localizedValues[locale.languageCode]![
+ 'select_user_to_try_flutter_sdk']!;
+ }
+
+ String get sharedGroups {
+ return _localizedValues[locale.languageCode]!['shared_groups']!;
+ }
+
+ String get signOut {
+ return _localizedValues[locale.languageCode]!['sign_out']!;
+ }
+
+ String get somethingWentWrongErrorMessage {
+ return _localizedValues[locale.languageCode]![
+ 'something_went_wrong_error_message']!;
+ }
+
+ String get streamSDK {
+ return _localizedValues[locale.languageCode]!['stream_sdk']!;
+ }
+
+ String get streamTestAccount {
+ return _localizedValues[locale.languageCode]!['stream_test_account']!;
+ }
+
+ String get to {
+ return _localizedValues[locale.languageCode]!['to']!;
+ }
+
+ String get typeANameHint {
+ return _localizedValues[locale.languageCode]!['type_a_name_hint']!;
+ }
+
+ String get userId {
+ return _localizedValues[locale.languageCode]!['user_id']!;
+ }
+
+ String get userIdError {
+ return _localizedValues[locale.languageCode]!['user_id_error']!;
+ }
+
+ String get usernameOptional {
+ return _localizedValues[locale.languageCode]!['username_optional']!;
+ }
+
+ String get userToken {
+ return _localizedValues[locale.languageCode]!['user_token']!;
+ }
+
+ String get userTokenError {
+ return _localizedValues[locale.languageCode]!['user_token_error']!;
+ }
+
+ String get viewInfo {
+ return _localizedValues[locale.languageCode]!['view_info']!;
+ }
+
+ String get welcomeToStreamChat {
+ return _localizedValues[locale.languageCode]!['welcome_to_stream_chat']!;
+ }
+
+ static List languages() => _localizedValues.keys.toList();
+
+ static AppLocalizations of(BuildContext context) {
+ return Localizations.of(context, AppLocalizations)!;
+ }
+}
+
+class AppLocalizationsDelegate extends LocalizationsDelegate {
+ const AppLocalizationsDelegate();
+
+ @override
+ bool isSupported(Locale locale) =>
+ AppLocalizations.languages().contains(locale.languageCode);
+
+ @override
+ Future load(Locale locale) {
+ return SynchronousFuture(AppLocalizations(locale));
+ }
+
+ @override
+ bool shouldReload(AppLocalizationsDelegate old) => false;
+}
diff --git a/packages/stream_chat_v1/lib/main.dart b/packages/stream_chat_v1/lib/main.dart
index b25c857..fc4ed9b 100644
--- a/packages/stream_chat_v1/lib/main.dart
+++ b/packages/stream_chat_v1/lib/main.dart
@@ -2,6 +2,7 @@ import 'dart:async';
import 'package:example/choose_user_page.dart';
import 'package:example/home_page.dart';
+import 'package:example/localizations.dart';
import 'package:example/splash_screen.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
@@ -9,6 +10,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
+import 'package:stream_chat_localizations/stream_chat_localizations.dart';
import 'package:stream_chat_persistence/stream_chat_persistence.dart';
import 'package:streaming_shared_preferences/streaming_shared_preferences.dart';
@@ -107,6 +109,16 @@ class _MyAppState extends State
0: ThemeMode.system,
1: ThemeMode.light,
}[snapshot],
+ supportedLocales: const [
+ Locale('en'),
+ Locale('it'),
+ ],
+ localizationsDelegates: const [
+ AppLocalizationsDelegate(),
+ GlobalStreamChatLocalizations.delegate,
+ GlobalMaterialLocalizations.delegate,
+ GlobalWidgetsLocalizations.delegate,
+ ],
builder: (context, child) => StreamChatTheme(
data: StreamChatThemeData(
brightness: Theme.of(context).brightness,
diff --git a/packages/stream_chat_v1/lib/new_chat_screen.dart b/packages/stream_chat_v1/lib/new_chat_screen.dart
index 7315c71..c0829d0 100644
--- a/packages/stream_chat_v1/lib/new_chat_screen.dart
+++ b/packages/stream_chat_v1/lib/new_chat_screen.dart
@@ -1,5 +1,6 @@
import 'dart:async';
+import 'package:example/localizations.dart';
import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
@@ -124,7 +125,7 @@ class _NewChatScreenState extends State {
backgroundColor: StreamChatTheme.of(context).colorTheme.barsBg,
leading: const StreamBackButton(),
title: Text(
- 'New Chat',
+ AppLocalizations.of(context).newChat,
style: StreamChatTheme.of(context).textTheme.headlineBold.copyWith(
color: StreamChatTheme.of(context).colorTheme.textHighEmphasis),
),
@@ -137,14 +138,14 @@ class _NewChatScreenState extends State {
switch (status) {
case ConnectionStatus.connected:
- statusString = 'Connected';
+ statusString = AppLocalizations.of(context).connected;
showStatus = false;
break;
case ConnectionStatus.connecting:
- statusString = 'Reconnecting...';
+ statusString = AppLocalizations.of(context).reconnecting;
break;
case ConnectionStatus.disconnected:
- statusString = 'Disconnected';
+ statusString = AppLocalizations.of(context).disconnected;
break;
}
return InfoTile(
@@ -162,6 +163,7 @@ class _NewChatScreenState extends State {
key: _chipInputTextFieldStateKey,
controller: _controller,
focusNode: _searchFocusNode,
+ hint: AppLocalizations.of(context).typeANameHint,
chipBuilder: (context, user) {
return GestureDetector(
onTap: () {
@@ -245,7 +247,7 @@ class _NewChatScreenState extends State {
),
SizedBox(width: 8),
Text(
- 'Create a Group',
+ AppLocalizations.of(context).createAGroup,
style: StreamChatTheme.of(context)
.textTheme
.bodyBold,
@@ -269,8 +271,8 @@ class _NewChatScreenState extends State {
),
child: Text(
_isSearchActive
- ? "Matches for \"$_userNameQuery\""
- : 'On the platform',
+ ? '${AppLocalizations.of(context).matchesFor} "$_userNameQuery"'
+ : AppLocalizations.of(context).onThePlatorm,
style: StreamChatTheme.of(context)
.textTheme
.footnote
@@ -307,8 +309,8 @@ class _NewChatScreenState extends State {
filter: Filter.and([
if (_userNameQuery.isNotEmpty)
Filter.autoComplete('name', _userNameQuery),
- Filter.notEqual(
- 'id', StreamChat.of(context).currentUser!.id),
+ Filter.notEqual('id',
+ StreamChat.of(context).currentUser!.id),
]),
sort: [
SortOption(
@@ -339,7 +341,8 @@ class _NewChatScreenState extends State {
),
),
Text(
- 'No user matches these keywords...',
+ AppLocalizations.of(context)
+ .noUserMatchesTheseKeywords,
style: StreamChatTheme.of(
context)
.textTheme
@@ -371,7 +374,7 @@ class _NewChatScreenState extends State {
return Center(
child: Text(
- 'No chats here yet...',
+ AppLocalizations.of(context).noChatsHereYet,
style: TextStyle(
fontSize: 12,
color: StreamChatTheme.of(context)
diff --git a/packages/stream_chat_v1/lib/new_group_chat_screen.dart b/packages/stream_chat_v1/lib/new_group_chat_screen.dart
index 1b21ec5..c9c7c08 100644
--- a/packages/stream_chat_v1/lib/new_group_chat_screen.dart
+++ b/packages/stream_chat_v1/lib/new_group_chat_screen.dart
@@ -1,5 +1,6 @@
import 'dart:async';
+import 'package:example/localizations.dart';
import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
@@ -57,7 +58,7 @@ class _NewGroupChatScreenState extends State {
backgroundColor: StreamChatTheme.of(context).colorTheme.barsBg,
leading: const StreamBackButton(),
title: Text(
- 'Add Group Members',
+ AppLocalizations.of(context).addGroupMembers,
style: TextStyle(
color: StreamChatTheme.of(context).colorTheme.textHighEmphasis,
fontSize: 16,
@@ -94,14 +95,14 @@ class _NewGroupChatScreenState extends State {
switch (status) {
case ConnectionStatus.connected:
- statusString = 'Connected';
+ statusString = AppLocalizations.of(context).connected;
showStatus = false;
break;
case ConnectionStatus.connecting:
- statusString = 'Reconnecting...';
+ statusString = AppLocalizations.of(context).reconnecting;
break;
case ConnectionStatus.disconnected:
- statusString = 'Disconnected';
+ statusString = AppLocalizations.of(context).disconnected;
break;
}
return InfoTile(
@@ -117,6 +118,7 @@ class _NewGroupChatScreenState extends State {
SliverToBoxAdapter(
child: SearchTextField(
controller: _controller,
+ hintText: AppLocalizations.of(context).search,
),
),
if (_selectedUsers.isNotEmpty)
@@ -209,8 +211,8 @@ class _NewGroupChatScreenState extends State {
),
child: Text(
_isSearchActive
- ? 'Matches for \"$_userNameQuery\"'
- : 'On the platform',
+ ? '${AppLocalizations.of(context).matchesFor} \"$_userNameQuery\"'
+ : AppLocalizations.of(context).onThePlatorm,
style: TextStyle(
color: StreamChatTheme.of(context)
.colorTheme
@@ -248,7 +250,8 @@ class _NewGroupChatScreenState extends State {
filter: Filter.and([
if (_userNameQuery.isNotEmpty)
Filter.autoComplete('name', _userNameQuery),
- Filter.notEqual('id', StreamChat.of(context).currentUser!.id),
+ Filter.notEqual(
+ 'id', StreamChat.of(context).currentUser!.id),
]),
sort: [
SortOption(
@@ -278,7 +281,8 @@ class _NewGroupChatScreenState extends State {
),
),
Text(
- 'No user matches these keywords...',
+ AppLocalizations.of(context)
+ .noUserMatchesTheseKeywords,
style: StreamChatTheme.of(context)
.textTheme
.footnote
diff --git a/packages/stream_chat_v1/lib/notifications_service.dart b/packages/stream_chat_v1/lib/notifications_service.dart
index 56f6ad7..d9ad7c5 100644
--- a/packages/stream_chat_v1/lib/notifications_service.dart
+++ b/packages/stream_chat_v1/lib/notifications_service.dart
@@ -1,8 +1,11 @@
+import 'package:example/localizations.dart';
+import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart'
hide Message;
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
-void showLocalNotification(Event event, String currentUserId) async {
+void showLocalNotification(
+ Event event, String currentUserId, BuildContext context) async {
if (![
EventType.messageNew,
EventType.notificationMessageNew,
@@ -27,8 +30,8 @@ void showLocalNotification(Event event, String currentUserId) async {
NotificationDetails(
android: AndroidNotificationDetails(
'message channel',
- 'Message channel',
- 'Channel used for showing messages',
+ AppLocalizations.of(context).messageChannelName,
+ AppLocalizations.of(context).messageChannelDescription,
priority: Priority.high,
importance: Importance.high,
),
diff --git a/packages/stream_chat_v1/lib/pinned_messages_screen.dart b/packages/stream_chat_v1/lib/pinned_messages_screen.dart
index f88270a..bfbb2f6 100644
--- a/packages/stream_chat_v1/lib/pinned_messages_screen.dart
+++ b/packages/stream_chat_v1/lib/pinned_messages_screen.dart
@@ -1,3 +1,4 @@
+import 'package:example/localizations.dart';
import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'package:video_player/video_player.dart';
@@ -64,7 +65,7 @@ class _PinnedMessagesScreenState extends State {
elevation: 1,
centerTitle: true,
title: Text(
- 'Pinned Messages',
+ AppLocalizations.of(context).pinnedMessages,
style: TextStyle(
color: StreamChatTheme.of(context).colorTheme.textHighEmphasis,
fontSize: 16.0,
@@ -102,7 +103,7 @@ class _PinnedMessagesScreenState extends State {
),
SizedBox(height: 16.0),
Text(
- 'No pinned items',
+ AppLocalizations.of(context).noPinnedItems,
style: TextStyle(
fontSize: 17.0,
color:
@@ -115,7 +116,7 @@ class _PinnedMessagesScreenState extends State {
textAlign: TextAlign.center,
text: TextSpan(children: [
TextSpan(
- text: 'Long-press an important message and\nchoose ',
+ text: '${AppLocalizations.of(context).longPressMessage} ',
style: TextStyle(
fontSize: 14.0,
color: StreamChatTheme.of(context)
@@ -125,7 +126,7 @@ class _PinnedMessagesScreenState extends State {
),
),
TextSpan(
- text: 'Pin to conversation',
+ text: AppLocalizations.of(context).pinToConversation,
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.bold,
@@ -186,7 +187,7 @@ class _PinnedMessagesScreenState extends State {
text != ''
? text
: (attachments.isNotEmpty
- ? '${attachments.length} attachment${attachments.length > 1 ? 's' : ''}'
+ ? '${attachments.length} ${attachments.length > 1 ? AppLocalizations.of(context).attachments : AppLocalizations.of(context).attachment}'
: ''),
),
onTap: () {
diff --git a/packages/stream_chat_v1/lib/stream_version.dart b/packages/stream_chat_v1/lib/stream_version.dart
index 89004f7..47d4651 100644
--- a/packages/stream_chat_v1/lib/stream_version.dart
+++ b/packages/stream_chat_v1/lib/stream_version.dart
@@ -1,3 +1,4 @@
+import 'package:example/localizations.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:yaml/yaml.dart';
@@ -26,7 +27,7 @@ class StreamVersion extends StatelessWidget {
yaml['packages']['stream_chat_flutter']['version'];
return Text(
- 'Stream SDK v $streamChatDep',
+ '${AppLocalizations.of(context).streamSDK} v $streamChatDep',
style: TextStyle(
fontSize: 14,
color: StreamChatTheme.of(context).colorTheme.disabled,
diff --git a/packages/stream_chat_v1/lib/user_mentions_page.dart b/packages/stream_chat_v1/lib/user_mentions_page.dart
index 0128787..b10df76 100644
--- a/packages/stream_chat_v1/lib/user_mentions_page.dart
+++ b/packages/stream_chat_v1/lib/user_mentions_page.dart
@@ -1,3 +1,4 @@
+import 'package:example/localizations.dart';
import 'package:example/routes/routes.dart';
import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
@@ -45,7 +46,7 @@ class UserMentionsPage extends StatelessWidget {
),
),
Text(
- 'No mentions exist yet...',
+ AppLocalizations.of(context).noMentionsExistYet,
style: StreamChatTheme.of(context)
.textTheme
.body
diff --git a/packages/stream_chat_v1/pubspec.yaml b/packages/stream_chat_v1/pubspec.yaml
index cc9a05e..55bf802 100644
--- a/packages/stream_chat_v1/pubspec.yaml
+++ b/packages/stream_chat_v1/pubspec.yaml
@@ -20,6 +20,11 @@ dependencies:
url: https://github.com/GetStream/stream-chat-flutter.git
ref: develop
path: packages/stream_chat_persistence
+ stream_chat_localizations:
+ git:
+ url: https://github.com/GetStream/stream-chat-flutter.git
+ ref: develop
+ path: packages/stream_chat_localizations
flutter_local_notifications: ^5.0.0+4
flutter_svg: ^0.22.0
flutter_secure_storage: ^4.2.0
@@ -44,6 +49,16 @@ dependency_overrides:
url: https://github.com/GetStream/stream-chat-flutter.git
ref: develop
path: packages/stream_chat_flutter_core
+ stream_chat_localizations:
+ git:
+ url: https://github.com/GetStream/stream-chat-flutter.git
+ ref: develop
+ path: packages/stream_chat_localizations
+ stream_chat_flutter:
+ git:
+ url: https://github.com/GetStream/stream-chat-flutter.git
+ ref: develop
+ path: packages/stream_chat_flutter
flutter:
assets: