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..c0a46c0 --- /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', + }, + 'it': { + 'add_a_group_name': 'Aggiungi un nome al gruppo', + 'add_group_members': 'Aggiungi un membro', + 'advanced_options': 'Opzioni Avanzate', + 'api_key_error': 'Per favore inserisci l\'API Key', + 'attachment': 'allegato', + 'attachments': 'allegati', + 'cancel': 'Annulla', + 'chat_api_key': 'Chat API Key', + 'chats': 'Conversazioni', + 'choose_a_group_chat_name': 'Scegli un nome per il gruppo', + 'connected': 'Connesso', + 'create_a_group': 'Crea un Gruppo', + 'custom_settings': 'Opzioni Personalizzate', + 'delete': 'Cancella', + 'delete_conversation_are_you_sure': + 'Sei sicuro di voler eliminare la conversazione?', + 'delete_conversation_title': 'Elimina Conversazione', + 'disconnected': 'Disconnesso', + 'error_connecting': 'Errore durante la connessione, riprova', + 'files': 'File', + 'files_appear_here': 'I file inviati in questa chat compariranno qui', + 'group_shared_with_user_appear_here': + 'I gruppi in comune con quest\'utente compariranno qui', + 'last_seen': 'Ultimo accesso', + 'leave': 'Lascia', + 'leave_conversation': 'Lascia conversazione', + 'leave_conversation_are_you_sure': + 'Sei sicuro di voler lasciare questa conversazione?', + 'leave_group': 'Lascia Gruppo', + 'loading': 'Caricamento...', + 'login': 'Login', + 'long_press_message': 'Premi a lungo su un messaggio importante e scegli', + 'matches_for': 'Risultati per', + 'member': 'Membro', + 'members': 'Membri', + 'mentions': 'Menzioni', + 'message': 'Messaggi', + 'message_channel_description': 'Canale usato per mostrare i messaggi', + 'message_channel_name': 'Invia un messaggio al canale', + 'more': 'altro', + 'mute_group': 'Silenzia gruppo', + 'mute_user': 'Silenzia utente', + 'name': 'Nome', + 'name_of_group_chat': 'Nome del gruppo', + 'new_chat': 'Nuova conversazione', + 'new_direct_message': 'Nuovo messaggio diretto', + 'new_group': 'Nuovo gruppo', + 'no_chats_here_yet': 'Ancora nessun messaggio...', + 'no_files': 'Nessun File', + 'no_media': 'Nessun Media', + 'no_mentions_exist_yet': 'Ancora nessuna menzione...', + 'no_pinned_items': 'Nessun messaggio in evidenza', + 'no_results': 'Nessun risultato...', + 'no_shared_groups': 'Nessun gruppo in comune', + 'no_title': 'Nessun titolo', + 'no_user_matches_these_keywords': 'Nessun utente per questa ricerca...', + 'ok': 'OK', + 'online': 'Online', + 'on_the_platform': 'Sulla piattaforma', + 'operation_could_not_be_completed': + 'Non é stato possibile completare l\'operazione.', + 'owner': 'Proprietario', + 'photos_and_videos': 'Foto & Video', + 'photos_or_videos_will_appear_here': + 'Foto or video inviati in questa chat \ncompariranno qui', + 'pinned_messages': 'Messaggi in evidenza', + 'pin_to_conversation': 'Metti in evidenza', + 'reconnecting': 'Riconnessione...', + 'remove': 'Rimuovi', + 'remove_from_group': 'Rimuovi Dal Gruppo', + 'remove_member': 'Rimuovi membro', + 'remove_member_are_you_sure': + 'Sei sicuro di voler rimuovere questo membro?', + 'search': 'Cerca', + 'select_user_to_try_flutter_sdk': + 'Selezione un utente per provare l\'SDK Flutter', + 'shared_groups': 'Gruppi in comune', + 'sign_out': 'Sign out', + 'something_went_wrong_error_message': 'Qualcosa é andato storto', + 'stream_sdk': 'Stream SDK', + 'stream_test_account': 'Account di test', + 'to': 'A', + 'type_a_name_hint': 'Scrivi un nome', + 'user_id': 'User ID', + 'user_id_error': 'Per favore inserisci l\'ID dell\'utente', + 'username_optional': 'Username (opzionale)', + 'user_token': 'Token Utente', + 'user_token_error': 'Per favore inserisci il token', + 'view_info': 'Vedi info', + 'welcome_to_stream_chat': 'Benvenuto in 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..b236a85 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,11 @@ dependency_overrides: url: https://github.com/GetStream/stream-chat-flutter.git ref: develop path: packages/stream_chat_flutter_core + stream_chat_flutter: + git: + url: https://github.com/GetStream/stream-chat-flutter.git + ref: develop + path: packages/stream_chat_flutter flutter: assets: