Added QRCode screen, in the development of the profile screen
This commit is contained in:
parent
a7ea864c47
commit
c7d0a114e0
BIN
assets/images/avatar.png
Normal file
BIN
assets/images/avatar.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
assets/images/banner.png
Normal file
BIN
assets/images/banner.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 63 KiB |
BIN
assets/images/logo/drifter_logo_white.png
Normal file
BIN
assets/images/logo/drifter_logo_white.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.8 KiB |
BIN
assets/images/qr.png
Normal file
BIN
assets/images/qr.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 462 B |
@ -4,6 +4,7 @@ import 'package:drifter/pages/create_account_screen/create_account_screen.dart';
|
||||
import 'package:drifter/pages/home_screen/home_screen_widget.dart';
|
||||
import 'package:drifter/pages/login_screen/login_screen.dart';
|
||||
import 'package:drifter/pages/main_screen/main_screen_widget.dart';
|
||||
import 'package:drifter/pages/qr_code_screen/qr_code_screen.dart';
|
||||
import 'package:drifter/pages/settings_screen/settings_screen.dart';
|
||||
import 'package:drifter/pages/splash_screen/splash_screen.dart';
|
||||
import 'package:drifter/pages/terms_of_service/terms_of_service.dart';
|
||||
@ -42,6 +43,7 @@ class MyApp extends StatelessWidget {
|
||||
'/createAccount': (context) => const CreateAccountScreen(),
|
||||
'/MainScreen': (context) => const MainScreenWidget(),
|
||||
'/Settings': (context) => const SettingsScreen(),
|
||||
'/QrCodeScreen': (context) => const QrCodeScreen(),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import 'package:drifter/pages/home_screen/widgets/message_text_button_widget.dar
|
||||
import 'package:drifter/pages/home_screen/widgets/message_text_form_field_widget.dart';
|
||||
import 'package:drifter/pages/profile_screen/widgets/message_snack_bar.dart';
|
||||
import 'package:nostr_tools/nostr_tools.dart';
|
||||
import 'package:toggle_switch/toggle_switch.dart';
|
||||
|
||||
class HomeScreen extends StatefulWidget {
|
||||
const HomeScreen({super.key});
|
||||
@ -20,6 +21,7 @@ class HomeScreen extends StatefulWidget {
|
||||
|
||||
class _HomeScreenState extends State<HomeScreen> {
|
||||
bool _isConnected = false;
|
||||
List<bool> isSelected = [true, false];
|
||||
|
||||
final List<Event> _events = [];
|
||||
final Map<String, Metadata> _metaDatas = {};
|
||||
@ -95,43 +97,123 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
onRefresh: () async {
|
||||
await _resubscribeStream();
|
||||
},
|
||||
child: StreamBuilder(
|
||||
stream: _controller.stream,
|
||||
builder: (context, snapshot) {
|
||||
// Inside the builder callback, the snapshot object contains the most recent event from the thread.
|
||||
// If snapshot.hasData is true, there is data to display. In this case, ListView.builder is returned, which displays a list of NoostCard widgets.
|
||||
if (snapshot.hasData) {
|
||||
return ListView.builder(
|
||||
// The itemCount property of ListView.builder is set to _events.length, , which is the number of events in the _events list.
|
||||
itemCount: _events.length,
|
||||
itemBuilder: (context, index) {
|
||||
final event = _events[index];
|
||||
final metadata = _metaDatas[event.pubkey];
|
||||
// For each event, a Noost object is created that encapsulates the details of the event, including id, avatarUrl, name,username, time, content и pubkey.
|
||||
// _metaDatas, you can map the event public key to the author's metadata.
|
||||
final domain = Domain(
|
||||
noteId: event.id,
|
||||
avatarUrl: metadata?.picture ??
|
||||
'https://robohash.org/${event.pubkey}',
|
||||
name: metadata?.name ?? 'Anon',
|
||||
username: metadata?.displayName ??
|
||||
(metadata?.display_name ?? 'Anon'),
|
||||
time: TimeAgo.format(event.created_at),
|
||||
content: event.content,
|
||||
pubkey: event.pubkey,
|
||||
);
|
||||
return DomainCard(domain: domain);
|
||||
child: Column(
|
||||
children: [
|
||||
// ToggleButtons(
|
||||
// isSelected: isSelected,
|
||||
// renderBorder: false,
|
||||
// fillColor: Color(0xFFFFFFFF),
|
||||
// selectedColor: Color(0xFF4F46F1),
|
||||
// disabledColor: Color(0xFF837CA3),
|
||||
// children: <Widget>[
|
||||
// Container(
|
||||
// margin: const EdgeInsets.all(4),
|
||||
// child: const Text('Following')),
|
||||
// Container(
|
||||
// margin: const EdgeInsets.all(4),
|
||||
// child: const Text('Global')),
|
||||
// ],
|
||||
// onPressed: (int newIndex) {
|
||||
// setState(() {
|
||||
// for (int index = 0; index < isSelected.length; index++) {
|
||||
// if (index == newIndex) {
|
||||
// isSelected[index] = true;
|
||||
// } else {
|
||||
// isSelected[index] = false;
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }),
|
||||
ToggleSwitch(
|
||||
minWidth: double.infinity,
|
||||
minHeight: 40,
|
||||
totalSwitches: 2,
|
||||
labels: ['Following', 'Global'],
|
||||
activeBgColor: [AppColors.toggleSwitchActiveBg],
|
||||
activeFgColor: AppColors.toggleSwitchTextActive,
|
||||
inactiveBgColor: AppColors.toggleSwitchBg,
|
||||
inactiveFgColor: AppColors.toggleSwitchTextInactive,
|
||||
activeBorders: [
|
||||
Border.all(
|
||||
color: AppColors.toggleSwitchBg,
|
||||
width: 4,
|
||||
),
|
||||
],
|
||||
radiusStyle: true,
|
||||
cornerRadius: 100,
|
||||
customTextStyles: [
|
||||
TextStyle(fontSize: 14, fontWeight: FontWeight.w600)
|
||||
],
|
||||
onToggle: (indexToggle) {
|
||||
print(indexToggle);
|
||||
},
|
||||
),
|
||||
SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
Flexible(
|
||||
child: StreamBuilder(
|
||||
stream: _controller.stream,
|
||||
builder: (context, snapshot) {
|
||||
// Inside the builder callback, the snapshot object contains the most recent event from the thread.
|
||||
// If snapshot.hasData is true, there is data to display. In this case, ListView.builder is returned, which displays a list of NoostCard widgets.
|
||||
if (snapshot.hasData) {
|
||||
return ListView.builder(
|
||||
// The itemCount property of ListView.builder is set to _events.length, , which is the number of events in the _events list.
|
||||
itemCount: _events.length,
|
||||
itemBuilder: (context, index) {
|
||||
final event = _events[index];
|
||||
final metadata = _metaDatas[event.pubkey];
|
||||
// For each event, a Noost object is created that encapsulates the details of the event, including id, avatarUrl, name,username, time, content и pubkey.
|
||||
// _metaDatas, you can map the event public key to the author's metadata.
|
||||
final domain = Domain(
|
||||
noteId: event.id,
|
||||
avatarUrl: metadata?.picture ??
|
||||
'https://robohash.org/${event.pubkey}',
|
||||
name: metadata?.name ?? 'Anon',
|
||||
username: metadata?.displayName ??
|
||||
(metadata?.display_name ?? 'Anon'),
|
||||
time: TimeAgo.format(event.created_at),
|
||||
content: event.content,
|
||||
pubkey: event.pubkey,
|
||||
);
|
||||
return DomainCard(domain: domain);
|
||||
},
|
||||
);
|
||||
} else if (snapshot.connectionState ==
|
||||
ConnectionState.waiting) {
|
||||
return const Center(child: Text('Loading....'));
|
||||
} else if (snapshot.hasError) {
|
||||
return Center(child: Text('Error: ${snapshot.error}'));
|
||||
}
|
||||
return const CenteredCircularProgressIndicator();
|
||||
},
|
||||
);
|
||||
} else if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return const Center(child: Text('Loading....'));
|
||||
} else if (snapshot.hasError) {
|
||||
return Center(child: Text('Error: ${snapshot.error}'));
|
||||
}
|
||||
return const CenteredCircularProgressIndicator();
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// ToggleButtons(
|
||||
// isSelected: isSelected,
|
||||
// children: <Widget>[
|
||||
// SizedBox(width: 300, child: Text('Following')),
|
||||
// SizedBox(child: Text('Global')),
|
||||
// ],
|
||||
// onPressed: (int newIndex) {
|
||||
// setState(() {
|
||||
// for (int index = 0;
|
||||
// index < isSelected.length;
|
||||
// index++) {
|
||||
// if (index == newIndex) {
|
||||
// isSelected[index] = true;
|
||||
// } else {
|
||||
// isSelected[index] = false;
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }),
|
||||
|
||||
floatingActionButton: Keys.keysExist
|
||||
? CreatePost(
|
||||
// The publishNote function is called when the user launches the "Noost!" button in the dialog box.
|
||||
@ -318,12 +400,15 @@ class DomainCard extends StatelessWidget {
|
||||
color: Colors.transparent,
|
||||
),
|
||||
Center(
|
||||
child: FadeInImage(
|
||||
placeholder: const NetworkImage(
|
||||
'https://media.tenor.com/On7kvXhzml4AAAAj/loading-gif.gif',
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: FadeInImage(
|
||||
placeholder: const NetworkImage(
|
||||
'https://media.tenor.com/On7kvXhzml4AAAAj/loading-gif.gif',
|
||||
),
|
||||
image: NetworkImage(imageLinks.first),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
image: NetworkImage(imageLinks.first),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -132,94 +132,390 @@ class ProfileScreenState extends State<ProfileScreen> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
privateKeyInput.text = _toHex ? Keys.nsecKey : Keys.privateKey;
|
||||
publicKeyInput.text = _toHex ? Keys.npubKey : Keys.publicKey;
|
||||
publicKeyInput.text = Keys.npubKey;
|
||||
|
||||
return ListView(
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 60,
|
||||
),
|
||||
const UserInfo(),
|
||||
const SizedBox(
|
||||
height: 40,
|
||||
),
|
||||
FormKeys(),
|
||||
const SizedBox(height: 20),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
return Container(
|
||||
color: AppColors.profileWrapperBg,
|
||||
child: Column(
|
||||
children: [
|
||||
Stack(
|
||||
children: [
|
||||
Keys.keysExist
|
||||
? IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_toHex = !_toHex;
|
||||
});
|
||||
},
|
||||
icon: const Icon(Icons.refresh))
|
||||
// ElevatedButton(
|
||||
// style: ButtonStyle(
|
||||
// backgroundColor:
|
||||
// MaterialStateProperty.all(AppColors.background)),
|
||||
// onPressed: () {
|
||||
// keysExistDialog(
|
||||
// Nostr.instance.keysService
|
||||
// .encodePublicKeyToNpub(Keys.publicKey),
|
||||
// Nostr.instance.keysService
|
||||
// .encodePrivateKeyToNsec(Keys.privateKey),
|
||||
// );
|
||||
// },
|
||||
// child: const Text(
|
||||
// 'Keys',
|
||||
// ),
|
||||
// )
|
||||
: Row(
|
||||
children: [
|
||||
ElevatedButton(
|
||||
style: ButtonStyle(
|
||||
backgroundColor: MaterialStateProperty.all(
|
||||
AppColors.background)),
|
||||
onPressed: () {
|
||||
modalBottomSheet();
|
||||
},
|
||||
child: const Text(
|
||||
'Generate Keys',
|
||||
),
|
||||
),
|
||||
SizedBox(width: 100),
|
||||
ElevatedButton(
|
||||
style: ButtonStyle(
|
||||
backgroundColor: MaterialStateProperty.all(
|
||||
AppColors.background)),
|
||||
onPressed: () {
|
||||
Navigator.pushNamed(context, '/login').then((_) {
|
||||
initState();
|
||||
});
|
||||
},
|
||||
child: const Text(
|
||||
'Login',
|
||||
),
|
||||
),
|
||||
],
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: 70,
|
||||
child: FittedBox(
|
||||
child: Image.asset('assets/images/banner.png'),
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(top: 30, left: 16, right: 58),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(200),
|
||||
child: Container(
|
||||
width: 80,
|
||||
height: 80,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
width: 2, color: Color(0xFFF2EFFF))),
|
||||
child: Image.asset('assets/images/avatar.png')),
|
||||
),
|
||||
Keys.keysExist
|
||||
? Row(
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
deleteKeysDialog();
|
||||
},
|
||||
icon: const Icon(Icons.delete)),
|
||||
],
|
||||
)
|
||||
: Container(),
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(top: 74, right: 16),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 32,
|
||||
height: 32,
|
||||
child: FloatingActionButton(
|
||||
backgroundColor:
|
||||
AppColors.buttonSecondaryDefaultBg,
|
||||
onPressed: () {},
|
||||
elevation: 0,
|
||||
child: Icon(
|
||||
Icons.edit,
|
||||
size: 18,
|
||||
color: AppColors.buttonSecondaryIcon,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
SizedBox(
|
||||
width: 32,
|
||||
height: 32,
|
||||
child: FloatingActionButton(
|
||||
backgroundColor:
|
||||
AppColors.buttonSecondaryDefaultBg,
|
||||
onPressed: () {
|
||||
Navigator.pushNamed(context, '/QrCodeScreen');
|
||||
},
|
||||
elevation: 0,
|
||||
child: Icon(
|
||||
Icons.qr_code,
|
||||
size: 18,
|
||||
color: AppColors.buttonSecondaryIcon,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
SizedBox(
|
||||
width: 32,
|
||||
height: 32,
|
||||
child: FloatingActionButton(
|
||||
backgroundColor:
|
||||
AppColors.buttonSecondaryDefaultBg,
|
||||
onPressed: () {},
|
||||
elevation: 0,
|
||||
child: Icon(
|
||||
Icons.mail_outlined,
|
||||
size: 18,
|
||||
color: AppColors.buttonSecondaryIcon,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
SizedBox(
|
||||
width: 100,
|
||||
height: 32,
|
||||
child: ElevatedButton(
|
||||
onPressed: () {},
|
||||
child: Text(
|
||||
'Follow',
|
||||
style: TextStyle(
|
||||
color:
|
||||
AppColors.buttonPrimaryDefaultText),
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor:
|
||||
AppColors.buttonPrimaryDefaultBg,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(100)))),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
Container(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Cameron Williamson',
|
||||
style: TextStyle(
|
||||
color: AppColors.profileFullName,
|
||||
fontWeight: FontWeight.w600),
|
||||
),
|
||||
SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text('@cameron',
|
||||
style: TextStyle(
|
||||
color: AppColors.profileUserName,
|
||||
)),
|
||||
SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
'This is the description of my profile. I am a nostrich and I love cats. Follow me for fun pictures and bad jokes. I also want to be a politician.',
|
||||
style: TextStyle(
|
||||
color: AppColors.profileSummary,
|
||||
)),
|
||||
SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
Container(
|
||||
child: TextField(
|
||||
style: TextStyle(color: AppColors.profileKeyText),
|
||||
readOnly: true,
|
||||
decoration: InputDecoration(
|
||||
suffixIcon: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.copy),
|
||||
color: AppColors.buttonSecondaryIcon,
|
||||
onPressed: () {},
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.qr_code),
|
||||
color: AppColors.buttonSecondaryIcon,
|
||||
onPressed: () {},
|
||||
),
|
||||
],
|
||||
),
|
||||
filled: true,
|
||||
fillColor: AppColors.profileKeyField,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide:
|
||||
BorderSide(width: 0, style: BorderStyle.none),
|
||||
)),
|
||||
minLines: 2,
|
||||
maxLines: 2,
|
||||
controller: publicKeyInput,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
TextButton.icon(
|
||||
// <-- TextButton
|
||||
onPressed: () {},
|
||||
icon: Icon(
|
||||
Icons.check_circle,
|
||||
size: 15.0,
|
||||
color: AppColors.profileSocialIcons,
|
||||
),
|
||||
label: Text(
|
||||
'nip-05-name',
|
||||
style: TextStyle(
|
||||
color: AppColors.profileSocialLinks,
|
||||
fontWeight: FontWeight.w500),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 6,
|
||||
),
|
||||
TextButton.icon(
|
||||
// <-- TextButton
|
||||
onPressed: () {},
|
||||
icon: Icon(
|
||||
Icons.check_circle,
|
||||
size: 15.0,
|
||||
color: AppColors.profileSocialIcons,
|
||||
),
|
||||
label: Text(
|
||||
'www.cameronforpresident.com',
|
||||
style: TextStyle(
|
||||
color: AppColors.profileSocialLinks,
|
||||
fontWeight: FontWeight.w500),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 6,
|
||||
),
|
||||
TextButton.icon(
|
||||
// <-- TextButton
|
||||
onPressed: () {},
|
||||
icon: Icon(
|
||||
Icons.score,
|
||||
size: 15.0,
|
||||
color: AppColors.profileSocialIcons,
|
||||
),
|
||||
label: Text(
|
||||
'@cameron_official',
|
||||
style: TextStyle(
|
||||
color: AppColors.profileSocialLinks,
|
||||
fontWeight: FontWeight.w500),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 6,
|
||||
),
|
||||
TextButton.icon(
|
||||
// <-- TextButton
|
||||
onPressed: () {},
|
||||
icon: Icon(
|
||||
Icons.check_circle,
|
||||
size: 15.0,
|
||||
color: AppColors.profileSocialIcons,
|
||||
),
|
||||
label: Text(
|
||||
'cameron.williamson.com/@cameron_official',
|
||||
style: TextStyle(
|
||||
color: AppColors.profileSocialLinks,
|
||||
fontWeight: FontWeight.w500),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 6,
|
||||
),
|
||||
TextButton.icon(
|
||||
// <-- TextButton
|
||||
onPressed: () {},
|
||||
icon: Icon(
|
||||
Icons.flash_on,
|
||||
size: 15.0,
|
||||
color: AppColors.profileSocialIcons,
|
||||
),
|
||||
label: Text(
|
||||
'whoknowswhatgoeshere',
|
||||
style: TextStyle(
|
||||
color: AppColors.profileSocialLinks,
|
||||
fontWeight: FontWeight.w500),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 6,
|
||||
),
|
||||
TextButton.icon(
|
||||
// <-- TextButton
|
||||
onPressed: () {},
|
||||
icon: Icon(
|
||||
Icons.flash_on,
|
||||
size: 15.0,
|
||||
color: AppColors.profileSocialIcons,
|
||||
),
|
||||
label: Text(
|
||||
'cameron@satoshiwallet.com',
|
||||
style: TextStyle(
|
||||
color: AppColors.profileSocialLinks,
|
||||
fontWeight: FontWeight.w500),
|
||||
),
|
||||
),
|
||||
]),
|
||||
)
|
||||
]),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
// return ListView(
|
||||
// children: [
|
||||
// const SizedBox(
|
||||
// height: 60,
|
||||
// ),
|
||||
// const UserInfo(),
|
||||
// const SizedBox(
|
||||
// height: 40,
|
||||
// ),
|
||||
// FormKeys(),
|
||||
// const SizedBox(height: 20),
|
||||
// Padding(
|
||||
// padding: const EdgeInsets.all(16.0),
|
||||
// child: Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
// children: [
|
||||
// Keys.keysExist
|
||||
// ? IconButton(
|
||||
// onPressed: () {
|
||||
// setState(() {
|
||||
// _toHex = !_toHex;
|
||||
// });
|
||||
// },
|
||||
// icon: const Icon(Icons.refresh))
|
||||
// // ElevatedButton(
|
||||
// // style: ButtonStyle(
|
||||
// // backgroundColor:
|
||||
// // MaterialStateProperty.all(AppColors.background)),
|
||||
// // onPressed: () {
|
||||
// // keysExistDialog(
|
||||
// // Nostr.instance.keysService
|
||||
// // .encodePublicKeyToNpub(Keys.publicKey),
|
||||
// // Nostr.instance.keysService
|
||||
// // .encodePrivateKeyToNsec(Keys.privateKey),
|
||||
// // );
|
||||
// // },
|
||||
// // child: const Text(
|
||||
// // 'Keys',
|
||||
// // ),
|
||||
// // )
|
||||
// : Row(
|
||||
// children: [
|
||||
// ElevatedButton(
|
||||
// style: ButtonStyle(
|
||||
// backgroundColor: MaterialStateProperty.all(
|
||||
// AppColors.background)),
|
||||
// onPressed: () {
|
||||
// modalBottomSheet();
|
||||
// },
|
||||
// child: const Text(
|
||||
// 'Generate Keys',
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(width: 100),
|
||||
// ElevatedButton(
|
||||
// style: ButtonStyle(
|
||||
// backgroundColor: MaterialStateProperty.all(
|
||||
// AppColors.background)),
|
||||
// onPressed: () {
|
||||
// Navigator.pushNamed(context, '/login').then((_) {
|
||||
// initState();
|
||||
// });
|
||||
// },
|
||||
// child: const Text(
|
||||
// 'Login',
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// Keys.keysExist
|
||||
// ? Row(
|
||||
// children: [
|
||||
// IconButton(
|
||||
// onPressed: () {
|
||||
// deleteKeysDialog();
|
||||
// },
|
||||
// icon: const Icon(Icons.delete)),
|
||||
// ],
|
||||
// )
|
||||
// : Container(),
|
||||
// ],
|
||||
// ),
|
||||
// )
|
||||
// ],
|
||||
// );
|
||||
}
|
||||
|
||||
Form FormKeys() {
|
||||
|
166
lib/pages/qr_code_screen/qr_code_screen.dart
Normal file
166
lib/pages/qr_code_screen/qr_code_screen.dart
Normal file
@ -0,0 +1,166 @@
|
||||
import 'package:drifter/models/models.dart';
|
||||
import 'package:drifter/pages/terms_of_service/btn_continue_terms_of_service.dart';
|
||||
import 'package:drifter/pages/terms_of_service/terms_of_service_text.dart';
|
||||
import 'package:drifter/theme/app_colors.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:flutter/src/widgets/placeholder.dart';
|
||||
import 'package:qr_flutter/qr_flutter.dart';
|
||||
|
||||
class QrCodeScreen extends StatefulWidget {
|
||||
const QrCodeScreen({super.key});
|
||||
|
||||
@override
|
||||
State<QrCodeScreen> createState() => _QrCodeScreenState();
|
||||
}
|
||||
|
||||
class _QrCodeScreenState extends State<QrCodeScreen> {
|
||||
String _publicKey = Keys.npubKey;
|
||||
bool isCopied = false;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: IconButton(
|
||||
icon: Icon(
|
||||
Icons.arrow_back,
|
||||
color: AppColors.topNavIconBack,
|
||||
),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
elevation: 0,
|
||||
backgroundColor: AppColors.mainBackground,
|
||||
),
|
||||
backgroundColor: AppColors.mainBackground,
|
||||
body: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(top: 10, right: 16, left: 16, bottom: 16),
|
||||
child: Center(
|
||||
child: Column(children: [
|
||||
Text(
|
||||
'Follow me on Nostr',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF302F38),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w600),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 24, bottom: 83, right: 48, left: 48),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(32),
|
||||
color: Colors.white,
|
||||
),
|
||||
height: 406,
|
||||
width: double.infinity,
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 32.0, bottom: 10),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(200),
|
||||
child: Container(
|
||||
width: 80,
|
||||
height: 80,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
width: 2, color: Color(0xFFF2EFFF))),
|
||||
child: Image.asset('assets/images/avatar.png')),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'Cameron Williams on',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF302F38),
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
'@cameron',
|
||||
style: TextStyle(
|
||||
fontSize: 12, color: AppColors.profileUserName),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
Container(
|
||||
width: 230,
|
||||
child: Text(_publicKey,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.profileSocialLinks))),
|
||||
SizedBox(height: 20),
|
||||
Container(
|
||||
width: 143,
|
||||
height: 143,
|
||||
child: QrImageView(
|
||||
eyeStyle: QrEyeStyle(
|
||||
color: AppColors.qrCodeBody,
|
||||
eyeShape: QrEyeShape.square),
|
||||
dataModuleStyle:
|
||||
QrDataModuleStyle(color: AppColors.qrCodeBody),
|
||||
embeddedImage: AssetImage(
|
||||
'assets/images/logo/drifter_logo_white.png'),
|
||||
data: _publicKey,
|
||||
version: QrVersions.auto,
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
),
|
||||
Expanded(child: SizedBox()),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: 56,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(100)),
|
||||
backgroundColor: AppColors.buttonSecondaryDefaultBg),
|
||||
onPressed: () {
|
||||
Clipboard.setData(ClipboardData(text: _publicKey))
|
||||
.then((value) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
|
||||
content: Text('Copied to clipboard'),
|
||||
));
|
||||
isCopied = true;
|
||||
setState(() {});
|
||||
});
|
||||
},
|
||||
child: isCopied
|
||||
? Text(
|
||||
'Copied',
|
||||
style: TextStyle(color: AppColors.buttonSecondaryText),
|
||||
)
|
||||
: Text(
|
||||
'Copy user ID',
|
||||
style: TextStyle(color: AppColors.buttonSecondaryText),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: 56,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(100)),
|
||||
backgroundColor: AppColors.buttonPrimaryDefaultBg),
|
||||
onPressed: () {},
|
||||
child: Text(
|
||||
'Share QR code',
|
||||
style: TextStyle(color: AppColors.buttonPrimaryDefaultText),
|
||||
),
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -4,6 +4,8 @@ abstract class AppColors {
|
||||
static const background = Color(0xFF4f46f1);
|
||||
static const mainAccent = Color(0xFFFFCC11);
|
||||
static const mainBackground = Color(0xFFF2EFFF);
|
||||
|
||||
// Button
|
||||
static const buttonPrimaryDefaultBg = Color(0xFF4F46F1);
|
||||
static const buttonPrimaryDefaultText = Color(0xFFFFFFFF);
|
||||
static const buttonPrimaryDisabledBg = Color(0x1A18171B);
|
||||
@ -11,6 +13,9 @@ abstract class AppColors {
|
||||
static const buttonOutlinedDefaultBorder = Color(0xFF4F46F1);
|
||||
static const buttonOutlinedDefaultText = Color(0xFF4F46F1);
|
||||
static const buttonOutlinedPressedBg = Color(0xFFE3E0F9);
|
||||
static const buttonSecondaryDefaultBg = Color(0xFFDCDAFC);
|
||||
static const buttonSecondaryIcon = Color(0xFF2D25BC);
|
||||
static const buttonSecondaryText = Color(0xFF2D25BC);
|
||||
|
||||
// TopNav
|
||||
|
||||
@ -72,4 +77,18 @@ abstract class AppColors {
|
||||
static const postActionIconDefault = Color(0xFFC8C5D0);
|
||||
static const postActionIconPressed = Color(0xFFFE82B1);
|
||||
static const postBookmark = Color(0xFF8482FF);
|
||||
|
||||
// Profile
|
||||
|
||||
static const profileWrapperBg = Color(0xFFF9F8FF);
|
||||
static const profileFullName = Color(0xFF302F38);
|
||||
static const profileUserName = Color(0xFF787680);
|
||||
static const profileSummary = Color(0xFF302F38);
|
||||
static const profileKeyField = Color(0xFFF2EFFF);
|
||||
static const profileKeyText = Color(0xFF6E61A0);
|
||||
static const profileSocialLinks = Color(0xFF4F46F1);
|
||||
static const profileSocialIcons = Color(0xFF837CA3);
|
||||
|
||||
// QR code
|
||||
static const qrCodeBody = Color(0xFF25207A);
|
||||
}
|
||||
|
18
pubspec.lock
18
pubspec.lock
@ -352,6 +352,22 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.7.3"
|
||||
qr:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: qr
|
||||
sha256: "64957a3930367bf97cc211a5af99551d630f2f4625e38af10edd6b19131b64b3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
qr_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: qr_flutter
|
||||
sha256: "5095f0fc6e3f71d08adef8feccc8cea4f12eec18a2e31c2e8d82cb6019f4b097"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.0"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
@ -479,4 +495,4 @@ packages:
|
||||
version: "6.2.2"
|
||||
sdks:
|
||||
dart: ">=2.19.6 <3.0.0"
|
||||
flutter: ">=3.7.0-0"
|
||||
flutter: ">=3.7.0"
|
||||
|
@ -40,6 +40,7 @@ dependencies:
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
cupertino_icons: ^1.0.2
|
||||
another_flushbar: ^1.12.29
|
||||
qr_flutter: ^4.1.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
@ -64,8 +65,9 @@ flutter:
|
||||
|
||||
# To add assets to your application, add an assets section, like this:
|
||||
assets:
|
||||
- assets/images//icons/
|
||||
- assets/images//logo/
|
||||
- assets/images/
|
||||
- assets/images/icons/
|
||||
- assets/images/logo/
|
||||
|
||||
# - images/a_dot_ham.jpeg
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user