806 lines
24 KiB
Dart
806 lines
24 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'ui/widgets/topbar.dart';
|
|
import 'ui/widgets/chatbubble.dart';
|
|
import 'ui/widgets/sharedimage.dart';
|
|
|
|
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
|
|
|
void main() => runApp(MyApp());
|
|
|
|
class MyApp extends StatelessWidget {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return MaterialApp(
|
|
title: 'Moxxy',
|
|
theme: ThemeData(
|
|
primarySwatch: Colors.blue,
|
|
),
|
|
darkTheme: ThemeData(
|
|
brightness: Brightness.dark
|
|
),
|
|
themeMode: ThemeMode.system,
|
|
routes: {
|
|
"/intro": (context) => IntroPage(),
|
|
"/login": (context) => LoginPage(),
|
|
"/register": (context) => RegistrationPage(),
|
|
"/conversations": (context) => ContactListPage(),
|
|
"/conversation": (context) => ConversationPage(),
|
|
"/conversation/profile": (context) => ProfilePage(),
|
|
"/new_conversation": (context) => NewConversationPage(),
|
|
"/new_conversation/add_contact": (context) => AddContactPage(),
|
|
},
|
|
home: IntroPage(),
|
|
);
|
|
}
|
|
}
|
|
|
|
/*
|
|
class Contact {
|
|
String name;
|
|
|
|
const Contact(this.name);
|
|
}
|
|
*/
|
|
class ContactsListRow extends StatelessWidget {
|
|
//Contact[] contacts = [ new User("Hallo") ];
|
|
String avatarUrl;
|
|
String name;
|
|
|
|
ContactsListRow(this.avatarUrl, this.name);
|
|
|
|
Widget _buildAvatar() {
|
|
if (this.avatarUrl != "") {
|
|
return CircleAvatar(
|
|
backgroundImage: NetworkImage(this.avatarUrl),
|
|
radius: 35.0
|
|
);
|
|
} else {
|
|
return CircleAvatar(
|
|
backgroundColor: Colors.grey,
|
|
child: Text(this.name[0]),
|
|
radius: 35.0
|
|
);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return InkWell(
|
|
onTap: () {
|
|
Navigator.pushNamed(context, "/conversation");
|
|
},
|
|
child: Row(
|
|
children: [
|
|
Padding(
|
|
padding: EdgeInsets.all(8.0),
|
|
child: this._buildAvatar()
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.all(8.0),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
this.name,
|
|
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 17),
|
|
),
|
|
Text("Did you really just call me \"Maru Maru\"?")
|
|
]
|
|
)
|
|
)
|
|
]
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
class ContactListPage extends StatefulWidget {
|
|
@override
|
|
_ContactListState createState() => _ContactListState();
|
|
}
|
|
|
|
class _ContactListState extends State<ContactListPage> {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: PreferredSize(
|
|
preferredSize: Size.fromHeight(60),
|
|
child: BorderlessTopbar(
|
|
children: <Widget>[
|
|
Padding(
|
|
padding: EdgeInsets.only(right: 3.0),
|
|
child: CircleAvatar(
|
|
backgroundImage: NetworkImage("https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse3.mm.bing.net%2Fth%3Fid%3DOIP.MkXhyVPrn9eQGC1CTOyTYAHaHa%26pid%3DApi&f=1"),
|
|
radius: 20.0
|
|
)
|
|
),
|
|
Text(
|
|
"Ojou",
|
|
style: TextStyle(
|
|
fontSize: 18
|
|
)
|
|
)
|
|
]
|
|
)
|
|
),
|
|
body: ListView(
|
|
children: <Widget>[
|
|
ContactsListRow("https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fyt3.ggpht.com%2Fa%2FAGF-l78YnmyE3snkHMp_18AZOP5QRH2WOYSBlnPKFA%3Ds900-c-k-c0xffffffff-no-rj-mo&f=1&nofb=1", "Ars Almal"),
|
|
ContactsListRow("https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse4.mm.bing.net%2Fth%3Fid%3DOIP.N1bqs6sYnkcHO9cp4VY56ACwCw%26pid%3DApi&f=1", "Millie Parfait"),
|
|
ContactsListRow("", "Normal dude"),
|
|
]
|
|
),
|
|
// TODO: Maybe don't use a SpeedDial
|
|
floatingActionButton: SpeedDial(
|
|
icon: Icons.add,
|
|
visible: true,
|
|
curve: Curves.bounceInOut,
|
|
children: [
|
|
SpeedDialChild(
|
|
child: Icon(Icons.person_add),
|
|
onTap: () => Navigator.pushNamed(context, "/new_conversation"),
|
|
label: "Add contact"
|
|
),
|
|
SpeedDialChild(
|
|
child: Icon(Icons.group_add),
|
|
onTap: () => print("OK"),
|
|
label: "Create groupchat"
|
|
),
|
|
SpeedDialChild(
|
|
child: Icon(Icons.group),
|
|
onTap: () => print("OK"),
|
|
label: "Join groupchat"
|
|
)
|
|
]
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _ConversationPageState extends State<ConversationPage> {
|
|
bool _showSendButton = false;
|
|
TextEditingController controller = TextEditingController();
|
|
|
|
_ConversationPageState();
|
|
|
|
@override
|
|
void dispose() {
|
|
this.controller.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
|
|
void _onMessageTextChanged(String value) {
|
|
setState(() {
|
|
this._showSendButton = value != "";
|
|
});
|
|
}
|
|
|
|
void _onSendButtonPressed() {
|
|
if (this._showSendButton) {
|
|
// TODO: Actual sending
|
|
this.controller.clear();
|
|
// NOTE: Calling clear on the controller does not trigger a onChanged on the
|
|
// TextField
|
|
this._onMessageTextChanged("");
|
|
} else {
|
|
// TODO: This
|
|
print("Adding file");
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: PreferredSize(
|
|
preferredSize: Size.fromHeight(60),
|
|
child: BorderlessTopbar(
|
|
children: [
|
|
Center(
|
|
child: InkWell(
|
|
onTap: () {
|
|
Navigator.pop(context);
|
|
},
|
|
child: Icon(Icons.arrow_back)
|
|
)
|
|
),
|
|
Center(
|
|
child: InkWell(
|
|
child: Row(
|
|
children: [
|
|
Padding(
|
|
padding: EdgeInsets.only(left: 16.0),
|
|
child: CircleAvatar(
|
|
backgroundImage: NetworkImage("https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse3.mm.bing.net%2Fth%3Fid%3DOIP.MkXhyVPrn9eQGC1CTOyTYAHaHa%26pid%3DApi&f=1"),
|
|
radius: 25.0
|
|
)
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.only(left: 2.0),
|
|
child: Text(
|
|
"Ojou",
|
|
style: TextStyle(
|
|
fontSize: 20
|
|
)
|
|
)
|
|
)
|
|
]
|
|
),
|
|
onTap: () {
|
|
Navigator.pushNamed(context, "/conversation/profile");
|
|
}
|
|
)
|
|
),
|
|
Spacer(),
|
|
Center(
|
|
child: InkWell(
|
|
// TODO: Implement
|
|
onTap: () {},
|
|
// TODO: Find a better icon
|
|
child: Icon(Icons.menu)
|
|
)
|
|
)
|
|
]
|
|
)
|
|
),
|
|
body: Column(
|
|
children: [
|
|
Expanded(
|
|
child: ListView(
|
|
children: [
|
|
ChatBubble(
|
|
messageContent: "Hello",
|
|
sentBySelf: true
|
|
),
|
|
ChatBubble(
|
|
messageContent: "Hello right back",
|
|
sentBySelf: false
|
|
),
|
|
ChatBubble(
|
|
messageContent: "What a nice person you are!",
|
|
sentBySelf: true
|
|
)
|
|
]
|
|
)
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.all(8.0),
|
|
child: Row(
|
|
children: [
|
|
Expanded(
|
|
child: Container(
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(20),
|
|
border: Border.all(
|
|
width: 1,
|
|
color: Colors.purple
|
|
)
|
|
),
|
|
// TODO: Fix the TextField being too tall
|
|
child: TextField(
|
|
maxLines: 5,
|
|
minLines: 1,
|
|
controller: this.controller,
|
|
onChanged: this._onMessageTextChanged,
|
|
decoration: InputDecoration(
|
|
hintText: "Send a message...",
|
|
border: InputBorder.none,
|
|
contentPadding: EdgeInsets.all(5)
|
|
)
|
|
)
|
|
)
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.only(left: 8.0),
|
|
// NOTE: https://stackoverflow.com/a/52786741
|
|
// Thank you kind sir
|
|
child: Container(
|
|
height: 45.0,
|
|
width: 45.0,
|
|
child: FittedBox(
|
|
child: FloatingActionButton(
|
|
child: Icon(
|
|
this._showSendButton ? Icons.send : Icons.add
|
|
),
|
|
onPressed: this._onSendButtonPressed
|
|
)
|
|
)
|
|
)
|
|
)
|
|
]
|
|
)
|
|
)
|
|
]
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
class ConversationPage extends StatefulWidget {
|
|
const ConversationPage({ Key? key }) : super(key: key);
|
|
|
|
@override
|
|
_ConversationPageState createState() => _ConversationPageState();
|
|
|
|
}
|
|
|
|
class ProfilePage extends StatelessWidget {
|
|
ProfilePage();
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
body: SafeArea(
|
|
child: Stack(
|
|
alignment: Alignment.center,
|
|
children: [
|
|
Positioned(
|
|
child: Column(
|
|
children: [
|
|
CircleAvatar(
|
|
backgroundImage: NetworkImage("https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse3.mm.bing.net%2Fth%3Fid%3DOIP.MkXhyVPrn9eQGC1CTOyTYAHaHa%26pid%3DApi&f=1"),
|
|
radius: 110.0
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.only(top: 8.0),
|
|
child: Text(
|
|
"Nakiri Ayame",
|
|
style: TextStyle(
|
|
fontSize: 30
|
|
)
|
|
)
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.only(top: 3.0),
|
|
child: Text(
|
|
"nakiri.ayame@hololive.tv",
|
|
style: TextStyle(
|
|
fontSize: 15)
|
|
)
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.only(top: 25.0),
|
|
child: Text(
|
|
"Shared Media",
|
|
style: TextStyle(
|
|
fontSize: 25
|
|
)
|
|
)
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.only(top: 8.0),
|
|
child: Container(
|
|
alignment: Alignment.topLeft,
|
|
child: Wrap(
|
|
spacing: 5,
|
|
runSpacing: 5,
|
|
children: [
|
|
SharedImage(
|
|
image: NetworkImage(
|
|
"https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fi.redd.it%2Fv2ybdgx5cow61.jpg&f=1&nofb=1"
|
|
)
|
|
),
|
|
SharedImage(
|
|
image: NetworkImage(
|
|
"https://ih1.redbubble.net/image.1660387906.9194/bg,f8f8f8-flat,750x,075,f-pad,750x1000,f8f8f8.jpg"
|
|
)
|
|
),
|
|
SharedImage(
|
|
image: NetworkImage(
|
|
"https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fcdn.donmai.us%2Fsample%2Fb6%2Fe6%2Fsample-b6e62e3edc1c6dfe6afdb54614b4a710.jpg&f=1&nofb=1"
|
|
)
|
|
),
|
|
SharedImage(
|
|
image: NetworkImage(
|
|
"https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2F64.media.tumblr.com%2Fec84dc5628ca3d8405374b85a51c7328%2Fbb0fc871a5029726-04%2Fs1280x1920%2Ffa6d89e8a2c2f3ce17465d328c2fe0ed6c951f01.jpg&f=1&nofb=1"
|
|
)
|
|
),
|
|
]
|
|
)
|
|
)
|
|
)
|
|
]
|
|
),
|
|
top: 8.0,
|
|
bottom: null,
|
|
left: null,
|
|
right: null
|
|
),
|
|
Positioned(
|
|
top: 8.0,
|
|
left: 8.0,
|
|
child: BackButton()
|
|
)
|
|
]
|
|
)
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
class NewConversationPage extends StatelessWidget {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: PreferredSize(
|
|
preferredSize: Size.fromHeight(60),
|
|
child: BorderlessTopbar(
|
|
children: [
|
|
BackButton(),
|
|
Text(
|
|
"Start new chat",
|
|
style: TextStyle(
|
|
fontSize: 17
|
|
)
|
|
)
|
|
]
|
|
)
|
|
),
|
|
body: ListView(
|
|
children: [
|
|
InkWell(
|
|
onTap: () => Navigator.pushNamed(context, "/new_conversation/add_contact"),
|
|
child: Row(
|
|
children: [
|
|
Padding(
|
|
padding: EdgeInsets.all(8.0),
|
|
child: CircleAvatar(
|
|
child: Icon(Icons.person_add),
|
|
radius: 35.0
|
|
)
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.all(8.0),
|
|
child: Text(
|
|
"Add contact",
|
|
style: TextStyle(
|
|
fontSize: 19,
|
|
fontWeight: FontWeight.bold
|
|
)
|
|
)
|
|
)
|
|
]
|
|
)
|
|
),
|
|
Row(
|
|
children: [
|
|
Padding(
|
|
padding: EdgeInsets.all(8.0),
|
|
child: CircleAvatar(
|
|
child: Icon(Icons.group_add),
|
|
radius: 35.0
|
|
)
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.all(8.0),
|
|
child: Text(
|
|
"Create groupchat",
|
|
style: TextStyle(
|
|
fontSize: 19,
|
|
fontWeight: FontWeight.bold
|
|
)
|
|
)
|
|
)
|
|
]
|
|
),
|
|
Row(
|
|
children: [
|
|
Padding(
|
|
padding: EdgeInsets.all(8.0),
|
|
child: CircleAvatar(
|
|
backgroundImage: NetworkImage("https://vignette.wikia.nocookie.net/virtualyoutuber/images/4/4e/Houshou_Marine_-_Portrait.png/revision/latest?cb=20190821035347"),
|
|
radius: 35.0
|
|
)
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.all(8.0),
|
|
child: Column (
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
"Houshou Marine",
|
|
style: TextStyle(
|
|
fontSize: 19,
|
|
fontWeight: FontWeight.bold
|
|
)
|
|
),
|
|
Text("houshou.marine@hololive.tv")
|
|
]
|
|
)
|
|
)
|
|
]
|
|
)
|
|
]
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
class LoginPage extends StatelessWidget {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: PreferredSize(
|
|
preferredSize: Size.fromHeight(60),
|
|
child: BorderlessTopbar(
|
|
children: [
|
|
BackButton(),
|
|
Text(
|
|
"Login",
|
|
style: TextStyle(
|
|
fontSize: 19
|
|
)
|
|
)
|
|
]
|
|
)
|
|
),
|
|
// TODO: The TextFields look a bit too smal
|
|
// TODO: Hide the LinearProgressIndicator if we're not doing anything
|
|
// TODO: Disable the inputs and the BackButton if we're working on loggin in
|
|
body: Column(
|
|
children: [
|
|
LinearProgressIndicator(value: null),
|
|
Padding(
|
|
padding: EdgeInsets.only(top: 8.0, left: 16.0, right: 16.0),
|
|
child: Container(
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(15),
|
|
border: Border.all(
|
|
width: 1,
|
|
color: Colors.purple
|
|
)
|
|
),
|
|
child: TextField(
|
|
maxLines: 1,
|
|
decoration: InputDecoration(
|
|
labelText: "XMPP-Address",
|
|
border: InputBorder.none,
|
|
contentPadding: EdgeInsets.only(top: 4.0, bottom: 4.0, left: 8.0, right: 8.0)
|
|
)
|
|
)
|
|
)
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.only(top: 8.0, left: 16.0, right: 16.0),
|
|
child: Container(
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(15),
|
|
border: Border.all(
|
|
width: 1,
|
|
color: Colors.purple
|
|
)
|
|
),
|
|
child: TextField(
|
|
maxLines: 1,
|
|
obscureText: true,
|
|
decoration: InputDecoration(
|
|
labelText: "Password",
|
|
border: InputBorder.none,
|
|
contentPadding: EdgeInsets.only(top: 4.0, bottom: 4.0, left: 8.0, right: 8.0),
|
|
suffixIcon: Padding(
|
|
padding: EdgeInsetsDirectional.only(end: 8.0),
|
|
// TODO: Switch this icon depending on the state
|
|
child: Icon(Icons.visibility /*visibility_off*/)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
),
|
|
|
|
ExpansionTile(
|
|
title: Text("Advanced options"),
|
|
children: [
|
|
Column(
|
|
children: [
|
|
SwitchListTile(
|
|
title: Text("Create account on server"),
|
|
value: false,
|
|
onChanged: (value) {}
|
|
)
|
|
]
|
|
)
|
|
]
|
|
),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: Padding(
|
|
padding: EdgeInsets.all(16.0),
|
|
child: ElevatedButton(
|
|
child: Text("Login"),
|
|
onPressed: () => Navigator.pushNamedAndRemoveUntil(
|
|
context,
|
|
"/conversations",
|
|
(route) => false
|
|
)
|
|
)
|
|
)
|
|
)
|
|
]
|
|
)
|
|
]
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
class RegistrationPage extends StatelessWidget {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: PreferredSize(
|
|
preferredSize: Size.fromHeight(60),
|
|
child: BorderlessTopbar(
|
|
children: [
|
|
BackButton(),
|
|
Text(
|
|
"Register",
|
|
style: TextStyle(
|
|
fontSize: 19
|
|
)
|
|
)
|
|
]
|
|
)
|
|
),
|
|
// TODO: The TextFields look a bit too smal
|
|
// TODO: Hide the LinearProgressIndicator if we're not doing anything
|
|
// TODO: Disable the inputs and the BackButton if we're working on loggin in
|
|
body: Column(
|
|
children: [
|
|
LinearProgressIndicator(value: null),
|
|
Padding(
|
|
padding: EdgeInsets.all(16.0),
|
|
child: Text("XMPP is a lot like e-mail: You can send e-mails to people who are not using your specific e-mail provider. As such, there are a lot of XMPP providers. To help you, we chose a random one from a curated list. You only have to pick a username.")
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.only(top: 8.0, left: 16.0, right: 16.0),
|
|
child: Container(
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(15),
|
|
border: Border.all(
|
|
width: 1,
|
|
color: Colors.purple
|
|
)
|
|
),
|
|
child: TextField(
|
|
maxLines: 1,
|
|
decoration: InputDecoration(
|
|
labelText: "Username",
|
|
border: InputBorder.none,
|
|
contentPadding: EdgeInsets.only(top: 4.0, bottom: 4.0, left: 8.0, right: 8.0),
|
|
suffixText: "@polynom.me",
|
|
suffixIcon: Padding(
|
|
padding: EdgeInsetsDirectional.only(end: 6.0),
|
|
child: Icon(Icons.refresh)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: Padding(
|
|
padding: EdgeInsets.all(16.0),
|
|
child: ElevatedButton(
|
|
child: Text("Register"),
|
|
onPressed: () {}
|
|
)
|
|
)
|
|
)
|
|
]
|
|
)
|
|
]
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
class IntroPage extends StatelessWidget {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
// TODO: Fix the typography
|
|
return SafeArea(
|
|
child: Column(
|
|
children: [
|
|
Padding(
|
|
padding: EdgeInsetsDirectional.only(top: 32.0),
|
|
child: Text("moxxy")
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.all(16.0),
|
|
child: Text(
|
|
"An experiment into building a modern easy-to-use XMPP client",
|
|
style: TextStyle(
|
|
fontSize: 20
|
|
)
|
|
)
|
|
),
|
|
ElevatedButton(
|
|
child: Text("Login"),
|
|
onPressed: () => Navigator.pushNamed(context, "/login")
|
|
),
|
|
ElevatedButton(
|
|
child: Text("Register"),
|
|
onPressed: () => Navigator.pushNamed(context, "/register")
|
|
)
|
|
]
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
class AddContactPage extends StatelessWidget {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: PreferredSize(
|
|
preferredSize: Size.fromHeight(60),
|
|
child: BorderlessTopbar(
|
|
children: [
|
|
BackButton(),
|
|
Text(
|
|
"Add new contact",
|
|
style: TextStyle(
|
|
fontSize: 19
|
|
)
|
|
)
|
|
]
|
|
)
|
|
),
|
|
// TODO: The TextFields look a bit too smal
|
|
// TODO: Hide the LinearProgressIndicator if we're not doing anything
|
|
// TODO: Disable the inputs and the BackButton if we're working on loggin in
|
|
body: Column(
|
|
children: [
|
|
LinearProgressIndicator(value: null),
|
|
|
|
Padding(
|
|
padding: EdgeInsets.only(top: 8.0, left: 16.0, right: 16.0),
|
|
child: Container(
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(15),
|
|
border: Border.all(
|
|
width: 1,
|
|
color: Colors.purple
|
|
)
|
|
),
|
|
child: TextField(
|
|
maxLines: 1,
|
|
decoration: InputDecoration(
|
|
labelText: "XMPP-Address",
|
|
border: InputBorder.none,
|
|
contentPadding: EdgeInsets.only(top: 4.0, bottom: 4.0, left: 8.0, right: 8.0),
|
|
suffixIcon: Padding(
|
|
padding: EdgeInsetsDirectional.only(end: 6.0),
|
|
child: Icon(Icons.qr_code)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
),
|
|
|
|
Padding(
|
|
padding: EdgeInsets.all(16.0),
|
|
child: Text("You can add a contact either by typing in their XMPP address or by scanning their QR code")
|
|
),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: Padding(
|
|
padding: EdgeInsets.all(16.0),
|
|
child: ElevatedButton(
|
|
child: Text("Add to contacts"),
|
|
// TODO: Add to roster and open a chat
|
|
onPressed: () {}
|
|
)
|
|
)
|
|
)
|
|
]
|
|
)
|
|
]
|
|
)
|
|
);
|
|
}
|
|
}
|