forked from alexvasl/drifter_app
main #2
BIN
assets/images/icons/drifter_vector.png
Normal file
BIN
assets/images/icons/drifter_vector.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.7 KiB |
@ -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/home_screen/home_screen_widget.dart';
|
||||||
import 'package:drifter/pages/login_screen/login_screen.dart';
|
import 'package:drifter/pages/login_screen/login_screen.dart';
|
||||||
import 'package:drifter/pages/main_screen/main_screen_widget.dart';
|
import 'package:drifter/pages/main_screen/main_screen_widget.dart';
|
||||||
|
import 'package:drifter/pages/settings_screen/settings_screen.dart';
|
||||||
import 'package:drifter/pages/splash_screen/splash_screen.dart';
|
import 'package:drifter/pages/splash_screen/splash_screen.dart';
|
||||||
import 'package:drifter/pages/terms_of_service/terms_of_service.dart';
|
import 'package:drifter/pages/terms_of_service/terms_of_service.dart';
|
||||||
import 'package:drifter/pages/welcome_screen/welcome_screen.dart';
|
import 'package:drifter/pages/welcome_screen/welcome_screen.dart';
|
||||||
@ -40,6 +41,7 @@ class MyApp extends StatelessWidget {
|
|||||||
'/terms': (context) => const TermsOfServiceScreen(),
|
'/terms': (context) => const TermsOfServiceScreen(),
|
||||||
'/createAccount': (context) => const CreateAccountScreen(),
|
'/createAccount': (context) => const CreateAccountScreen(),
|
||||||
'/MainScreen': (context) => const MainScreenWidget(),
|
'/MainScreen': (context) => const MainScreenWidget(),
|
||||||
|
'/Settings': (context) => const SettingsScreen(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import 'package:dart_nostr/dart_nostr.dart';
|
|||||||
import 'package:drifter/models/models.dart';
|
import 'package:drifter/models/models.dart';
|
||||||
import 'package:drifter/pages/home_screen/widgets/message_text_button_widget.dart';
|
import 'package:drifter/pages/home_screen/widgets/message_text_button_widget.dart';
|
||||||
import 'package:drifter/pages/profile_screen/profile_screen.dart';
|
import 'package:drifter/pages/profile_screen/profile_screen.dart';
|
||||||
|
import 'package:drifter/pages/profile_screen/profile_screen.dart';
|
||||||
|
|
||||||
import 'package:drifter/pages/profile_screen/widgets/keys_option_modal_bottom_sheet.dart';
|
import 'package:drifter/pages/profile_screen/widgets/keys_option_modal_bottom_sheet.dart';
|
||||||
import 'package:drifter/pages/profile_screen/widgets/message_snack_bar.dart';
|
import 'package:drifter/pages/profile_screen/widgets/message_snack_bar.dart';
|
||||||
@ -24,6 +25,84 @@ class CreateAccountScreen extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class CreateAccountScreenState extends State<CreateAccountScreen> {
|
class CreateAccountScreenState extends State<CreateAccountScreen> {
|
||||||
|
final secureStorage = const FlutterSecureStorage();
|
||||||
|
|
||||||
|
Future<bool> generateNewKeys() async {
|
||||||
|
final newPrivateKey = await Nostr.instance.keysService.generatePrivateKey();
|
||||||
|
// final newPrivateKey = keyGenerator.generatePrivateKey();
|
||||||
|
|
||||||
|
final nsec =
|
||||||
|
Nostr.instance.keysService.encodePrivateKeyToNsec(newPrivateKey);
|
||||||
|
|
||||||
|
// final nsecDecoded =
|
||||||
|
// Nostr.instance.keysService.decodeNsecKeyToPrivateKey(nsec);
|
||||||
|
// assert(nsecDecoded['type'] == 'nsec');
|
||||||
|
// assert(nsecDecoded['data'] == newPrivateKey);
|
||||||
|
|
||||||
|
final newPublicKey = await Nostr.instance.keysService
|
||||||
|
.derivePublicKey(privateKey: newPrivateKey);
|
||||||
|
// final newPublicKey = keyGenerator.getPublicKey(newPrivateKey);
|
||||||
|
|
||||||
|
final npub = Nostr.instance.keysService.encodePublicKeyToNpub(newPublicKey);
|
||||||
|
|
||||||
|
// final npubDecoded =
|
||||||
|
// Nostr.instance.keysService.decodeNpubKeyToPublicKey(npub);
|
||||||
|
// assert(npubDecoded['type'] == 'npub');
|
||||||
|
// assert(npubDecoded['data'] == newPublicKey);
|
||||||
|
|
||||||
|
return await addKeyToStorage(newPrivateKey, newPublicKey, nsec, npub);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _getKeysFromStorage() async {
|
||||||
|
// Reading values associated with the " privateKey " and " publicKey " keys from a secure repository
|
||||||
|
final storedPrivateKey = await secureStorage.read(key: 'privateKey');
|
||||||
|
final storedPublicKey = await secureStorage.read(key: 'publicKey');
|
||||||
|
|
||||||
|
final storedNsecKey = await secureStorage.read(key: 'nsec');
|
||||||
|
final storedNpubKey = await secureStorage.read(key: 'npub');
|
||||||
|
|
||||||
|
// Indicates that both private and public keys are stored in a secure repository, after which, the state variables are updated
|
||||||
|
if (storedPrivateKey != null &&
|
||||||
|
storedPublicKey != null &&
|
||||||
|
storedNsecKey != null &&
|
||||||
|
storedNpubKey != null) {
|
||||||
|
setState(() {
|
||||||
|
Keys.privateKey = storedPrivateKey;
|
||||||
|
Keys.publicKey = storedPublicKey;
|
||||||
|
Keys.nsecKey = storedNsecKey;
|
||||||
|
Keys.npubKey = storedNpubKey;
|
||||||
|
Keys.keysExist = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> addKeyToStorage(
|
||||||
|
String privateKeyHex,
|
||||||
|
String publicKeyHex,
|
||||||
|
String nsecKey,
|
||||||
|
String npubKey,
|
||||||
|
) async {
|
||||||
|
// Waiting for both write operations to complete
|
||||||
|
Future.wait([
|
||||||
|
secureStorage.write(key: 'privateKey', value: privateKeyHex),
|
||||||
|
secureStorage.write(key: 'publicKey', value: publicKeyHex),
|
||||||
|
secureStorage.write(key: 'nsec', value: nsecKey),
|
||||||
|
secureStorage.write(key: 'npub', value: npubKey),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Updating status variables and starting widget rebuilding
|
||||||
|
setState(() {
|
||||||
|
Keys.privateKey = privateKeyHex;
|
||||||
|
Keys.publicKey = publicKeyHex;
|
||||||
|
Keys.nsecKey = nsecKey;
|
||||||
|
Keys.npubKey = npubKey;
|
||||||
|
Keys.keysExist = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Returns a boolean value indicating whether the keys were successfully added to the repository or not.
|
||||||
|
return Keys.keysExist;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@ -123,6 +202,15 @@ class CreateAccountScreenState extends State<CreateAccountScreen> {
|
|||||||
height: 56,
|
height: 56,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
final currentContext = context;
|
||||||
|
generateNewKeys().then(
|
||||||
|
(keysGenerated) {
|
||||||
|
if (keysGenerated) {
|
||||||
|
ScaffoldMessenger.of(currentContext).showSnackBar(
|
||||||
|
MessageSnackBar(label: 'Keys Generated!'));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
Navigator.pushNamedAndRemoveUntil(
|
Navigator.pushNamedAndRemoveUntil(
|
||||||
context, '/MainScreen', (_) => false);
|
context, '/MainScreen', (_) => false);
|
||||||
},
|
},
|
||||||
|
@ -90,6 +90,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
backgroundColor: AppColors.mainBackground,
|
||||||
body: RefreshIndicator(
|
body: RefreshIndicator(
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
await _resubscribeStream();
|
await _resubscribeStream();
|
||||||
@ -192,16 +193,16 @@ class TimeAgo {
|
|||||||
String timeAgo = '';
|
String timeAgo = '';
|
||||||
|
|
||||||
if (difference.inDays > 0) {
|
if (difference.inDays > 0) {
|
||||||
timeAgo =
|
timeAgo = '${difference.inDays}d';
|
||||||
'${difference.inDays} ${difference.inDays == 1 ? 'day' : 'days'} ago';
|
// '${difference.inDays} ${difference.inDays == 1 ? 'day' : 'days'} ago';
|
||||||
} else if (difference.inHours > 0) {
|
} else if (difference.inHours > 0) {
|
||||||
timeAgo =
|
timeAgo = '${difference.inHours}h';
|
||||||
'${difference.inHours} ${difference.inHours == 1 ? 'hour' : 'hours'} ago';
|
// '${difference.inHours} ${difference.inHours == 1 ? 'hour' : 'hours'} ago';
|
||||||
} else if (difference.inMinutes > 0) {
|
} else if (difference.inMinutes > 0) {
|
||||||
timeAgo =
|
timeAgo = '${difference.inMinutes}m';
|
||||||
'${difference.inMinutes} ${difference.inMinutes == 1 ? 'minute' : 'minutes'} ago';
|
// '${difference.inMinutes} ${difference.inMinutes == 1 ? 'minute' : 'minutes'} ago';
|
||||||
} else {
|
} else {
|
||||||
timeAgo = 'just now';
|
timeAgo = '${difference.inMinutes}m';
|
||||||
}
|
}
|
||||||
|
|
||||||
return timeAgo;
|
return timeAgo;
|
||||||
@ -237,34 +238,79 @@ class DomainCard extends StatelessWidget {
|
|||||||
return Container(
|
return Container(
|
||||||
margin: const EdgeInsets.all(4),
|
margin: const EdgeInsets.all(4),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.grey,
|
color: AppColors.postBg,
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
children: [
|
||||||
|
// Row(
|
||||||
|
// children: [
|
||||||
|
// CircleAvatar(
|
||||||
|
// radius: 25,
|
||||||
|
// backgroundImage: FadeInImage(
|
||||||
|
// placeholder: const NetworkImage(
|
||||||
|
// 'https://i.ibb.co/mJkxDkb/satoshi.png'),
|
||||||
|
// image: NetworkImage(domain.avatarUrl),
|
||||||
|
// ).image,
|
||||||
|
// ),
|
||||||
|
// Container(
|
||||||
|
// width: 300,
|
||||||
|
// child: Row(
|
||||||
|
// children: [
|
||||||
|
// Text(domain.name),
|
||||||
|
// SizedBox(
|
||||||
|
// width: 4,
|
||||||
|
// ),
|
||||||
|
// Text('@${domain.username.toLowerCase()}',
|
||||||
|
// style: TextStyle(color: AppColors.postUserName)),
|
||||||
|
// Expanded(child: SizedBox()),
|
||||||
|
// Text('${domain.time}',
|
||||||
|
// style: TextStyle(color: AppColors.postUserName)),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// )
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
ListTile(
|
ListTile(
|
||||||
|
contentPadding: EdgeInsets.only(top: 16, right: 16, left: 16),
|
||||||
leading: CircleAvatar(
|
leading: CircleAvatar(
|
||||||
|
radius: 25,
|
||||||
backgroundImage: FadeInImage(
|
backgroundImage: FadeInImage(
|
||||||
placeholder:
|
placeholder:
|
||||||
const NetworkImage('https://i.ibb.co/mJkxDkb/satoshi.png'),
|
const NetworkImage('https://i.ibb.co/mJkxDkb/satoshi.png'),
|
||||||
image: NetworkImage(domain.avatarUrl),
|
image: NetworkImage(domain.avatarUrl),
|
||||||
).image,
|
).image,
|
||||||
),
|
),
|
||||||
title:
|
title: Row(
|
||||||
Text(domain.name, style: const TextStyle(color: Colors.white)),
|
children: [
|
||||||
subtitle: Text('@${domain.username.toLowerCase()} • ${domain.time}',
|
Text(domain.name),
|
||||||
style: TextStyle(color: Colors.grey.shade400)),
|
SizedBox(
|
||||||
trailing: const Icon(Icons.more_vert, color: Colors.grey),
|
width: 4,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
|
child: Text('@${domain.username.toLowerCase()}',
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(color: AppColors.postUserName)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text('${domain.time}',
|
||||||
|
style: TextStyle(color: AppColors.postUserName)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
trailing:
|
||||||
|
const Icon(Icons.more_horiz, color: AppColors.postMoreIcon),
|
||||||
),
|
),
|
||||||
Divider(height: 1, color: Colors.grey.shade400),
|
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
padding:
|
||||||
|
const EdgeInsets.only(top: 12, right: 16, bottom: 14, left: 78),
|
||||||
child: Text(domain.content,
|
child: Text(domain.content,
|
||||||
style: const TextStyle(color: Colors.white)),
|
style: const TextStyle(color: AppColors.postBodyText)),
|
||||||
),
|
),
|
||||||
if (imageLinks != null && imageLinks.isNotEmpty)
|
if (imageLinks != null && imageLinks.isNotEmpty)
|
||||||
Center(
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
top: 12, right: 16, bottom: 14, left: 78),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
const Placeholder(
|
const Placeholder(
|
||||||
@ -274,7 +320,7 @@ class DomainCard extends StatelessWidget {
|
|||||||
Center(
|
Center(
|
||||||
child: FadeInImage(
|
child: FadeInImage(
|
||||||
placeholder: const NetworkImage(
|
placeholder: const NetworkImage(
|
||||||
'https://i.ibb.co/D9jqXgR/58038897-167f0280-7ae6-11e9-94eb-88e880a25f0f.gif',
|
'https://media.tenor.com/On7kvXhzml4AAAAj/loading-gif.gif',
|
||||||
),
|
),
|
||||||
image: NetworkImage(imageLinks.first),
|
image: NetworkImage(imageLinks.first),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
import 'package:drifter/pages/home_screen/home_screen_widget.dart';
|
import 'package:drifter/pages/home_screen/home_screen_widget.dart';
|
||||||
import 'package:drifter/pages/login_screen/login_screen.dart';
|
import 'package:drifter/pages/login_screen/login_screen.dart';
|
||||||
import 'package:drifter/pages/message_screen/message_screen_widget.dart';
|
import 'package:drifter/pages/message_screen/message_screen_widget.dart';
|
||||||
|
import 'package:drifter/pages/notifications_screen/notifications_screen.dart';
|
||||||
import 'package:drifter/pages/profile_screen/profile_screen.dart';
|
import 'package:drifter/pages/profile_screen/profile_screen.dart';
|
||||||
|
import 'package:drifter/pages/search_screen/search_screen.dart';
|
||||||
import 'package:drifter/theme/app_colors.dart';
|
import 'package:drifter/theme/app_colors.dart';
|
||||||
import 'package:drifter/main.dart';
|
import 'package:drifter/main.dart';
|
||||||
import 'package:drifter/utilities/assets.dart';
|
import 'package:drifter/utilities/assets.dart';
|
||||||
@ -17,15 +19,48 @@ class MainScreenWidget extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MainScreenWidgetState extends State<MainScreenWidget> {
|
class _MainScreenWidgetState extends State<MainScreenWidget> {
|
||||||
int _selectedTap = 0;
|
int _selectedTap = 2;
|
||||||
|
late String _title;
|
||||||
|
|
||||||
void onSelectedtap(int index) {
|
void onSelectedtap(int index) {
|
||||||
if (_selectedTap == index) return;
|
if (_selectedTap == index) return;
|
||||||
setState(() {
|
setState(() {
|
||||||
_selectedTap = index;
|
_selectedTap = index;
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
_title = 'Message';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
_title = 'Search';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
_title = 'Feed';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
_title = 'Notifications';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
_title = 'Profile';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
initState() {
|
||||||
|
_title = 'Feed';
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@ -34,7 +69,9 @@ class _MainScreenWidgetState extends State<MainScreenWidget> {
|
|||||||
leading: IconButton(
|
leading: IconButton(
|
||||||
icon: Icon(Icons.settings),
|
icon: Icon(Icons.settings),
|
||||||
color: AppColors.topNavIconPtimary,
|
color: AppColors.topNavIconPtimary,
|
||||||
onPressed: () {},
|
onPressed: () {
|
||||||
|
Navigator.pushNamed(context, '/Settings');
|
||||||
|
},
|
||||||
),
|
),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
IconButton(
|
IconButton(
|
||||||
@ -43,8 +80,8 @@ class _MainScreenWidgetState extends State<MainScreenWidget> {
|
|||||||
onPressed: () {},
|
onPressed: () {},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
title: const Text(
|
title: Text(
|
||||||
"Drifter",
|
_title,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: AppColors.topNavText,
|
color: AppColors.topNavText,
|
||||||
),
|
),
|
||||||
@ -57,8 +94,10 @@ class _MainScreenWidgetState extends State<MainScreenWidget> {
|
|||||||
body: IndexedStack(
|
body: IndexedStack(
|
||||||
index: _selectedTap,
|
index: _selectedTap,
|
||||||
children: const [
|
children: const [
|
||||||
HomeScreen(),
|
|
||||||
MessageScreen(),
|
MessageScreen(),
|
||||||
|
SearchScreen(),
|
||||||
|
HomeScreen(),
|
||||||
|
NotificationsScreen(),
|
||||||
ProfileScreen(),
|
ProfileScreen(),
|
||||||
// LoginScreen(),
|
// LoginScreen(),
|
||||||
],
|
],
|
||||||
@ -67,19 +106,31 @@ class _MainScreenWidgetState extends State<MainScreenWidget> {
|
|||||||
backgroundColor: AppColors.bottomNavBackground,
|
backgroundColor: AppColors.bottomNavBackground,
|
||||||
selectedItemColor: AppColors.bottomNavIconActive,
|
selectedItemColor: AppColors.bottomNavIconActive,
|
||||||
unselectedItemColor: AppColors.bottomNavIconDefault,
|
unselectedItemColor: AppColors.bottomNavIconDefault,
|
||||||
|
selectedFontSize: 0,
|
||||||
currentIndex: _selectedTap,
|
currentIndex: _selectedTap,
|
||||||
|
type: BottomNavigationBarType.fixed,
|
||||||
items: const [
|
items: const [
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.home),
|
icon: Icon(Icons.mail_outline),
|
||||||
label: 'Home',
|
label: '',
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.message),
|
icon: Icon(Icons.search),
|
||||||
label: 'Message',
|
label: '',
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.person),
|
icon:
|
||||||
label: 'Profile',
|
ImageIcon(AssetImage('assets/images/icons/drifter_vector.png')),
|
||||||
|
label: '',
|
||||||
|
),
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: Icon(Icons.notifications_outlined),
|
||||||
|
label: '',
|
||||||
|
),
|
||||||
|
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: Icon(Icons.person_2_outlined),
|
||||||
|
label: '',
|
||||||
),
|
),
|
||||||
// BottomNavigationBarItem(
|
// BottomNavigationBarItem(
|
||||||
// icon: Icon(Icons.login),
|
// icon: Icon(Icons.login),
|
||||||
|
@ -18,7 +18,7 @@ class _MessageScreenState extends State<MessageScreen> {
|
|||||||
children: const [
|
children: const [
|
||||||
Center(
|
Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
"List of posts",
|
"Message",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
18
lib/pages/notifications_screen/notifications_screen.dart
Normal file
18
lib/pages/notifications_screen/notifications_screen.dart
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/src/widgets/placeholder.dart';
|
||||||
|
|
||||||
|
class NotificationsScreen extends StatefulWidget {
|
||||||
|
const NotificationsScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<NotificationsScreen> createState() => _NotificationsScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NotificationsScreenState extends State<NotificationsScreen> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Center(
|
||||||
|
child: Text('Notifications Page'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
18
lib/pages/search_screen/search_screen.dart
Normal file
18
lib/pages/search_screen/search_screen.dart
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/src/widgets/placeholder.dart';
|
||||||
|
|
||||||
|
class SearchScreen extends StatefulWidget {
|
||||||
|
const SearchScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<SearchScreen> createState() => _SearchScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SearchScreenState extends State<SearchScreen> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Center(
|
||||||
|
child: Text('Search Page'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
41
lib/pages/settings_screen/settings_screen.dart
Normal file
41
lib/pages/settings_screen/settings_screen.dart
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import 'package:drifter/theme/app_colors.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/src/widgets/placeholder.dart';
|
||||||
|
|
||||||
|
class SettingsScreen extends StatefulWidget {
|
||||||
|
const SettingsScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<SettingsScreen> createState() => _SettingsScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SettingsScreenState extends State<SettingsScreen> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: AppColors.mainBackground,
|
||||||
|
appBar: AppBar(
|
||||||
|
leading: IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
Icons.arrow_back,
|
||||||
|
color: AppColors.topNavIconPtimary,
|
||||||
|
),
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
('Settings'),
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.topNavText,
|
||||||
|
),
|
||||||
|
// textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
centerTitle: true,
|
||||||
|
backgroundColor: AppColors.mainBackground,
|
||||||
|
elevation: 0,
|
||||||
|
),
|
||||||
|
body: Center(
|
||||||
|
child: Text('Settings'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -35,7 +35,7 @@ class _SplashState extends State<Splash> {
|
|||||||
height: 300,
|
height: 300,
|
||||||
),
|
),
|
||||||
Image.asset(
|
Image.asset(
|
||||||
'assets/images/logo/drifter_vector.png',
|
'assets/images/icons/drifter_vector.png',
|
||||||
height: 111,
|
height: 111,
|
||||||
width: 93,
|
width: 93,
|
||||||
),
|
),
|
||||||
|
@ -64,7 +64,8 @@ flutter:
|
|||||||
|
|
||||||
# To add assets to your application, add an assets section, like this:
|
# To add assets to your application, add an assets section, like this:
|
||||||
assets:
|
assets:
|
||||||
- assets/images/logo/
|
- assets/images//icons/
|
||||||
|
- assets/images//logo/
|
||||||
|
|
||||||
# - images/a_dot_ham.jpeg
|
# - images/a_dot_ham.jpeg
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user