Apresentando um Ui do App Telegram, uma demontração.
Neste Ui, irei apresentar um versão clone, do App do Telegram.
O Projeto feito em Flutter 3.3.*, usando o Dart 2.18.*, e os componentes abaixo.
Componentes usados no UI, (pubspec.yaml)
- line_icons: ^2.0.1 (ícones da Icons8)
- flutter_svg: ^1.1.6 (Desenhe arquivos SVG (e alguns Android VectorDrawable (XML)) em um widget Flutter)
- animate_do: ^2.1.0 (Um pacote de animação inspirado no Animate.css, construído usando apenas animações Flutter, sem pacotes extras)
- bubble: ^1.2.1 (Um widget Flutter para bate-papo como um balão de fala no Whatsapp e outros)
- flutter_font_icons: ^2.2.5 (Fontes para o projeto)
- badges: ^2.0.3 (Badges, até animados)
Pastas do projeto
– (Json) com os seguintes códigos (chat_json.dart, contact_json.dart, setting_json.dart)
– (pages) com os seguintes códigos (chat_detail_page.dart, chats_page.dart, contact_page.dart, root_app.dart, settings_page.dart)
– (theme) com o seguinte código (colors.dart)
– (widgets) com o seguinte código (chat_bubble.dart)
– (raiz) com o seguinte código (main.dart)
O arquivo main.dart, contem a chamada base do projeto.
main.dart
import 'package:flutter/material.dart'; import 'package:telegram_clone_app/pages/root_app.dart'; void main() { runApp(MaterialApp( debugShowCheckedModeBanner: false, home: RootApp(), )); }
Sendo carregado o arquivo root_app.dart, que contem toda a estrutura base do aplicativo, com chamadas de outros projetos dele.
root_app.dart
import 'package:badges/badges.dart'; import 'package:flutter/material.dart'; import 'package:flutter_font_icons/flutter_font_icons.dart'; import 'package:telegram_clone_app/pages/chats_page.dart'; import 'package:telegram_clone_app/pages/contact_page.dart'; import 'package:telegram_clone_app/pages/setting_page.dart'; import 'package:telegram_clone_app/theme/colors.dart'; class RootApp extends StatefulWidget { const RootApp({ Key? key }) : super(key: key); @override _RootAppState createState() => _RootAppState(); } class _RootAppState extends State<RootApp> { int pageIndex = 0; @override Widget build(BuildContext context) { return Scaffold( backgroundColor: bgColor, bottomNavigationBar: getFooter(), body: getBody(), ); } Widget getBody(){ return IndexedStack( index: pageIndex, children: [ ContactPage(), ChatPage(), SettingPage() ], ); } Widget getFooter(){ List iconsItems = [ MaterialIcons.account_circle, Ionicons.ios_chatbubbles, MaterialIcons.settings, ]; List textItems = [ "Contatos", "Chats", "Configuração" ]; return Container( height: 90, width: double.infinity, decoration: BoxDecoration( color: greyColor ), child: Padding( padding: const EdgeInsets.only(top: 5), child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: List.generate(iconsItems.length, (index) { return GestureDetector( onTap: (){ setState(() { pageIndex = index; }); }, child: Column( children: [ index == 1 ? Badge( badgeContent: Text("3",style: TextStyle( color:white ), ), child:Icon(iconsItems[index],size: 30,color:pageIndex == index ? primary :white.withOpacity(0.5)) , ) : Icon(iconsItems[index],size: 30,color:pageIndex == index ? primary :white.withOpacity(0.5)), SizedBox(height: 3,), Text(textItems[index],style: TextStyle(fontSize: 11,color:pageIndex == index ? primary : white.withOpacity(0.5)),) ], ), ); }), ), ), ); } }
Nele contem alguns projetos (Widget) com o nav bar, e seus componentes básicos externos, como os getFooter()
, e getBody()
No getBody
é chamado os seguintes componentes (ContactPage()
, ChatPage()
, SettingPage()
) todos externos.
No getFooter
é montado do Button Nav Bar, com 3 itens o ‘Contatos, Chats, e Configuração),
Com a ligação com seus componentes externos (ContactPage()
, ChatPage()
, SettingPage()
).
O primeiro componente é o ContactPage -> contact_page.dart
contact_page.dart
import 'package:flutter/material.dart'; import 'package:line_icons/line_icons.dart'; import 'package:telegram_clone_app/json/contact_json.dart'; import 'package:telegram_clone_app/theme/colors.dart'; class ContactPage extends StatefulWidget { const ContactPage({ Key? key }) : super(key: key); @override _ContactPageState createState() => _ContactPageState(); } class _ContactPageState extends State<ContactPage> { @override Widget build(BuildContext context) { return Scaffold( backgroundColor: bgColor, appBar: PreferredSize(child: getAppBar(), preferredSize: Size.fromHeight(60)), body: getBody(), ); } Widget getAppBar(){ return AppBar( elevation: 0, backgroundColor: greyColor, title: Text("Contatos", style: TextStyle( fontSize: 20, color: white,fontWeight: FontWeight.w500 ), ), leading: IconButton(onPressed: null, icon: Icon(Icons.sort, size: 27, color: primary), ), actions: [ IconButton(onPressed: null, icon: Icon(LineIcons.plus,color: primary,)) ], ); } Widget getBody(){ return SingleChildScrollView( child: Column( children: [ Container( height: 68, decoration: BoxDecoration( color: greyColor ), child: Padding( padding: const EdgeInsets.all(15), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( height: 38, decoration: BoxDecoration( color: bgColor, borderRadius: BorderRadius.circular(10) ), child: TextField( style: TextStyle( color: white ), cursorColor: primary, decoration: InputDecoration( border: InputBorder.none, prefixIcon: Icon(LineIcons.search,color: white.withOpacity(0.5),), hintText: "Busca", hintStyle: TextStyle( color: white.withOpacity(0.5),fontSize: 17 ) ), ), ) ], ), ), ), SizedBox(height: 10,), getSectionIcons(), getContactLists() ], ), ); } Widget getSectionIcons(){ List icons = [ { "icon": LineIcons.mapMarker, "label" : "Encontrar pessoas próximas" }, { "icon": LineIcons.userPlus, "label" : "Convide amigos" }, ]; return Padding( padding: const EdgeInsets.only(left: 10), child: Column( children: List.generate(icons.length , (index) { return Column( children: [ Row( children: [ Icon(icons[index]['icon'],color: primary,size: 28,), SizedBox(width: 20,), Text(icons[index]['label'],style: TextStyle( fontSize: 16,color: primary,fontWeight: FontWeight.w500 ),) ], ), Padding( padding: const EdgeInsets.only(left: 50), child: Divider( thickness: 1, color: white.withOpacity(0.15), ), ) ], ); }), ), ); } Widget getContactLists(){ return Padding( padding: const EdgeInsets.only(left: 10), child: Column( children: List.generate(contact_data.length, (index) { return Column( children: [ Row( children: [ CircleAvatar( backgroundImage: NetworkImage(contact_data[index]['img']), ), SizedBox(width: 12,), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(contact_data[index]['name'],style: TextStyle( fontSize: 17,color: white,fontWeight: FontWeight.w500 ),), SizedBox(height: 2,), Text(contact_data[index]['is_online'] ? "online" : contact_data[index]['seen'],style: TextStyle( fontSize: 13,color: contact_data[index]['is_online'] ?primary : white.withOpacity(0.5),fontWeight: FontWeight.w500 ),), ], ) ], ), Padding( padding: const EdgeInsets.only(left: 50), child: Divider( thickness: 1, color:white.withOpacity(0.15) ), ) ], ); }), ), ); } }
O segundo componente é o ChatPage -> chats_page.dart
chats_page.dart
import 'package:badges/badges.dart'; import 'package:flutter/material.dart'; import 'package:line_icons/line_icons.dart'; import 'package:telegram_clone_app/json/chat_json.dart'; import 'package:telegram_clone_app/pages/chat_detail_page.dart'; import 'package:telegram_clone_app/theme/colors.dart'; class ChatPage extends StatefulWidget { const ChatPage({Key? key}) : super(key: key); @override _ChatPageState createState() => _ChatPageState(); } class _ChatPageState extends State<ChatPage> { @override Widget build(BuildContext context) { return Scaffold( backgroundColor: bgColor, appBar: PreferredSize(child: getAppBar(), preferredSize: Size.fromHeight(60)), body: getBody(), ); } Widget getAppBar() { return AppBar( elevation: 0, backgroundColor: greyColor, title: Text( "Chats", style: TextStyle(fontSize: 20, color: white, fontWeight: FontWeight.w500), ), leading: IconButton( onPressed: null, icon: Text( "Edit", style: TextStyle( fontSize: 16, color: primary, fontWeight: FontWeight.w500), )), actions: [ IconButton( onPressed: null, icon: Icon( LineIcons.edit, color: primary, )) ], ); } Widget getBody() { var size = MediaQuery.of(context).size; return SingleChildScrollView( child: Column( children: [ Container( height: 68, decoration: BoxDecoration(color: greyColor), child: Padding( padding: const EdgeInsets.all(15), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( height: 38, decoration: BoxDecoration( color: bgColor, borderRadius: BorderRadius.circular(10)), child: TextField( style: TextStyle(color: white), cursorColor: primary, decoration: InputDecoration( border: InputBorder.none, prefixIcon: Icon( LineIcons.search, color: white.withOpacity(0.3), ), hintText: "Search for messages or users", hintStyle: TextStyle( color: white.withOpacity(0.3), fontSize: 17)), ), ) ], ), ), ), SizedBox( height: 20, ), getListChats() ], ), ); } Widget getListChats() { var size = MediaQuery.of(context).size; return Column( children: List.generate(chat_data.length, (index) { return GestureDetector( onTap: (){ Navigator.push(context, MaterialPageRoute(builder: (_) => ChatDetailPage(name: chat_data[index]['name'], img: chat_data[index]['img']))); }, child: Padding( padding: const EdgeInsets.only(left: 12,right: 12,top: 5), child: Row( children: [ Container( width: 60, height: 60, decoration: BoxDecoration( shape: BoxShape.circle, image: DecorationImage( image: NetworkImage(chat_data[index]['img']), fit: BoxFit.cover)), ), SizedBox( width: 12, ), Expanded( child: Container( height: 70, child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( width: (size.width - 40) * 0.6, child: Text( chat_data[index]['name'], style: TextStyle( fontSize: 16, color: white, fontWeight: FontWeight.w600), maxLines: 2, ), ), Text(chat_data[index]['date'],style: TextStyle( fontSize: 14,color: white.withOpacity(0.4) ),) ], ), SizedBox(height: 4,), Container( width: (size.width-40)*1, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(chat_data[index]['text'],style: TextStyle( fontSize: 15, height: 1.3, color: white.withOpacity(0.3) ),), chat_data[index]['badge'] > 0 ? Badge( badgeColor: primary, badgeContent: Padding( padding: const EdgeInsets.all(1), child: Text(chat_data[index]['badge'].toString(),style: TextStyle( color: white ),), ), ) : Container() ], ), ), Divider( color: white.withOpacity(0.3), ) ], ), ), ), ], ), ), ); }), ); } }
O terceiro componente a segunda parte que vem do segundo componente o chats_page.dart, e o segundo este é o chat_detail_page.dart
chat_detail_page.dart
import 'package:flutter/material.dart'; import 'package:flutter_font_icons/flutter_font_icons.dart'; import 'package:telegram_clone_app/json/chat_json.dart'; import 'package:telegram_clone_app/theme/colors.dart'; import 'package:telegram_clone_app/widgets/chat_bubble.dart'; class ChatDetailPage extends StatefulWidget { final String name; final String img; const ChatDetailPage({ Key? key,required this.name,required this.img }) : super(key: key); @override _ChatDetailPageState createState() => _ChatDetailPageState(); } class _ChatDetailPageState extends State<ChatDetailPage> { @override Widget build(BuildContext context) { return Scaffold( backgroundColor: bgColor, appBar: PreferredSize(child: getAppBar(), preferredSize: Size.fromHeight(60)), bottomNavigationBar: getBottomBar(), body: getBody(), ); } Widget getAppBar(){ return AppBar( elevation: 0, backgroundColor: greyColor, title: Container( child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text(widget.name,style: TextStyle( fontSize: 17,color: white, fontWeight: FontWeight.bold ),), Text( "visto pela última vez recentemente", style: TextStyle( fontSize: 12, color: white.withOpacity(0.4), ),), ], ), ), ], ), ), leading: IconButton( onPressed: (){ Navigator.pop(context); }, icon: Icon(Icons.arrow_back_ios,color: primary,), ), actions: [ CircleAvatar( backgroundImage: NetworkImage(widget.img), ) ], ); } Widget getBottomBar(){ var size = MediaQuery.of(context).size; return Container( height: 80, width: double.infinity, decoration: BoxDecoration( color: greyColor ), child: Padding( padding: const EdgeInsets.all(10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ Icon(Entypo.attachment, color: primary, size: 21, ), Container( width: size.width*0.76, height: 32, decoration: BoxDecoration( color: white.withOpacity(0.1), borderRadius: BorderRadius.circular(30) ), child: Padding( padding: const EdgeInsets.only(left: 12), child: TextField( style: TextStyle( color: white, ), cursorColor: primary, decoration: InputDecoration( border: InputBorder.none, suffixIcon: Icon(MaterialCommunityIcons.sticker_emoji,color: primary,size: 25,) ), ), ), ), Icon(MaterialCommunityIcons.microphone,color: primary,size: 28,) ], ), ), ); } Widget getBody(){ return ListView( padding: EdgeInsets.only(top: 20,bottom: 80), children: List.generate(messages.length, (index) { return CustomBubbleChat(isMe: messages[index]['isMe'], message: messages[index]['message'], time: messages[index]['time'], isLast: messages[index]['isLast']); }), ); } }
O quarto e ultimo componente é o settings_page.dart
settings_page.dart
import 'package:badges/badges.dart'; import 'package:flutter/material.dart'; import 'package:telegram_clone_app/json/chat_json.dart'; import 'package:telegram_clone_app/json/setting_json.dart'; import 'package:telegram_clone_app/theme/colors.dart'; class SettingPage extends StatefulWidget { const SettingPage({ Key? key }) : super(key: key); @override _SettingPageState createState() => _SettingPageState(); } class _SettingPageState extends State<SettingPage> { @override Widget build(BuildContext context) { return Scaffold( backgroundColor: bgColor, appBar: PreferredSize(child: getAppBar(), preferredSize: Size.fromHeight(60)), body: getBody(), ); } getAppBar(){ return AppBar( elevation: 0, backgroundColor: bgColor, leading: IconButton( onPressed: null, icon: Icon(Icons.qr_code,color: primary,size: 28,), ), actions: [ IconButton( onPressed: null, icon: Text("Edit",style: TextStyle( fontSize: 16,color: primary,fontWeight: FontWeight.w500 ),), ) ], ); } Widget getBody(){ return SingleChildScrollView( child: Column( children: [ Center( child: Container( width: 90, height: 90, decoration: BoxDecoration( shape: BoxShape.circle, image: DecorationImage(image: NetworkImage(profile[0]['img']),fit: BoxFit.cover) ), ), ), SizedBox(height: 20,), Text(profile[0]['name'],style: TextStyle( fontSize: 24,color: white,fontWeight:FontWeight.w600 ),), SizedBox(height: 2,), Text("+55 21 99222 3201 - @francisco.ferreira",style: TextStyle( fontSize: 18, color: white.withOpacity(0.5), fontWeight: FontWeight.w500 ),), SizedBox(height: 30,), getSectionOne(), SizedBox(height: 30,), getSectionTwo(), SizedBox(height: 30,), getSectionThree(), SizedBox(height: 30,), ], ), ); } Widget getSectionOne(){ return Column( children: List.generate(setting_section_one.length, (index) { return Container( width: double.infinity, decoration: BoxDecoration( color: textfieldColor ), child: Padding( padding: const EdgeInsets.only(left: 10,right: 10,bottom: 8,top: 8), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Container( width: 30, height: 30, decoration: BoxDecoration( color: setting_section_one[index]['color'], borderRadius: BorderRadius.circular(8) ), child: Center( child: Icon(setting_section_one[index]['icon'],color: white,size: 20,), ), ), SizedBox(width: 12,), Text(setting_section_one[index]['text'],style: TextStyle( fontSize: 16,color:white,fontWeight: FontWeight.w500 ),) ], ), Icon(Icons.arrow_forward_ios,color:white.withOpacity(0.2),size: 15,) ], ) ], ), ), ); }), ); } Widget getSectionTwo(){ return Column( children: List.generate(setting_section_two.length, (index) { return Container( width: double.infinity, decoration: BoxDecoration( color: textfieldColor ), child: Padding( padding: const EdgeInsets.only(left: 10,right: 10,bottom: 8,top: 8), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Container( width: 30, height: 30, decoration: BoxDecoration( color: setting_section_two[index]['color'], borderRadius: BorderRadius.circular(8) ), child: Center( child: Icon(setting_section_two[index]['icon'],color: white,size: 20,), ), ), SizedBox(width: 12,), Text(setting_section_two[index]['text'],style: TextStyle( fontSize: 16,color:white,fontWeight: FontWeight.w500 ),) ], ), Row(children: [ getLangAndSticker(setting_section_two[index]['text']), SizedBox(width: 5,), Icon(Icons.arrow_forward_ios,color:white.withOpacity(0.2),size: 15,), ],) ], ) ], ), ), ); }), ); } getLangAndSticker(value){ if(value == "Linguagem"){ return Text("Portugues",style: TextStyle( fontSize: 15,color: white.withOpacity(0.5) ),); }else if(value == "Adesivos e emojis"){ return Badge( badgeColor: primary, badgeContent: Text("12",style: TextStyle( fontSize: 15,color: white ),), ); } return Container(); } Widget getSectionThree(){ return Column( children: List.generate(setting_section_three.length, (index) { return Container( width: double.infinity, decoration: BoxDecoration( color: textfieldColor ), child: Padding( padding: const EdgeInsets.only(left: 10,right: 10,bottom: 8,top: 8), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Container( width: 30, height: 30, decoration: BoxDecoration( color: setting_section_three[index]['color'], borderRadius: BorderRadius.circular(8) ), child: Center( child: Icon(setting_section_three[index]['icon'],color: white,size: 20,), ), ), SizedBox(width: 12,), Text(setting_section_three[index]['text'],style: TextStyle( fontSize: 16,color:white,fontWeight: FontWeight.w500 ),) ], ), Icon(Icons.arrow_forward_ios,color:white.withOpacity(0.2),size: 15,) ], ) ], ), ), ); }), ); } }
Abaixo são os 3 jsons que existe para alimentar o app.
chat_json.dart
const List profile = [ { "name": "Francisco Ferreira", "img": "https://yt3.ggpht.com/ytc/AKedOLTHDJOiJgIkQBX7zkuGEXTY0SgIdiikKIAhXmsttw=s600-c-k-c0x00ffffff-no-rj-rp-mo" } ]; const List chat_data = [ { "img": "https://images.unsplash.com/photo-1531427186611-ecfd6d936c79?ixid=MXwxMjA3fDB8MHxzZWFyY2h8MTB8fHByb2ZpbGV8ZW58MHx8MHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60", "name": "Carlos Sousa", "text": "Sim entendi. Obrigado pelo seu contato.", "date": "3:23 PM", "badge" : 0 }, { "img": "https://images.unsplash.com/photo-1603415526960-f7e0328c63b1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8NDV8fHByb2ZpbGV8ZW58MHx8MHx8&auto=format&fit=crop&w=800&q=60", "name": "Bem Freitas", "text": "Ei cara, vamos conversar em breve.", "date": "3:23 PM", "badge" : 3 }, { "img": "https://images.unsplash.com/photo-1520155707862-5b32817388d6?ixid=MXwxMjA3fDB8MHxzZWFyY2h8MTF8fHByb2ZpbGV8ZW58MHx8MHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60", "name": "Foto Sushi", "text": "indo dormir agora", "date": "2:28 PM", "badge" : 1 }, { "img": "https://images.unsplash.com/photo-1521572267360-ee0c2909d518?ixid=MXwxMjA3fDB8MHxzZWFyY2h8MTd8fHByb2ZpbGV8ZW58MHx8MHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60", "name": "Antonio Soares", "text": "Tenha um bom dia, Freancisco 😁", "date": "9:36 PM", "badge" : 1 }, { "img": "https://images.unsplash.com/photo-1517070208541-6ddc4d3efbcb?ixid=MXwxMjA3fDB8MHxzZWFyY2h8MTZ8fHByb2ZpbGV8ZW58MHx8MHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60", "name": "Carlos Diego", "text": "Como está tudo?", "date": "Sat", "badge" : 0 }, { "img": "https://images.unsplash.com/photo-1525879000488-bff3b1c387cf?ixid=MXwxMjA3fDB8MHxzZWFyY2h8MjV8fHByb2ZpbGV8ZW58MHx8MHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60", "name": "Soares F.", "text": "ok", "date": "Fri", "badge" : 2 }, { "img": "https://images.unsplash.com/photo-1502823403499-6ccfcf4fb453?ixid=MXwxMjA3fDB8MHxzZWFyY2h8MzV8fHByb2ZpbGV8ZW58MHx8MHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60", "name": "Paulo Feiras", "text": "cuidar! fale logo :)", "date": "Thu", "badge" : 0 } ]; const List messages = [ { "isMe": true, "message": "Oi amigo, como vai?", "time": "1:40 PM", "isLast": false, }, { "isMe": true, "message": "bom saber que você está bem.", "time": "1:40 PM", "isLast": false, }, { "isMe": true, "message": "você pode cantar.", "time": "1:41 PM", "isLast": false, }, { "isMe": true, "message": "tudo bem amiga,", "time": "1:41 PM", "isLast": true, }, { "isMe": false, "message": "Boa ei amigo", "time": "2:42 PM", "isLast": false, }, { "isMe": false, "message": "jam cantar 2 nak", "time": "2:44 PM", "isLast": false, }, { "isMe": false, "message": "bom nas", "time": "2:45 PM", "isLast": false, }, { "isMe": false, "message": "Oi amigo.", "time": "2:46 PM", "isLast": true, }, { "isMe": true, "message": "sim, ei de novo Pedro", "time": "1:40 PM", "isLast": false, }, { "isMe": true, "message": "Deixe-me tentar ligar para você amanhã.", "time": "1:40 PM", "isLast": false, }, { "isMe": true, "message": "Da próxima vez pel tenh tam me tov", "time": "1:41 PM", "isLast": false, }, { "isMe": true, "message": "Encomende tam me tov", "time": "1:41 PM", "isLast": true, }, { "isMe": false, "message": "amigo orkun", "time": "2:42 PM", "isLast": false, }, { "isMe": false, "message": "eu tenho uma música sex ai", "time": "2:44 PM", "isLast": false, }, { "isMe": false, "message": "amigo orkun", "time": "2:45 PM", "isLast": false, }, { "isMe": false, "message": "tudo de bom né!!!", "time": "2:46 PM", "isLast": true, }, { "isMe": true, "message": "uau, legal", "time": "1:40 PM", "isLast": false, }, { "isMe": true, "message": "Sim muito bom", "time": "1:40 PM", "isLast": false, }, { "isMe": true, "message": "Não se preocupe, tudo de bom", "time": "1:41 PM", "isLast": false, }, { "isMe": true, "message": "Falo com você em breve.", "time": "1:41 PM", "isLast": true, }, ];
contact_json.dart
const List contact_data = [ { "img": "https://images.unsplash.com/photo-1570295999919-56ceb5ecca61?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MTh8fHByb2ZpbGV8ZW58MHx8MHx8&auto=format&fit=crop&w=800&q=60", "name": "Marcio Soares", "is_online" : true, "seen" : "" }, { "img": "https://images.unsplash.com/photo-1544005313-94ddf0286df2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8NDB8fHByb2ZpbGV8ZW58MHx8MHx8&auto=format&fit=crop&w=800&q=60", "name": "Monica Ferreira", "is_online" : true, "seen" : "" }, { "img": "https://images.unsplash.com/photo-1517070208541-6ddc4d3efbcb?ixid=MXwxMjA3fDB8MHxzZWFyY2h8MTZ8fHByb2ZpbGV8ZW58MHx8MHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60", "name": "Carlos Diego", "is_online" : true, "seen" : "" }, { "img": "https://images.unsplash.com/photo-1502823403499-6ccfcf4fb453?ixid=MXwxMjA3fDB8MHxzZWFyY2h8MzV8fHByb2ZpbGV8ZW58MHx8MHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60", "name": "Paulo Feiras", "is_online" : false, "seen" : "visto pela última vez agora" }, { "img": "https://images.unsplash.com/photo-1603415526960-f7e0328c63b1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8NDV8fHByb2ZpbGV8ZW58MHx8MHx8&auto=format&fit=crop&w=800&q=60", "name": "Bem Freitas", "is_online" : false, "seen" : "visto pela última vez agora" }, { "img": "https://images.unsplash.com/photo-1521572267360-ee0c2909d518?ixid=MXwxMjA3fDB8MHxzZWFyY2h8MTd8fHByb2ZpbGV8ZW58MHx8MHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60", "name": "Antonio Soares", "is_online" : false, "seen" : "visto pela última vez agora" }, { "img": "https://images.unsplash.com/photo-1531427186611-ecfd6d936c79?ixid=MXwxMjA3fDB8MHxzZWFyY2h8MTB8fHByb2ZpbGV8ZW58MHx8MHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60", "name": "Beto Frontes", "is_online" : false, "seen" : "visto pela última vez 1 minuto atrás" }, { "img": "https://images.unsplash.com/photo-1619895862022-09114b41f16f?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1yZWxhdGVkfDd8fHxlbnwwfHx8fA%3D%3D&auto=format&fit=crop&w=800&q=60", "name": "Ana Clara", "is_online" : false, "seen" : "visto pela última vez 1 minuto atrás" }, { "img": "https://images.unsplash.com/photo-1520155707862-5b32817388d6?ixid=MXwxMjA3fDB8MHxzZWFyY2h8MTF8fHByb2ZpbGV8ZW58MHx8MHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60", "name": "Foto Sushi", "is_online" : false, "seen" : "visto pela última vez 2 minuto atrás" }, { "img": "https://images.unsplash.com/photo-1525879000488-bff3b1c387cf?ixid=MXwxMjA3fDB8MHxzZWFyY2h8MjV8fHByb2ZpbGV8ZW58MHx8MHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60", "name": "Soares F.", "is_online" : false, "seen" : "visto pela última vez 2 minuto atrás" }, ];
settings_json.dart
import 'package:flutter/material.dart'; import 'package:flutter_font_icons/flutter_font_icons.dart'; import 'package:line_icons/line_icons.dart'; List setting_section_one = [ {"icon": Icons.bookmark, "text": "Mensagens salvas", "color": Colors.blue[700]}, { "icon": FontAwesome.phone, "text": "Chamada recente", "color": Colors.green }, { "icon": MaterialIcons.devices, "text": "Dispositivos", "color": Color(0xFFFCAA26) }, { "icon": Icons.folder, "text": "Pastas de bate-papo", "color": Colors.cyan }, ]; List setting_section_two = [ {"icon": Icons.notifications, "text": "Notificações e sons", "color": Colors.redAccent}, {"icon": Icons.lock, "text": "Privacidade e segurança", "color": Colors.grey}, { "icon": LineIcons.database, "text": "Data and Storage", "color": Colors.green }, { "icon": Icons.dark_mode, "text": "Aparência", "color": Colors.cyan }, { "icon": Icons.language, "text": "Linguagem", "color": Colors.purple }, { "icon": Icons.sticky_note_2, "text": "Adesivos e emojis", "color": Colors.yellow[800] }, ]; List setting_section_three = [ {"icon": Icons.chat, "text": "Ask a Question", "color": Colors.yellow[800]}, { "icon": Icons.info, "text": "Telegram FAQ", "color": Colors.cyan }, { "icon": MaterialIcons.lightbulb_outline, "text": "Recursos do telegrama", "color": Color(0xFFFCAA26) }, ];