Skip to content

Instantly share code, notes, and snippets.

@tushar4303
Created January 3, 2023 10:59
Show Gist options
  • Save tushar4303/a6ff0979f7c8ffe15baedcf196e53d11 to your computer and use it in GitHub Desktop.
Save tushar4303/a6ff0979f7c8ffe15baedcf196e53d11 to your computer and use it in GitHub Desktop.
main.dart file for the example app
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:retry/retry.dart';
import 'package:intl/intl.dart';
import 'package:navbar_router/navbar_router.dart';
import 'dart:convert';
import 'package:collection/collection.dart';
import 'package:timeago/timeago.dart' as timeago;
import 'package:cached_network_image/cached_network_image.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key);
final List<Color> colors = [mediumPurple, Colors.orange, Colors.teal];
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'BottomNavbar Demo',
theme: ThemeData(
primarySwatch: Colors.indigo,
),
home: HomePage());
// home: const NavbarSample(title: 'BottomNavbar Demo'));
}
}
class HomePage extends StatelessWidget {
HomePage({Key? key}) : super(key: key);
List<NavbarItem> items = [
NavbarItem(
Icons.home,
'Home',
),
NavbarItem(
Icons.notifications,
'Notifications',
),
NavbarItem(Icons.explore, 'Explore'),
NavbarItem(Icons.person, 'Profile'),
];
final Map<int, Map<String, Widget>> _routes = const {
0: {
'/': HomeScreen(),
},
1: {
'/': NotificationPage(),
},
2: {
'/': MyEvents(),
},
3: {
'/': HomeScreen(),
},
};
@override
Widget build(BuildContext context) {
return NavbarRouter(
errorBuilder: (context) {
return const Center(child: Text('Error 404'));
},
onBackButtonPressed: (isExiting) {
return isExiting;
},
destinationAnimationCurve: Curves.fastOutSlowIn,
destinationAnimationDuration: 600,
decoration: NavbarDecoration(
backgroundColor: Colors.white,
selectedIconTheme: const IconThemeData(color: Colors.black),
navbarType: BottomNavigationBarType.fixed,
elevation: 18,
selectedLabelTextStyle: const TextStyle(color: Colors.black),
enableFeedback: true),
destinations: [
for (int i = 0; i < items.length; i++)
DestinationRouter(
navbarItem: items[i],
destinations: [
for (int j = 0; j < _routes[i]!.keys.length; j++)
Destination(
route: _routes[i]!.keys.elementAt(j),
widget: _routes[i]!.values.elementAt(j),
),
],
initialRoute: _routes[i]!.keys.first,
),
],
);
}
}
class HomeScreen extends StatelessWidget {
static var route;
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
toolbarHeight: MediaQuery.of(context).size.height * 0.096,
elevation: 0.3,
title: Transform(
transform: Matrix4.translationValues(8.0, -5.6, 0),
child: const Text(
"Home",
textAlign: TextAlign.left,
textScaleFactor: 1.3,
style: TextStyle(color: Color.fromARGB(255, 30, 29, 29)),
),
)),
);
}
}
class NotificationPage extends StatefulWidget {
const NotificationPage({super.key});
@override
State<NotificationPage> createState() => _NotificationPageState();
}
class _NotificationPageState extends State<NotificationPage> {
bool showFrom = false;
//set variable for Connectivity subscription listiner
final url =
"https://gist.githubusercontent.com/tushar4303/0ababbdad3073acd8ab2580b5deb084b/raw/e56d65b028681c9beb3074657e9d81f0d33f5391/notifications.json";
final _filters = [];
final _senders = [];
final List<Item> _filteredNotifications = [];
late Future<List<Item>?> myfuture;
@override
void initState() {
// using this listiner, you can get the medium of connection as well.
super.initState();
myfuture = loadNotifications();
}
@override
void dispose() {
super.dispose();
}
Future<List<Item>?> loadNotifications() async {
final r = RetryOptions(maxAttempts: 3);
final response = await r.retry(
// Make a GET request
() => http.get(Uri.parse(url)).timeout(Duration(seconds: 2)),
// Retry on SocketException or TimeoutException
retryIf: (e) => e is SocketException || e is TimeoutException,
);
try {
if (response.statusCode == 200) {
final NotificationsJson = response.body;
final decodedData = jsonDecode(NotificationsJson);
var notificationsData = decodedData["notifications"];
var labelsData = decodedData["labels"];
var senderRolesData = decodedData["senderRoles"];
NotificationModel.labels = List.from(labelsData);
NotificationModel.senderRoles = List.from(senderRolesData);
NotificationModel.items = List.from(notificationsData)
.map<Item>((item) => Item.fromMap(item))
.toList();
setState(() {
_filters.clear();
_senders.clear();
showFrom = false;
_filteredNotifications.clear();
_filteredNotifications.addAll(NotificationModel.items!);
});
return NotificationModel.items;
}
} catch (e) {
throw Exception(e.toString());
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color.fromARGB(255, 255, 255, 255),
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
toolbarHeight: MediaQuery.of(context).size.height * 0.125,
elevation: 0.3,
// title: Text("Notifications"),
title: Transform(
transform: Matrix4.translationValues(8.0, 16.0, 0),
child: Column(
// mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Notifications",
textAlign: TextAlign.left,
textScaleFactor: 1.3,
style: TextStyle(color: Color.fromARGB(255, 30, 29, 29)),
),
SizedBox(
height: 4,
),
(NotificationModel.labels != null &&
NotificationModel.labels!.isNotEmpty)
? SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Container(
margin: EdgeInsets.only(bottom: 16),
child: Row(
children: [
Transform(
transform: Matrix4.translationValues(0, -4, 0),
child: Visibility(
visible: showFrom,
child: Padding(
padding: const EdgeInsets.only(right: 16),
child: ActionChip(
onPressed: () {
//if filtertype == Academics then call show modalbottomsheet
showModalBottomSheet(
enableDrag: true,
useRootNavigator: true,
isScrollControlled: true,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(25.0),
),
),
context: context,
builder: (builder) {
return SingleChildScrollView(
child: SizedBox(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: const Radius
.circular(20.0),
topRight: const Radius
.circular(20.0))),
//content starts
child: Container(
margin: EdgeInsets.only(
right: 5.0,
left: 5.0,
top: 10.0),
child: Column(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: <Widget>[
// rounded rectangle grey handle
Container(
width: 40.0,
height: 5.0,
decoration:
BoxDecoration(
borderRadius:
BorderRadius
.circular(
10.0),
color: Colors.grey,
),
),
SingleChildScrollView(
child: Column(
crossAxisAlignment:
CrossAxisAlignment
.start,
mainAxisAlignment:
MainAxisAlignment
.start,
children: (NotificationModel
.senderRoles!
.map(
(sender) {
return Column(
children: [
ListTile(
title: Text(
sender),
trailing:
Visibility(
visible:
_senders.contains(sender),
child:
Icon(
Icons
.done,
color:
Colors.blueAccent,
),
),
onTap:
() {
setState(
() {
if (_senders
.contains(sender)) {
_senders.remove(sender);
} else {
_senders.add(sender);
}
});
},
),
Divider(),
],
);
}).toList())),
),
],
),
),
),
),
);
});
},
label: Text("From"),
avatar: Icon(
Icons.account_circle,
color: Colors.black,
),
visualDensity:
VisualDensity(vertical: -1.5),
side: BorderSide(
width: 1,
color: Color.fromARGB(66, 75, 74, 74)),
// surfaceTintColor: Colors.black,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
),
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children:
(NotificationModel.labels!.map((filterType) {
return Transform(
transform: Matrix4.identity()..scale(0.85),
child: FilterChip(
checkmarkColor: Colors.black,
label: Text(
filterType,
textScaleFactor: 1.1,
),
// labelPadding: EdgeInsets.symmetric(
// horizontal: 4, vertical: 0),
selected: _filters.contains(filterType),
side: BorderSide(
width: 1,
color:
Color.fromARGB(66, 75, 74, 74)),
// surfaceTintColor: Colors.black,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(20.0),
),
selectedColor:
Color.fromARGB(180, 224, 220, 220),
onSelected: ((value) {
setState(() {
if (value) {
_filters.add(filterType);
} else {
_filters.removeWhere((name) {
return name == filterType;
});
}
_filteredNotifications.clear();
if (_filters
.contains("Academics")) {
setState(() {
showFrom = true;
});
} else {
setState(() {
showFrom = false;
});
}
if (_filters.isEmpty) {
_filteredNotifications.addAll(
NotificationModel.items!);
} else {
_filteredNotifications.addAll(
NotificationModel.items!.where(
(notification) => _filters
.contains(notification
.messageLabel)));
}
});
})));
}).toList()),
),
],
),
),
)
: Center(
child: CircularProgressIndicator(
color: Colors.white,
)),
],
),
),
),
body: Column(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
child: FutureBuilder(
future: myfuture,
builder: ((context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasData) {
return RefreshIndicator(
onRefresh: () async {
loadNotifications();
},
child: Padding(
padding: const EdgeInsets.only(bottom: 54),
child: ListView.builder(
itemCount: _filteredNotifications.length,
itemBuilder: (context, index) {
return NotificationWidget(
item: _filteredNotifications[index],
);
}),
),
);
} else if (snapshot.hasError) {
return Text("Some error has occured");
}
}
return Center(
child: CircularProgressIndicator(
color: Colors.black,
),
);
}))),
),
],
),
// ignore: prefer_const_literals_to_create_immutables
);
}
}
class MyEvents extends StatefulWidget {
const MyEvents({super.key});
@override
State<MyEvents> createState() => _MyEventsState();
}
class _MyEventsState extends State<MyEvents> {
bool showFrom = false;
//set variable for Connectivity subscription listiner
final url =
"https://gist.githubusercontent.com/tushar4303/675432e0e112e258c971986dbca37156/raw/d805186a9b7fb95b8606fe2b2257fcadadb2a47c/events.json";
final _filters = [];
final _senders = [];
final List<Item> _filteredEvents = [];
late Future<List<Item>?> myfuture;
@override
void initState() {
// using this listiner, you can get the medium of connection as well.
super.initState();
myfuture = loadEvents();
}
@override
void dispose() {
super.dispose();
}
Future<List<Item>?> loadEvents() async {
final r = RetryOptions(maxAttempts: 3);
final response = await r.retry(
// Make a GET request
() => http.get(Uri.parse(url)).timeout(Duration(seconds: 2)),
// Retry on SocketException or TimeoutException
retryIf: (e) => e is SocketException || e is TimeoutException,
);
try {
if (response.statusCode == 200) {
final EventsJson = response.body;
final decodedData = jsonDecode(EventsJson);
var eventsData = decodedData["events"];
var labelsData = decodedData["labels"];
var senderRolesData = decodedData["senderRoles"];
NotificationModel.labels = List.from(labelsData);
NotificationModel.senderRoles = List.from(senderRolesData);
NotificationModel.items = List.from(eventsData)
.map<Item>((item) => Item.fromMap(item))
.toList();
setState(() {
_filters.clear();
_senders.clear();
showFrom = false;
_filteredEvents.clear();
_filteredEvents.addAll(NotificationModel.items!);
});
return NotificationModel.items;
}
} catch (e) {
throw Exception(e.toString());
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color.fromARGB(255, 255, 255, 255),
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
toolbarHeight: MediaQuery.of(context).size.height * 0.125,
elevation: 0.3,
// title: Text("Notifications"),
title: Transform(
transform: Matrix4.translationValues(8.0, 16.0, 0),
child: Column(
// mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Events",
textAlign: TextAlign.left,
textScaleFactor: 1.3,
style: TextStyle(color: Color.fromARGB(255, 30, 29, 29)),
),
SizedBox(
height: 4,
),
(NotificationModel.labels != null &&
NotificationModel.labels!.isNotEmpty)
? SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Container(
margin: EdgeInsets.only(bottom: 16),
child: Row(
children: [
Transform(
transform: Matrix4.translationValues(0, -4, 0),
child: Visibility(
visible: showFrom,
child: Padding(
padding: const EdgeInsets.only(right: 16),
child: ActionChip(
onPressed: () {
//if filtertype == Academics then call show modalbottomsheet
showModalBottomSheet(
enableDrag: true,
useRootNavigator: true,
isScrollControlled: true,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(25.0),
),
),
context: context,
builder: (builder) {
return SingleChildScrollView(
child: SizedBox(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: const Radius
.circular(20.0),
topRight: const Radius
.circular(20.0))),
//content starts
child: Container(
margin: EdgeInsets.only(
right: 5.0,
left: 5.0,
top: 10.0),
child: Column(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: <Widget>[
// rounded rectangle grey handle
Container(
width: 40.0,
height: 5.0,
decoration:
BoxDecoration(
borderRadius:
BorderRadius
.circular(
10.0),
color: Colors.grey,
),
),
SingleChildScrollView(
child: Column(
crossAxisAlignment:
CrossAxisAlignment
.start,
mainAxisAlignment:
MainAxisAlignment
.start,
children: (NotificationModel
.senderRoles!
.map(
(sender) {
return Column(
children: [
ListTile(
title: Text(
sender),
trailing:
Visibility(
visible:
_senders.contains(sender),
child:
Icon(
Icons
.done,
color:
Colors.blueAccent,
),
),
onTap:
() {
setState(
() {
if (_senders
.contains(sender)) {
_senders.remove(sender);
} else {
_senders.add(sender);
}
});
},
),
Divider(),
],
);
}).toList())),
),
],
),
),
),
),
);
});
},
label: Text("From"),
avatar: Icon(
Icons.auto_awesome,
color: Colors.black,
),
visualDensity:
VisualDensity(vertical: -1.5),
side: BorderSide(
width: 1,
color: Color.fromARGB(66, 75, 74, 74)),
// surfaceTintColor: Colors.black,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
),
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children:
(NotificationModel.labels!.map((filterType) {
return Transform(
transform: Matrix4.identity()..scale(0.85),
child: FilterChip(
checkmarkColor: Colors.black,
label: Text(
filterType,
textScaleFactor: 1.1,
),
// labelPadding: EdgeInsets.symmetric(
// horizontal: 4, vertical: 0),
selected: _filters.contains(filterType),
side: BorderSide(
width: 1,
color:
Color.fromARGB(66, 75, 74, 74)),
// surfaceTintColor: Colors.black,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(20.0),
),
selectedColor:
Color.fromARGB(180, 224, 220, 220),
onSelected: ((value) {
setState(() {
if (value) {
_filters.add(filterType);
} else {
_filters.removeWhere((name) {
return name == filterType;
});
}
_filteredEvents.clear();
if (_filters
.contains("Technical")) {
setState(() {
showFrom = true;
});
} else {
setState(() {
showFrom = false;
});
}
if (_filters.isEmpty) {
_filteredEvents.addAll(
NotificationModel.items!);
} else {
_filteredEvents.addAll(
NotificationModel.items!.where(
(notification) => _filters
.contains(notification
.messageLabel)));
}
});
})));
}).toList()),
),
],
),
),
)
: Center(
child: CircularProgressIndicator(
color: Colors.white,
)),
],
),
),
),
body: Column(
children: [
Expanded(
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: FutureBuilder(
future: myfuture,
builder: ((context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasData) {
return RefreshIndicator(
onRefresh: () async {
loadEvents();
},
child: Padding(
padding:
const EdgeInsets.only(bottom: 54, top: 4),
child: GridView.builder(
itemCount: _filteredEvents.length,
itemBuilder: (context, index) {
return EventsWidget(
item: _filteredEvents[index]);
},
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 16.0,
mainAxisSpacing: 12.0,
mainAxisExtent: 310.0),
),
),
);
} else if (snapshot.hasError) {
return Text("Some error has occured");
}
}
return Center(
child: CircularProgressIndicator(
color: Colors.black,
),
);
}))),
),
],
),
// ignore: prefer_const_literals_to_create_immutables
);
}
}
class EventsWidget extends StatelessWidget {
const EventsWidget({super.key, required this.item});
final Item item;
@override
Widget build(BuildContext context) {
return Hero(
tag: Key(item.messageId.toString()),
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NotificationDetailsPage(item: item)));
},
child: Column(
children: [
ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(12)),
child: Stack(
children: <Widget>[
Container(
height: 260,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12.0)),
child: CachedNetworkImage(
fit: BoxFit.cover,
imageUrl: item.imageUrl,
placeholder: (context, url) {
return Image.asset(
"assets/images/placeholder.png",
fit: BoxFit.cover,
);
},
),
),
Positioned(
child: Container(
margin: const EdgeInsets.only(top: 236),
height: 24,
color: const Color.fromARGB(165, 0, 0, 0),
child: Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.only(left: 8),
child: RichText(
maxLines: 2,
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
text: TextSpan(
text: null,
style: const TextStyle(
fontSize: 12, color: Colors.black87),
children: [
const WidgetSpan(
child: Icon(
Icons.watch_later_outlined,
size: 12,
color: Colors.white,
),
),
TextSpan(
text:
" ${DateFormat('MMM d, ' 'yy').format(item.dateOfcreation)}",
style: const TextStyle(
fontSize: 12,
color: Colors.white,
fontWeight: FontWeight.w500)),
]),
),
),
),
),
),
],
),
),
const SizedBox(
height: 8,
),
Align(
alignment: Alignment.topLeft,
child: Text(item.messageTitle,
maxLines: 2,
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontSize: 16, fontWeight: FontWeight.bold)),
),
// Align(
// alignment: Alignment.topLeft,
// child: Text(
// item
// .messageLabel,
// maxLines: 2,
// textAlign: TextAlign.left,
// overflow: TextOverflow.ellipsis,
// style: const TextStyle(
// fontSize: 14,
// )),
// ),
],
),
));
}
}
// ignore_for_file: prefer_const_constructors
// ignore_for_file: public_member_api_docs, sort_constructors_first
class NotificationModel {
static List<String>? labels;
static List<String>? senderRoles;
static List<Item>? items;
}
class SenderRoles {
final List senderRoles;
SenderRoles(
this.senderRoles,
);
SenderRoles copyWith({
List? senderRoles,
}) {
return SenderRoles(
senderRoles ?? this.senderRoles,
);
}
Map<String, dynamic> toMap() {
return <String, dynamic>{
'senderRoles': senderRoles,
};
}
factory SenderRoles.fromMap(Map<String, dynamic> map) {
return SenderRoles(List.from(
(map['senderRoles'] as List),
));
}
String toJson() => json.encode(toMap());
factory SenderRoles.fromJson(String source) =>
SenderRoles.fromMap(json.decode(source) as Map<String, dynamic>);
@override
String toString() => 'SenderRoles(senderRoles: $senderRoles)';
@override
bool operator ==(covariant SenderRoles other) {
if (identical(this, other)) return true;
final listEquals = const DeepCollectionEquality().equals;
return listEquals(other.senderRoles, senderRoles);
}
@override
int get hashCode => senderRoles.hashCode;
}
class Labels {
final List labels;
Labels(
this.labels,
);
Labels copyWith({
List? labels,
}) {
return Labels(
labels ?? this.labels,
);
}
Map<String, dynamic> toMap() {
return <String, dynamic>{
'labels': labels,
};
}
factory Labels.fromMap(Map<String, dynamic> map) {
return Labels(List.from(
(map['labels'] as List),
));
}
String toJson() => json.encode(toMap());
factory Labels.fromJson(String source) =>
Labels.fromMap(json.decode(source) as Map<String, dynamic>);
@override
String toString() => 'Labels(labels: $labels)';
@override
bool operator ==(covariant Labels other) {
if (identical(this, other)) return true;
final listEquals = const DeepCollectionEquality().equals;
return listEquals(other.labels, labels);
}
@override
int get hashCode => labels.hashCode;
}
class Item {
final int messageId;
final String userName;
final String userRole;
final String messageTitle;
final String messageLabel;
final String userMessage;
final String imageUrl;
final DateTime dateOfcreation;
Item(
{required this.messageId,
required this.userName,
required this.userRole,
required this.messageTitle,
required this.messageLabel,
required this.userMessage,
required this.imageUrl,
required this.dateOfcreation});
factory Item.fromMap(Map<String, dynamic> map) {
return Item(
messageId: map["message_id"],
userName: map["userName"],
userRole: map["userRole"],
messageTitle: map["message_title"],
messageLabel: map["message_label"],
userMessage: map["user_message"],
imageUrl: map["image_url"],
dateOfcreation: DateTime.parse(map["dateOfcreation"]),
);
}
toMap() => {
"message_id": messageId,
"userName": userName,
"userRole": userRole,
"message_title": messageTitle,
"message_label": messageLabel,
"user_message": userMessage,
"image_url": imageUrl,
"dateOfcreation": dateOfcreation,
};
@override
String toString() {
return 'Item(messageId: $messageId, userName: $userName, userRole: $userRole, messageTitle: $messageTitle, messageLabel: $messageLabel, userMessage: $userMessage, imageUrl: $imageUrl, dateOfcreation: $dateOfcreation)';
}
}
class NotificationWidget extends StatelessWidget {
const NotificationWidget({super.key, required this.item});
final Item item;
@override
Widget build(BuildContext context) {
return Hero(
tag: Key(item.messageId.toString()),
child: SizedBox(
width: double.infinity,
// height: MediaQuery.of(context).size.height * 0.1155,
child: Card(
// color: Colors.amberAccent,
elevation: 0.0,
margin: const EdgeInsets.only(bottom: 12),
child: ListTile(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
NotificationDetailsPage(item: item)));
},
leading: CircleAvatar(
backgroundImage: NetworkImage(item.imageUrl),
child: const Text('DP')),
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
RichText(
maxLines: 1,
overflow: TextOverflow.ellipsis,
text: TextSpan(
text: item.userRole,
style: const TextStyle(
fontWeight: FontWeight.w600, color: Colors.black),
children: <TextSpan>[
TextSpan(
text: " @${item.userName}",
style: const TextStyle(fontWeight: FontWeight.w400),
)
],
),
),
const SizedBox(
height: 1,
),
Text(item.messageTitle,
textScaleFactor: 0.9,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(fontWeight: FontWeight.w600)),
Padding(
padding: const EdgeInsets.only(top: 3),
child: Text(
item.userMessage,
textScaleFactor: 0.9,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
],
),
trailing: Text(
DateFormat('MMM d, ' 'yy').format(item.dateOfcreation),
textAlign: TextAlign.end,
textScaleFactor: 0.8,
),
),
),
),
);
}
}
// ignore_for_file: prefer_const_constructors
class NotificationDetailsPage extends StatelessWidget {
const NotificationDetailsPage({
Key? key,
required this.item,
}) : super(key: key);
final Item item;
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
backgroundColor: Colors.white,
// appBar: SliverAppBar(),
body: NestedScrollView(
floatHeaderSlivers: true,
headerSliverBuilder: (context, innerBoxIsScrolled) => [
const SliverAppBar(
floating: true,
)
],
body: Padding(
padding: const EdgeInsets.only(
left: 24, right: 24, bottom: 54, top: 8),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: const EdgeInsets.only(top: 8, bottom: 16),
decoration: const BoxDecoration(
color: Color.fromRGBO(240, 221, 245, 1),
borderRadius:
BorderRadius.all(Radius.circular(10))),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
item.messageLabel,
style: const TextStyle(
fontWeight: FontWeight.w500,
color: Color.fromRGBO(30, 29, 29, 0.8)),
),
),
),
Text(
item.messageTitle,
style: const TextStyle(
fontWeight: FontWeight.w400,
fontSize: 28,
color: Color.fromARGB(255, 30, 29, 29)),
),
//start
Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
CircleAvatar(
backgroundImage: NetworkImage(item.imageUrl)),
const SizedBox(
width: 8,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
RichText(
text: TextSpan(
text: item.userRole,
style: const TextStyle(
fontWeight: FontWeight.w600,
color: Colors.black),
children: <TextSpan>[
TextSpan(
text: " @${item.userName}",
style: const TextStyle(
fontWeight: FontWeight.w400),
)
],
),
),
Row(
children: [
const Icon(
Icons.watch_later_outlined,
size: 16,
),
const SizedBox(
width: 2,
),
Text(timeago.format(item.dateOfcreation)),
],
),
],
)
],
),
),
Hero(
tag: Key(item.messageId.toString()),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: ClipRRect(
borderRadius:
const BorderRadius.all(Radius.circular(16)),
child: CachedNetworkImage(
imageUrl: item.imageUrl,
placeholder: (context, url) {
return Image.asset(
"assets/images/placeholder.png",
fit: BoxFit.cover,
);
},
),
),
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: Text(
item.userMessage,
textAlign: TextAlign.left,
style: const TextStyle(fontSize: 16),
),
)
],
),
),
))),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment